我有这个漂亮的Json,我正在尝试使用强大的mongodb查询来获取file_id 12的所有注释....所以这就是我想要的[4,5,7,10,11, 15]。
我试过这个查询但是file_id被引擎完全忽略了:
db.collection.distinct("changes.comments",
{"my_uuid":"bf48e757-1a65-4546-bf24-2bb001effddd",
"changes":{$elemMatch:{file_id:12}} }
)
输出:
{
"_id" : ObjectId("5342bf796b03d7ffc834afcc"),
"my_uuid" : "bf48e757-1a65-4546-bf24-2bb001effddd",
"changes" : [
{
"file_id" : 12,
"version" : 1,
"comments" : [
4,
5,
7
],
"lastseen" : 1394640549
},
{
"file_id" : 12,
"version" : 2,
"comments" : [
10,
11,
15
],
"lastseen" : 1394640511
},
{
"file_id" : 234,
"version" : 1,
"comments" : [
100,
110,
150
],
"lastseen" : 1394640555
}
]
}
提前致谢
答案 0 :(得分:2)
您可以使用aggregation framework
来实现您的目标。尽管查询对于您要执行的操作看起来很复杂,但只要您了解它就很简单。
db.collection.aggregate([
// Get only documents where "my_uuid" equals "bf48e757-1a65-4546-bf24-2bb001effddd"
{"$match":{"my_uuid":"bf48e757-1a65-4546-bf24-2bb001effddd"}},
// Unwind the "changes" array
{"$unwind":"$changes"},
// Get only elements of the "changes" array where "file_id" equals 12
{"$match":{"changes.file_id":12}},
// Unwind the "comments" array
{"$unwind":"$changes.comments"},
// Group by _id and add the comments to array only if not already present
{"$group":{_id:"$_id", comments:{$addToSet:"$changes.comments"}}},
// Cleanup the output
{"$project":{_id:0, comments:1}}
])
输出:
{
"result" : [
{
"comments" : [
4,
5,
7,
10,
11,
15
]
}
],
"ok" : 1
}
编辑:在结果中包含my_uuid
非常简单。我们只需要按my_uuid
而不是_id
进行分组:
db.collection.aggregate([
{"$match":{"my_uuid":"bf48e757-1a65-4546-bf24-2bb001effddd"}},
{"$unwind":"$changes"},
{"$match":{"changes.file_id":12}},
{"$unwind":"$changes.comments"},
{"$group":{_id:"$my_uuid", comments:{$addToSet:"$changes.comments"}}},
{"$project":{_id:0, my_uuid:"$_id", comments:1}}
])
答案 1 :(得分:0)
目前还没有直接从数组中提取匹配文档的方法。 $ elemMatch运算符仅确保阵列中的至少一个文档满足您提供的条件。但是,查询将始终返回整个文档。实现目标的一种方法是 -
db.sample4.aggregate({$unwind:"$changes"},{$match:{"changes.file_id":12}},{$project:{"changes.comments":1,"_id":0}});
这些主题在stackoverflow中涵盖here,其中列出了map-reduce方法以实现此目的。如果要求是返回第一个匹配的文档,那么您可以使用changes.comments.$:1
Eg进行投影。 - db.sample4.find({"changes":{$elemMatch:{"file_id":12}} },{"changes.comments.$":1} )