javascript - MongoDB with Mongoose - 仅查找某些子文档

标签 javascript mongodb mongoose

MongoDB 3.0.7 和 Mongoose 4.3.4。

架构:

var schema = new mongoose.Schema({
    confirmed: { type: Boolean, default: false },
    moves: [new mongoose.Schema({
        name: { type: String, default: '' },
        live: { type: Boolean, default: true }
    })]
});
mongoose.model('Batches', schema);

查询:

var Batch = mongoose.model('Batches');
var query = {
    confirmed: true,
    moves: {
        $elemMatch: {
            live: true
        }
    }
};
Batch.find(query).exec(function(err, batches){
    console.log('batches: ', batches);
});

我需要返回 confirmed 的所有批处理,以及返回批处理内的所有移动 live .

目前,上面仅返回 confirmed批处理(这就是我想要的),但是所有moves在每个返回的批处理中(这不是我想要的)。因此,移动的限制是 live标志不起作用。

如何限制返回的子文档..?

理想情况下,我希望将控制返回数据的所有内容保留在 query 内。传递至find ,而不必在 Batch 上调用更多方法.

最佳答案

对于支持 MongoDB Server 3.2.x 的 Mongoose 版本 >=4.3.0,您可以使用 $filter 运算符与聚合框架一起根据指定条件限制/选择要返回的移动数组的子集。这将返回一个仅包含与条件匹配的元素的数组,因此您将在 $project 中使用它。 阶段根据上面的过滤器修改移动数组。

以下示例展示了如何执行此操作:

var Batch = mongoose.model('Batches'),
    pipeline = [
        {
            "$match": { "confirmed": true, "moves.live": true }
        },
        { 
            "$project": {
                "confirmed": 1,
                "moves": {
                    "$filter": {
                         "input": "$moves",
                         "as": "el",
                         "cond": { "$eq": [ "$$el.live", true ] }
                     }
                }
            }
        }
    ];

Batch.aggregate(pipeline).exec(function(err, batches){
    console.log('batches: ', batches);
});

或使用流畅的aggregate() API 管道构建器:

Batch.aggregate()
     .match({
         "$match": { "confirmed": true, "moves.live": true }
     })
     .project({
         "confirmed": 1,
         "moves": {
             "$filter": {
                  "input": "$moves",
                  "as": "el",
                  "cond": { "$eq": [ "$$el.live", true ] }
             }
         }
     })
     .exec(function(err, batches){
        console.log('batches: ', batches);
     });

对于支持 MongoDB Server >=2.6.x 的 Mongoose 版本 ~3.8.8、~3.8.22、4.x,您可以过滤掉 false 值使用 $map 的组合 $setDifference 运算符:

var Batch = mongoose.model('Batches'),
    pipeline = [
        {
            "$match": { "confirmed": true, "moves.live": true }
        },
        { 
            "$project": {
                "confirmed": 1,
                "moves": {
                    "$setDifference": [
                         {
                             "$map": {
                                 "input": "$moves",
                                 "as": "el",
                                 "in": {
                                     "$cond": [
                                         { "$eq": [ "$$el.live", true ] },
                                         "$$el",
                                         false
                                     ]
                                 }
                             }
                         },
                         [false]
                     ]
                 }
            }
        }
    ];

Batch.aggregate(pipeline).exec(function(err, batches){
    console.log('batches: ', batches);
});

关于javascript - MongoDB with Mongoose - 仅查找某些子文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35428741/

相关文章:

javascript - 如何从 Angular 2/5 中的服务订阅对象?

java - 如何使用java在mongodb中查找id和密码?

mysql - mongodb - 寻找类似于 mysql 的 "id in(1,2,3,4)"的选择查询

node.js - 如何在 mongodb 中 insertMany 和更新重复项?

javascript - 按时钟范围查询 mongo 文档 - 正向和反向

javascript - 对象未通过引用传递(CoffeeScript)

Javascript 正则表达式 urlify 文本

javascript - 未捕获的类型错误 : Cannot read property '_myPrivateFunction' of undefined

node.js - 创建添加到数组字段的新子项

javascript - 在 Mongoose 中查询变量