Mongoose查询子文档

时间:2017-12-10 04:29:24

标签: node.js mongodb mongoose

您好,我试图在MongoDB中查询一些嵌套文档。即时通讯使用Mongoose ..我的文件就像

[
{
    "_id": "5a2ca2227c42ad67682731d4",
    "description": "some descrition",
    "photos": [
        {
            "_id": "5a2ca22b7c42ad67682731d5",  
            "approved": false,
            "text":"good"  
        },
        {
            "_id": "5a2ca72b0a1aa173aaae07da",
            "approved": true,
            "text":"bad"
        },
        {
            "_id": "5a2cabf85a41077a2f87d4e3",    
            "approved": false,
            "text":"bad"
        }
    ]
}
]

我只想找到价值“好”的照片,在文字属性中,这是我的查找代码:

ObjectSchema.find({
        'photos': {
            $elemMatch : {
                'text' : 'good'
            }
        }
    },function(err,result){
       console.log(result);
    });

我想要只返回带有与我的查询匹配的值的元素的objct,但是当这个列表的一个对象匹配时,整个照片列表都带有结果,而不仅仅是匹配文本的人。 我如何查询它,并且只带来匹配的元素,在这种情况下,只带有文本中“good”的元素。

我正在使用nodejs + mongoose

谢谢!

1 个答案:

答案 0 :(得分:1)

您只使用find条件,这将返回整个文档。您还可以specify a projection with find在文档中包含/排除某些字段。您可以在投影中使用$ elemMatch,如下所示:

ObjectSchema.find({
    'photos': {
        $elemMatch : {
            'text' : 'good'
        }
    }
}, {
    'photos': {
        $elemMatch : {
            'text' : 'good'
        }
    }
}, function(err,result){
   console.log(result);
});

但要注意$elemMatch in the projection will only include the first matching array element。根据示例文档,这可能不是您想要的。相反,您可以使用Aggregation Framework。您可以从以下内容开始(未经测试)并根据需要调整输出:

ObjectSchema.aggregate(
    {$unwind: "$photos"},
    {$match: {"photos.text": "good"}},
    function(err,result){
        console.log(result);
    }
)

其中$unwind为数组的每个元素创建单独的文档。

要按照您在评论中描述的方式塑造输出,您需要使用$group aggregation。尝试将类似于以下内容的$ group聚合添加到管道的末尾:

{$group: {_id: "$_id", photos: {$push: "$photos"}}}