【问题标题】:Mongoose query document with multiple fileds including sub field Mongodb具有多个文件的 Mongoose 查询文档,包括子字段 Mongodb
【发布时间】:2019-07-27 17:11:12
【问题描述】:

您好,我在 mongodb 中有以下文档模型

架构是

const ProductionsSchema=new Schema({
        name: {type: String, required: true, unique: true},
        isActive: {type: Boolean, default: true},
        locations: [{
            name: {type: String},
            isActive : {type: Boolean, default: false}
        }],
        trackno: {type: String}
})
Productions:[{ 
       _id: 125,
        name: 'John Smith',
        locations: [{ name: 'Boston', isActive: true}]
        isActive: true,
        trackno: 2123
    }, 
        { 
       _id: 126,
        name: 'Moe Adam',
        locations: [{ name: 'Chicago', isActive: true}]
        isActive: true,
        trackno: 5663
    }, 
     { 
       _id: 126,
        name: 'Henry Noel',
        locations: [{ name: 'Houston', isActive: false}]
        isActive: true,
        trackno: 4552
    }, 
      { 
       _id: 128,
        name: 'Tim Johnson',
        locations: [{ name: 'Denver', isActive: true}]
        isActive: false,
        trackno: 6672
    }

]

我正在尝试查找两个 isActive true 的列表

Productions.find({"isActive" : true , "locations.isActive": true}, (err, list)=>{
      if(err){
            callback(err);
            }
            callback(null, list)
        })

我正在尝试编写查询,所以两个 isActive 都是真的。在上面的示例数据中,只有前两条记录应该在答案中。但是我一直在获取所有记录,即使是带有“假”的记录,我什至在位置上尝试了 $elemMatch。isActive 仍然没有工作。 请让我知道如何解决此问题,以便我只获得仅包含两个 isActive 的真实值的结果。

【问题讨论】:

  • { "isActive": true, "locations.isActive": true }。这是一个 AND 条件,这意味着 BOTH。
  • 我将其更改为 $ 并且仍然可以同时获取位置的真假记录。isActive
  • 将其标记为重复的人正在查看 Mongo 查询的答案,我正在使用 mongoose 进行具有不同语法的查询,并且我已经在 stackoverflow 上查看了很多解决方案
  • 我已经非常合理地要求您展示一些示例数据来说明问题所在以及您的期望。最多两个小文件,这不是一个大问题。如果有一个全新的问题,那么我很乐意重新打开它,或者至少以其他方式为您指明正确的方向,解释和示例属于问题
  • 那么问题是什么?我在第一条评论中给你的查询返回了前两个文档。你在期待什么?我读了您的问题,因为这就是您想要的,而这正是您想要的。对于数组元素的单个条件,您不需要 $elemMatch。仅适用于同一数组元素的多个条件

标签: javascript mongodb mongoose


【解决方案1】:

正如原始评论所解释的,您需要的唯一查询条件是:

{ isActive: true, "locations.isActive": true }

这是一个基本的 AND 条件,您不需要任何特殊的运算符来验证数组中任何位置的单个属性是否满足条件,这就是您所要求的。

由于这完全符合预期,我只能想向您展示一个完整的工作清单,以作为确定您在做什么不同之处的基础,从而导致您获得与预期不同的结果。

const { Schema } = mongoose = require('mongoose');

const uri = 'mongodb://localhost:27017/productions';
const opts = { useNewUrlParser: true };

mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
mongoose.set('debug', true);

const productionSchema = new Schema({
  name: String,
  isActive: { type: Boolean, default: true },
  locations: [{
    name: String,
    isActive: { type: Boolean, default: false }
  }],
  trackno: Number
})

const Production = mongoose.model('Production', productionSchema);

const data =
[
    {
        name: 'John Smith',
        locations: [{ name: 'Boston', isActive: true}],
        isActive: true,
        trackno: 2123
    },
        {
        name: 'Moe Adam',
        locations: [{ name: 'Chicago', isActive: true}],
        isActive: true,
        trackno: 5663
    },
     {
        name: 'Henry Noel',
        locations: [{ name: 'Houston', isActive: false}],
        isActive: true,
        trackno: 4552
    },
    {
        name: 'Tim Johnson',
        locations: [{ name: 'Denver', isActive: true}],
        isActive: false,
        trackno: 6672
    }
];

const log = data => console.log(JSON.stringify(data, undefined, 2));

(async function() {

  try {
    const conn = await mongoose.connect(uri, opts);

    // clean data
    await Promise.all(
      Object.entries(conn.models).map(([k, m]) => m.deleteMany())
    );

    // set up
    await Production.insertMany(data);

    // Query
    let query = { isActive: true, "locations.isActive": true };
    let results = await Production.find(query);

    log(results);


  } catch(e) {
    console.error(e)
  } finally {
    mongoose.disconnect()
  }

})()

输出两个预期的文档:

Mongoose: productions.deleteMany({}, {})
Mongoose: productions.insertMany([ { isActive: true, _id: 5c7f7e9367daed19d6773e9b, name: 'John Smith', locations: [ { isActive: true, _id: 5c7f7e9367daed19d6773e9c, name: 'Boston' } ], trackno: 2123, __v: 0 }, { isActive: true, _id: 5c7f7e9367daed19d6773e9d, name: 'Moe Adam', locations: [ { isActive: true, _id: 5c7f7e9367daed19d6773e9e, name: 'Chicago' } ], trackno: 5663, __v: 0 }, { isActive: true, _id: 5c7f7e9367daed19d6773e9f, name: 'Henry Noel', locations: [ { isActive: false, _id: 5c7f7e9367daed19d6773ea0, name: 'Houston' } ], trackno: 4552, __v: 0 }, { isActive: false, _id: 5c7f7e9367daed19d6773ea1, name: 'Tim Johnson', locations: [ { isActive: true, _id: 5c7f7e9367daed19d6773ea2, name: 'Denver' } ], trackno: 6672, __v: 0 } ], {})
Mongoose: productions.find({ isActive: true, 'locations.isActive': true }, { projection: {} })
[
  {
    "isActive": true,
    "_id": "5c7f7e9367daed19d6773e9b",
    "name": "John Smith",
    "locations": [
      {
        "isActive": true,
        "_id": "5c7f7e9367daed19d6773e9c",
        "name": "Boston"
      }
    ],
    "trackno": 2123,
    "__v": 0
  },
  {
    "isActive": true,
    "_id": "5c7f7e9367daed19d6773e9d",
    "name": "Moe Adam",
    "locations": [
      {
        "isActive": true,
        "_id": "5c7f7e9367daed19d6773e9e",
        "name": "Chicago"
      }
    ],
    "trackno": 5663,
    "__v": 0
  }
]

【讨论】:

    猜你喜欢
    • 2017-10-01
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    相关资源
    最近更新 更多