我发现很多关于如何根据某些子文档标准查找文档的问题,但是是否可以检索子文档本身,而不是包含它们的文档?
注意 - 建议的副本不重复。该OP询问如何返回集合中的文档,每个文档都包含匹配的子文档的子集。我的问题是,如何检索匹配的仅子文档。
来自这样的集合:
{ name:"a" subs: [ { subname:"aa", value: 1 }, { subname:"ab", value: 2 } ] }
{ name:"b" subs: [ { subname:"ba", value: 2 }, { subname:"bb", value: 3 } ] }
我想做一个生成的查询,只是生成匹配查询的子文件,例如value === 2
。
我试过了:
myCollection.find().elemMatch("subs", { value:2 })
这很接近,但它只是找到(在示例数据中)两个上层文档,因为它们的子元素匹配。我知道我可以从结果中挑选出子文档,但我希望查询能够完成这项工作,然后生成这个......
{ subname:"ab", value: 2 }
{ subname:"ba", value: 2 }
...即只是匹配的subdocs。可能吗?提前谢谢。
答案 0 :(得分:1)
您可以在find的第二个参数中指定要返回的内容。请尝试使用您的数据:
db.myCollection.find( { subs: { $elemMatch: { "value" : 2 } } }, { "subs.$": 2 } );
此外,还有一些很好的例子:
https://docs.mongodb.org/v3.0/reference/operator/projection/positional/#proj.S
答案 1 :(得分:1)
一个选项可能是使用聚合fwk,下面是我的例子
db.foo.insert({ name:"a", subs : [ { subname:"aa", value: 1 }, { subname:"ab", value: 2 } ] })
db.foo.insert({ name:"b" , subs: [ { subname:"ba", value: 2 }, { subname:"bb", value: 3 } ] })
db.foo.insert({ name:"c", subs : [ { subname:"aa", value: 1 }, { subname:"ab", value: 2 }, { subname:"acc", value: 2 } ] })
使用
db.foo.aggregate(
[
{ $unwind : "$subs" },
{ $match : { "subs.value": 2 }},
{ $project : {"subs" : 1 , "_id" : 0} }
]
)
结果是
{ "subs" : { "subname" : "ab", "value" : 2 } }
{ "subs" : { "subname" : "ba", "value" : 2 } }
{ "subs" : { "subname" : "ab", "value" : 2 } }
{ "subs" : { "subname" : "acc", "value" : 2 } }
如果要删除重复,请执行最终$ group
db.foo.aggregate(
[
{ $unwind : "$subs" },
{ $match : { "subs.value": 2 }},
{ $group : { "_id": { "subname" : "$subs.subname" , "value" : "$subs.value" }}},
{ $project : { "subs" : "$_id" , "_id" : 0}}
]
)
结果将是
{ "subs" : { "subname" : "acc", "value" : 2 } }
{ "subs" : { "subname" : "ba", "value" : 2 } }
{ "subs" : { "subname" : "ab", "value" : 2 } }