MongoDB的嵌套文档where子句返回许多子文档

问题描述:

我有一个MongoDB的文件,看起来与此类似:MongoDB的嵌套文档where子句返回许多子文档

{ 
"id": 1, 
"title": "This is the title", 
"body" : "This is the body", 
"comments": [ 
    { 
     "email_address": "[email protected]", 
     "name": "Mirko", 
     "surname": "Benedetti", 
     "language": "it", 
     "text": "This is a message", 
     "published": "Y", 
     "on": "2014-03-22 15:04:04" 
    }, 
    { 
     "email_address": "[email protected]", 
     "name": "Marc", 
     "surname": "Surname", 
     "language": "it", 
     "text": "Another Message", 
     "published": "N", 
     "on": "2014-03-23 15:04:05" 
    } 
    ] 
} 

我有这样的查询:

$this->db->collection->find(array('id' => $id, 'language' => $lang, 'comments.published' => 'Y'), 
         array('comments.name' => 1, 'comments.surname' => 1, 'comments.text' => 1, 'comments.on' => 1, '_id' => 0)); 

我的问题是运行查询,mongodb返回两个注释,我不想要,我只想要“已发布”的消息:“Y”。

我试着运行'comments.published'=>'something'并且没有选择任何评论,这是正确的,但是如果至少其中一个评论有 标记“published”设置为“Y” ,两个评论都显示出来了。

任何帮助将受到欢迎。

+0

我试着添加一个注释,将“published”设置为“N”,它给了我3个记录,var_dump,结果数组是3个元素。 –

$elemMatch documentation

db.schools.find({ zipcode: "63109" }, 
       { students: { $elemMatch: { school: 102 } } }) 

您需要同时使用elemMatch操作要小心。首先它有两个变种。 $elemMatch(projection) & $elemMatch(query)

的elemMatch(突起)的变体似乎工作,因为你必须筛选条件只匹配在注释阵列的一个值。

下面的查询将正常工作。

find({'_id' : ObjectId("582f2abf9b549b5a765ab380"), comments: { $elemMatch: { language: "it", published : "Y" }}}) 

当你有超过1个匹配值注释阵列(与“Y”发表状态两个值),那么上面的查询将行不通,只会返回第一个匹配值现在考虑的问题。

在这种情况下,您将需要使用$filter,它将根据传递的过滤器过滤器来过滤comments数组。

aggregate([{ 
    $match: { 
     '_id': ObjectId("582f2abf9b549b5a765ab380") 
    } 
}, { 
    "$project": { 
     "comments": { 
      "$filter": { 
       "input": "$comments", 
       "as": "result", 
       "cond": { 
        $and: [{ 
         $eq: ["$$result.language", "it"] 
        }, { 
         $eq: ["$$result.published", "Y"] 
        }] 
       } 
      } 
     } 
    } 
}, { 
    $project: { 
     "comments": { 
      name: 1, 
      surname: 1, 
      text: 1, 
      on: 1 
     } 
    } 
}]) 
+0

我的问题还在于我必须在某个文档(“blog_post”)中选择“注释”,但我还需要选择**正确的文档**(blog_post),这不是从文档中非常直观的, 。 –

+1

您只需要添加匹配阶段,考虑与我们在find方法中使用的查询条件相同的更新答案。希望这是你以前的评论意味着什么。 – Veeram

+0

如果我只想挑选某些“评论”元素,该怎么办? –