Mongodb 在另一个集合中查找具有值的键
我们有一个请求集合,示例文档如下:Mongodb 在另一个集合中查找具有值的键,mongodb,mongodb-query,aggregation-framework,mongodb-3.6.4,Mongodb,Mongodb Query,Aggregation Framework,Mongodb 3.6.4,我们有一个请求集合,示例文档如下: { "_id" : ObjectId("xxxxxx"), "requestId" : "REQ4", "scrip" : "5647" } { "_id" : ObjectId("xxxxxx"), "requestId" : "REQ4", "scrip" : "5648" } { "_id" : ObjectId("xxxxxx"), "requestId" : "REQ1", "s
{
"_id" : ObjectId("xxxxxx"),
"requestId" : "REQ4",
"scrip" : "5647"
}
{
"_id" : ObjectId("xxxxxx"),
"requestId" : "REQ4",
"scrip" : "5648"
}
{
"_id" : ObjectId("xxxxxx"),
"requestId" : "REQ1",
"scrip" : "0001"
}
{
"_id" : ObjectId("xxxxxx"),
"requestId" : "REQ1",
"scrip" : "0456"
}
纸条收集:
{
"_id" : ObjectId("xxxx"),
"scrip" : "0001"
}
{
"_id" : ObjectId("xxxx"),
"scrip" : "0456"
}
{
"_id" : ObjectId("xxxx"),
"scrip" : "5647"
}
我们需要返回在Scrips集合中包含所有相应Scrips的请求
预期输出:
{"_id" : ObjectId("xxxxxx"),
"requestId" : "REQ1",
"scrip" : ["0001","0456"]
}
我们如何做到这一点?试试这个:
db.requests.aggregate([
/** Filter to reduce dataset */
{ $match: { requestId: { $in: ['REQ4', 'REQ1', 'REQ5'] } } },
/** check for matching docs based on scrip */
{
$lookup:
{
from: "scrips",
localField: "scrip",
foreignField: "scrip",
as: "scrips"
}
}, { $addFields: { scrips: { $arrayElemAt: ['$scrips', 0] } } },
/** Group all docs in request collection based on requestId */
{ $group: { _id: '$requestId', scrip: { $push: '$scrip' }, scrips: { $push: '$scrips' } } },
/** Remove request docs if all request docs doesn't have match in scrips */
{ $match: { $expr: { $eq: [{ $size: '$scrip' }, { $size: '$scrips' }] } } },
/** Transform final result */
{ $project: { _id: 0, requestId: '$_id', scrip: 1 } }
])
测试:尝试以下方法:
db.requests.aggregate([
/** Filter to reduce dataset */
{ $match: { requestId: { $in: ['REQ4', 'REQ1', 'REQ5'] } } },
/** check for matching docs based on scrip */
{
$lookup:
{
from: "scrips",
localField: "scrip",
foreignField: "scrip",
as: "scrips"
}
}, { $addFields: { scrips: { $arrayElemAt: ['$scrips', 0] } } },
/** Group all docs in request collection based on requestId */
{ $group: { _id: '$requestId', scrip: { $push: '$scrip' }, scrips: { $push: '$scrips' } } },
/** Remove request docs if all request docs doesn't have match in scrips */
{ $match: { $expr: { $eq: [{ $size: '$scrip' }, { $size: '$scrips' }] } } },
/** Transform final result */
{ $project: { _id: 0, requestId: '$_id', scrip: 1 } }
])
测试:我不明白你的问题,你说的子集是什么意思?您是如何获得
[“0001”,“0456”]
?REQ1在任务集合中有两个条目-分别有0001和0456的纸条我在请求集合中只看到一个REQ1
,这是一个编辑错误。感谢您指出您想要检查请求集合scrip
是否存在于纸条集合中&如果存在,请将它们推到一个数组中,如果不是,我不明白你的问题,你说的子集是什么意思?您是如何获得[“0001”,“0456”]
?REQ1在任务集合中有两个条目-分别有0001和0456的纸条我在请求集合中只看到一个REQ1
,这是一个编辑错误。感谢您指出您想要检查请求集合scrip
是否存在于纸条集合中&如果存在,请将它们推到一个数组中,如果不是否?谢谢。但是,这将扫描整个请求和脚本集合(~1M条记录)。如果我仅为作为输入传入的请求的分块列表触发此操作,会发生什么情况。@IUnknown:可能有关系,也可能没有关系,但是的,我始终建议将数据集尽可能低,你的输入是什么样的?基本上使用一个$match
stage它可能是一个数组['REQ4','REQ1'…]来限制每次扫描iteration@IUnknown:然后您可以将其添加为第一阶段::{$match:{requestId:{$in:['REQ4','REQ1'…]}
Yes-但这将返回甚至部分匹配的请求,例如REQ4…而不是像REQ1Thanks这样的完全匹配候选。但是,这将扫描整个请求和脚本集合(~1M条记录)。如果我仅为作为输入传入的请求的分块列表触发此操作,这是怎么发生的。@IUnknown:可能有关系,也可能没有关系,但是的,这是正确的,我总是建议将您的数据集保持尽可能低,您的输入会是什么样子?基本上使用一个$match
stage它可能是一个数组['REQ4','REQ1'…]来限制每次扫描iteration@IUnknown:然后您可以将其添加为第一阶段::{$match:{requestId:{$in:['REQ4','REQ1'…]}
是-但这将返回部分匹配的请求,例如REQ4…而不是像REQ1这样的完全匹配候选