使用MongoDB中的$ in查找子文档

时间:2015-11-14 19:33:40

标签: node.js mongodb find

我的任务是找到个别作者(comments.user_id)对文章的评论(_id

{
    "_id" : ObjectId("56479d9c8510369a4ecea3a9"),
    "comments" : [ 
        {
            "text" : "222",
            "user_id" : ObjectId("563f2db0e2bf6c431b297d45"),
        }, 
        {
            "text" : "333",
            "user_id" : ObjectId("563f2db0e2bf6c431b297d45"),
        }, 
        {
            "text" : "444",
            "user_id" : ObjectId("563f2db0e2bf6c431b297d45"),
        }, 
        {
            "text" : "55555",
            "user_id" : ObjectId("563e3337e2bf6c431b297d41"),
        }, 
        {
            "text" : "00000",
            "user_id" : ObjectId("563f7c0a8db7963420cd5732"),
        }, 
        {
            "text" : "00001",
            "user_id" : ObjectId("563f7c0a8db7963420cd5732"),
        }
    ]
}

我的查询如下

db.getCollection('messages').find({
  '_id': ObjectId("56479d9c8510369a4ecea3a9"),
  'comments.user_id': {$in : [
    ObjectId("563e3337e2bf6c431b297d41"),
    ObjectId("563f7c0a8db7963420cd5732")
  ]}
})

返回所有评论。请帮助理解它为什么会发生。

预期结果

{
    "_id" : ObjectId("56479d9c8510369a4ecea3a9"),
    "comments" : [ 
        {
            "text" : "55555",
            "user_id" : ObjectId("563e3337e2bf6c431b297d41"),
        }, 
        {
            "text" : "00000",
            "user_id" : ObjectId("563f7c0a8db7963420cd5732"),
        }, 
        {
            "text" : "00001",
            "user_id" : ObjectId("563f7c0a8db7963420cd5732"),
        }
    ]
}

更新查询(绝望)

db.getCollection('messages').find(
    {'_id': ObjectId("56479d9c8510369a4ecea3a9")},
    {'comments.user_id': {$in:  ["563f2db0e2bf6c431b297d45", "563e3337e2bf6c431b297d41"]}},
    {'comments.user_id': {$elemMatch: {$in:  ["563f2db0e2bf6c431b297d45", "563e3337e2bf6c431b297d41"]}}}
     )


db.getCollection('messages').find(
    {'_id': ObjectId("56479d9c8510369a4ecea3a9")},
     {comments: {$elemMatch: {'user_id': {$in : [ObjectId("563f2db0e2bf6c431b297d45"), ObjectId("563f7c0a8db7963420cd5732")]}}}}  
    )

我只返回1条记录,并且我拥有这些作者的所有记录

1 个答案:

答案 0 :(得分:0)

如您所见,$$elemMatch投影运算符仅包含第一个匹配元素。

要在comment数组的投影中包含多个已过滤的数组元素,您可以将aggregate$redact运算符一起使用,而不是find

db.getCollection('test').aggregate([
    {$match: {
        '_id': ObjectId("56479d9c8510369a4ecea3a9"),
        'comments.user_id': {$in : [
            ObjectId("563e3337e2bf6c431b297d41"),
            ObjectId("563f7c0a8db7963420cd5732")
        ]},
    }},
    {$redact: {
        $cond: {
            if: {
                $or: [
                    {$eq: ['$user_id', ObjectId("563e3337e2bf6c431b297d41")]},
                    {$eq: ['$user_id', ObjectId("563f7c0a8db7963420cd5732")]},
                    {$not: '$user_id'}
                ]
            },
            then: '$$DESCEND',
            else: '$$PRUNE'
        }
    }}
])

$redact像树一样遍历每个文档,保留或修剪每个文档的字段,因为它是$cond表达式所指示的。

围绕$redact包围你有点棘手,但它基本上是说如果级别的user_id字段与$in中的两个ObjectId中的任何一个匹配,或者它不是现在(即它位于文档的顶层),包括数据,否则将其删除。