我有几个遵循这种结构的文件:
{
"queue-type": <integer>,
"participants": [{
"id": <integer>,
"level": <level>,
"flags": <integer>
}]
}
participants.id
上有一个多键索引。
在代码中,有一个查询查询,如下所示:db.queues.find({"participants.id": {"$in": [2, 3, 4]}})
,其结果如下:
{"queue-type": 1, "participants": [{"id": 1, "level": 10, "flags":4},{"id": 2, "level": 10, "flags":8}]}
{"queue-type": 25, "participants": [{"id": 5, "level": 10, "flags":4},{"id": 15, "level": 10, "flags":8},{"id": 4, "level": 10, "flags":8}]}
有没有办法检索用于匹配查询的元素?类似的东西:
{"queue-type": 1, "_matched": 2, "participants": [{"id": 1, "level": 10, "flags":4},{"id": 2, "level": 10, "flags":8}]}
{"queue-type": 25, "_matched": 4, "participants": [{"id": 5, "level": 10, "flags":4},{"id": 15, "level": 10, "flags":8},{"id": 4, "level": 10, "flags":8}]}
PS:我试图避免在[2, 3, 4]
和participants
数组中循环,因为它们更大。
实施例: 队列
{"queue-type": 1, "participants": [{"id": 1, "level": 10, "flags":4},{"id": 2, "level": 10, "flags":8}]}
{"queue-type": 2, "participants": [{"id": 3, "level": 10, "flags":0}]}
{"queue-type": 3, "participants": [{"id": 4, "level": 10, "flags":4},{"id": 5, "level": 10, "flags":8}]}
{"queue-type": 4, "participants": [{"id": 7, "level": 10, "flags":4},{"id": 8, "level": 10, "flags":8},{"id": 9, "level": 10, "flags":8}]}
我希望检索的结果:
db.queues.find({"participants.id": {"$in": [2]}});
{"queue-type": 1, "_matched": 2, "participants": [{"id": 1, "level": 10, "flags":4},{"id": 2, "level": 10, "flags":8}]}
注意&#34; _匹配&#34;元素与&#39; participant.id&#39;相同。在搜索查询上给出
另一个例子:
db.queues.find({"participants.id": {"$in": [2, 3, 6]}});
{"queue-type": 1, "_matched": 2, "participants": [{"id": 1, "level": 10, "flags":4},{"id": 2, "level": 10, "flags":8}]}
{"queue-type": 2, "_matched": 3, "participants": [{"id": 3, "level": 10, "flags":0}]}
多个匹配示例:
db.queues.find({"participants.id": {"$in": [1, 2, 3]}});
{"queue-type": 1, "_matched": 1, "participants": [{"id": 1, "level": 10, "flags":4},{"id": 2, "level": 10, "flags":8}]}
{"queue-type": 1, "_matched": 2, "participants": [{"id": 1, "level": 10, "flags":4},{"id": 2, "level": 10, "flags":8}]}
{"queue-type": 2, "_matched": 3, "participants": [{"id": 3, "level": 10, "flags":0}]}
一个不太好的解决方案就是简单地复制参与者&#39;数据(&#39;参与者-cpy&#39;)然后运行:
db.queues.find({"participants-cpy.id": {"$in": [2]}}, {"participants-cpy.$":1, "participants":1, "_id": 1, "queue-type":1})
可用于检索用于匹配&#39;的元素。查询,但这将生成重复的数据 - 这是非常糟糕的:p
答案 0 :(得分:1)
常规find
查询在此处不起作用。您需要使用聚合框架。在您的管道中,您需要使用$match
管道运算符仅选择与您的查询条件匹配的文档。
管道中的下一个和最后一个阶段是$project
阶段,您可以在其中将新字段“_matched”添加到文档中。如果你考虑一下,你会发现新字段只是一个数组,其中包含出现在“partcipantsId”数组/列表中的元素以及文档中“参与者”字段的所有“id”。
要获得该值,您只需使用$map
和$setIntersection
运算符对participantId数组和“参与者”中的“id”数组执行集交集操作。请注意,结果数组仅包含唯一条目,因为$setIntersection
会过滤掉重复项。
participantsId = [1, 2, 3]
db.queues.aggregate([
{ "$match": { "participants.id": { "$in": participantsId } } },
{ "$project": {
"_matched": {
"$setIntersection": [
{ "$map": {
"input": "$participants",
"as": "p",
"in": "$$p.id"
}},
participantsId
]
},
"queue-type": 1,
"participants": 1
}}
])