基于字段查找MongoDB中两个对象数组的交集
解决MongoDB中两个数组的交集查找问题
没问题,我来帮你搞定这个需求——要找出文档里plates和accounts两个数组基于rego字段的交集,我们可以用MongoDB的聚合管道来实现,下面是具体的方案:
核心思路
我们需要先提取两个数组中rego字段的集合,找到共同的rego值,再根据这些共同值分别过滤原数组,得到匹配的元素(也就是交集)。
具体聚合查询
db.yourCollectionName.aggregate([ // 第一步:提取两个数组的rego字段列表 { $addFields: { plateRegos: { $map: { input: "$plates", as: "p", in: "$$p.rego" } }, accountRegos: { $map: { input: "$accounts", as: "a", in: "$$a.rego" } } } }, // 第二步:找出两个rego列表的交集 { $addFields: { commonRegos: { $setIntersection: ["$plateRegos", "$accountRegos"] } } }, // 第三步:过滤原数组,只保留rego在交集中的元素 { $addFields: { platesIntersection: { $filter: { input: "$plates", as: "p", cond: { $in: ["$$p.rego", "$commonRegos"] } } }, accountsIntersection: { $filter: { input: "$accounts", as: "a", cond: { $in: ["$$a.rego", "$commonRegos"] } } } } }, // 可选:清理结果,只保留需要的字段 { $project: { _id: 1, qty: 1, platesIntersection: 1, accountsIntersection: 1 } } ])
代码解释
- 第一个
$addFields:分别从plates和accounts数组中提取所有rego值,生成两个临时数组plateRegos和accountRegos。 - 第二个
$addFields:用$setIntersection操作符找出两个rego数组的共同值,得到commonRegos。 - 第三个
$addFields:用$filter过滤原数组,只保留rego在commonRegos中的元素,得到最终的交集数组platesIntersection和accountsIntersection。 $project阶段:可选步骤,用来移除临时生成的字段,让结果更简洁。
针对你的示例文档的输出结果
运行上述查询后,你会得到如下结果:
{ "_id": "Suzuki", "qty": 10, "platesIntersection": [ { "rego": "1QX-WA-123", "date": 1516374000000.0 } ], "accountsIntersection": [ { "_id": "23kpi9MD4KnTvnaW7", "createdAt": 1513810712802.0, "date": 1503446400000.0, "type": "Suzuki", "rego": "1QX-WA-123" } ] }
进阶:合并匹配的元素
如果你想把匹配的plates和accounts元素关联起来,可以在上述管道末尾添加一个$addFields阶段:
{ $addFields: { combinedIntersection: { $map: { input: "$platesIntersection", as: "p", in: { plate: "$$p", account: { $first: { $filter: { input: "$accountsIntersection", as: "a", cond: { $eq: ["$$a.rego", "$$p.rego"] } } } } } } } } }
这样会得到一个combinedIntersection数组,每个元素包含一对匹配的plate和account对象。
内容的提问来源于stack exchange,提问作者Waqas
相关产品推荐
相关产品推荐

