如何在文档中找到嵌套对象?

时间:2014-06-05 00:36:55

标签: node.js mongodb mongoose mongodb-query aggregation-framework

我试图找出如何查询文档中的嵌套对象。假设我有一个mongoose Schema如下:

var posts = mongoose.Schema({
    title : String,
    post : String,
    comments : [{
        status : Number,
        title : String,
        comment : String
    }]
});

我想搜索特定帖子中的所有评论,其中评论的状态等于1.这是我尝试过的,但它不起作用:

Post.find(
    {_id: req.params.id, comments: { status: 1 }},
    null,
    {},
    function (err, data) {
        if (err) return console.error(err);
        return res.json(data);
    }
);

我做错了什么?

1 个答案:

答案 0 :(得分:0)

使用"点符号":

Post.find(
    {
        _id: req.params.id, 
        "commments": { "$exists": true }, 
        "comments.status": 1 
    },
    function (err, data) {
        if (err) return console.error(err);
        return res.json(data);
    }
);

如果没有这个,你要求的评论是"确切地说"在您查询的形式中,包含" status"作为一个领域。

如果要返回的只是数组的匹配注释,则基本上有两个选项。要么使用positional $运算符才能返回第一个匹配元素一个数组,这是它的当前限制。或者您使用聚合框架以返回所有项目:

Post.aggregate(
    [
        // Initial match is on only the documents that contain
        { "$match": {
            "_id": req.params.id,
            "comments": { "$exists": true },
            "comments.status": 1
        }},

        // Unwind the array to "de-normalize" as documents
        { "$unwind": "$comments" },

        // Match the "unwound" documents
        { "$match": { 
            "comments.status": 1
        }},

        // Push back as an array
        { "$group": {
            "_id": "$_id",
            "title": { "$first": "$title },
            "post": { "$first": "$post" },
            "comments": { "$push": "$comments" }
        }}
    ],
    function(err,data) {

        // work in here
})

或者使用MongoDB 2.6及更高版本,你可以做到这一点"就地"改为使用$map

Post.aggregate(
    [
        // Initial match is on only the documents that contain
        { "$match": {
            "_id": req.params.id,
            "comments": { "$exists": true },
            "comments.status": 1
        }},

        // Project matching items only
        { "$project": {
           "title": 1,
           "post": 1,
           "comments": {
               "$setDifference": [
                   { 
                       "$map": {
                           "input": "$comments",
                           "as": "el",
                           "in": {
                               "$cond": [
                                   { "$eq": [ "$$el.status", 1 ] },
                                   "$$el",
                                   false
                               ]
                           }
                       }
                   },
                   [false]
               ]
           }
        }}
    ],
    function(err,data) {

        // work in here
})

所以这里的区别是匹配"文件"它包含您在查询中指定的条件和"过滤" 匹配查询规范的数组成员。