假设我有一个类似于
的博客数据集{
"_id" : "abcde",
"author" : "xyz",
"body" : "this is test body",
"date" : "xyz",
"tags" : ["tag1","tag2"],
"comments":[
{ "body": "comment1",
"email": "email1",
"author" :"author1"
},
{ "body": "comment2",
"email": "email2",
"author" :"author2"
}
]
}
此处每篇文档都代表一篇博文。每篇博文都可以有多个评论,但是我的一个用户。让我们说我必须找到特定作者的所有评论。对此有什么疑问?
一种方法是展开评论,然后按comments.author分组并推送comments.body。
但是,只有使用find,才能在没有聚合管道的情况下完成吗?因为我认为我应该只是通过发现来做到这一点。任何人都可以帮我这个吗?
答案 0 :(得分:2)
您可以使用点表示法来查询子文档数组。
您的查询将如下所示:
db.blog_posts.find({"comments.author": "author1"});
这将返回包含作者值为author1
的子文档的所有文档。结果将是整个帖子文档,因此您可能希望指定要返回的字段。这称为query projection。
db.blog_posts.find({“comments.author”:“author1”});
要指定所需的字段,请在.find()
函数中添加一个额外的对象作为第二个参数:
db.blog_posts.find({"comments.author": "author1"}, {"comments": 1} );
现在生成的文档只包含_id
字段和comments
字段。
请记住,您实际上是在查询博客文章集合,因此您返回的结果仍然是博客文章 - 但只有指定作者评论过的文章。
采取下一步并仅提取注释对象的简单方法可能如下所示:
var author = 'author1';
var comments = [];
db.blog_posts.find(...).forEach(function(doc){
var post_comments = doc.comments;
for (var i=0; i<post_comments.length; i++){
if (post_comments[i].author == author){
comments.push(post_comments[i]);
}
}
});
以下是相关文档页面:
http://docs.mongodb.org/manual/tutorial/query-documents/#array-of-embedded-documents
匹配字段而不指定数组索引
如果您不知道数组中文档的索引位置,请将包含该数组的字段的名称与点(。)和嵌入文档中的字段名称连接起来。