Mongodb 从$in查询返回匹配的元素

Mongodb 从$in查询返回匹配的元素,mongodb,mongodb-query,pymongo,aggregation-framework,Mongodb,Mongodb Query,Pymongo,Aggregation Framework,我有几个文件遵循这种结构: { "queue-type": <integer>, "participants": [{ "id": <integer>, "level": <level>, "flags": <integer> }] } 是否有任何方法也可以检索用于匹配查询的元素?比如: {"queue-type": 1, "_matched": 2, "participants": [{"id": 1,

我有几个文件遵循这种结构:

{
  "queue-type": <integer>,
  "participants": [{
     "id": <integer>,
     "level": <level>,
     "flags": <integer>
  }]
}
是否有任何方法也可以检索用于匹配查询的元素?比如:

{"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}]}
注:我试图避免在
[2,3,4]
参与者
数组中循环,因为它们要大得多

示例: 排队

我希望检索的结果是:

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}]}
注意“_matched”元素与搜索查询中给定的“participant.id”相同

另一个例子:

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}]}

一个不好的解决方案是简单地复制“参与者”数据(“参与者-cpy”),然后运行:

db.queues.find({"participants-cpy.id": {"$in": [2]}}, {"participants-cpy.$":1, "participants":1, "_id": 1, "queue-type":1})
它可以用来检索用于“匹配”查询的元素,但这会生成重复的数据——这非常糟糕:p常规查询在这里不起作用。您需要使用聚合框架。在管道中,只需使用管道操作符选择与查询条件匹配的文档

管道中的下一个也是最后一个阶段是使用将新字段“\u matched”添加到文档中的阶段。仔细想想,您会发现新字段只不过是一个数组,其中包含出现在“partcipantsId”数组/列表中以及文档中“参与者”字段中所有“id”中的元素

要获得该值,只需使用and运算符对participantsId数组和“participants”的“id”数组执行一个集合交集操作。请注意,生成的数组只包含唯一的条目,因为
$setIntersection
会过滤掉重复项

participantsId=[1,2,3]
db.queues.aggregate([
{“$match”:{“participants.id”:{“$in”:participantsId}},
{“$project”:{
“_matched”:{
“$setcrossion”:[
{“$map”:{
“输入”:“$participants”,
“as”:“p”,
“在”:“$$p.id”
}}, 
参与者
]
}, 
“队列类型”:1,
“参与者”:1
}}
])

您所说的
查询中用于匹配的元素是什么意思?
?很抱歉,这里不清楚。在查询中,我总是传递一个列表(在示例[2,3,4]中),但大多数情况下,只有列表中的一个元素能够成功匹配。我会更新帖子,让它更清晰。我明白你的意思。您可以尝试使用
aggregate
$group
,这是获取所需内容的方法。@titi23这并不容易,因为您需要传递查询参数来比较匹配的内容-最简单的方法是使用
$filter
并仅返回匹配的文档,或者按照问题所述,在简单查询
$elemMatch
中,他需要知道数组中每个值的匹配元素计数
{“$in”:[2,3,4]}
。所以我认为,
$group
将是获得计数的解决方案@教授79
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}]}
db.queues.find({"participants-cpy.id": {"$in": [2]}}, {"participants-cpy.$":1, "participants":1, "_id": 1, "queue-type":1})