MongoDB聚合关联两个集合并返回独立数组的实现方法
MongoDB聚合关联ParentDocument与ReferencedDocument并返回独立数组
核心思路
要实现需求,需通过聚合管道完成以下关键步骤:
- 筛选出指定
code的目标父文档 - 从父文档的嵌套结构中提取所有关联的引用键(
key字段) - 对引用键去重,避免重复关联
- 关联
ReferencedDocument集合,匹配对应的引用文档 - 最终将结果整理为包含
Parent和Reference两个独立数组的结构
示例1聚合查询(筛选OF_Code、OF_Code2)
db.ParentDocument.aggregate([ // 筛选目标父文档 { $match: { code: { $in: ["OF_Code", "OF_Code2"] } } }, // 逐层展开嵌套数组,提取关联key { $unwind: "$attributes.associatedProducts" }, { $unwind: "$attributes.associatedProducts.bundleProducts" }, { $unwind: "$attributes.associatedProducts.bundleProducts.products" }, // 暂存父文档code和关联key { $project: { parentCode: "$code", refKey: "$attributes.associatedProducts.bundleProducts.products.key", _id: 0 } }, // 聚合去重,收集父文档code和引用key { $group: { _id: null, parentCodes: { $addToSet: "$parentCode" }, refKeys: { $addToSet: "$refKey" } } }, // 关联引用文档集合 { $lookup: { from: "ReferencedDocument", localField: "refKeys", foreignField: "code", as: "Reference" } }, // 整理最终输出结构 { $project: { _id: 0, Parent: { $map: { input: "$parentCodes", as: "code", in: { code: "$$code" } } }, Reference: "$Reference" } } ])
各阶段说明
- $match:过滤出指定
code的父文档,缩小处理范围。 - 多次$unwind:逐层展开嵌套数组,将深层的
key字段提取到顶层,方便后续处理。 - $project:仅保留需要的字段,减少数据处理量。
- $group:将所有文档聚合为一组,用
$addToSet实现父文档code和引用key的去重收集。 - $lookup:根据去重后的引用key,关联
ReferencedDocument获取匹配的引用文档。 - $project:将收集到的父文档code转换为需求的对象结构,输出最终格式。
示例2的调整(筛选OF_Code、OF_Code3)
只需修改$match阶段的$in数组为["OF_Code", "OF_Code3"],其余逻辑完全相同,即可得到包含REF_123和REF_456的引用数组(注:用户示例2中写的REF_789应为笔误,实际匹配的是REF_456)。
补充提示
- 若父文档的嵌套数组可能为空,可在
$unwind阶段添加preserveNullAndEmptyArrays: true,避免丢失空数组对应的父文档。 - 为提升查询性能,建议给
ParentDocument.code和ReferencedDocument.code字段建立索引。
内容的提问来源于stack exchange,提问作者Hero
相关产品推荐
相关产品推荐

