求助:MongoDB实现lookup并合并嵌套数组的方法
MongoDB关联查询并合并对象实现方案
需求说明
从cases文档的suspects字段中,关联suspects和lawyers集合,将关联到的文档字段与原suspects对象(包括其下的lawyer子对象)合并,最终得到包含完整嫌疑人、律师信息的结果。
完整聚合管道代码
db.cases.aggregate([ // 展开suspects数组,逐个处理每个嫌疑人 { $unwind: "$suspects" }, // 关联suspects集合获取嫌疑人详情 { $lookup: { from: "suspects", let: { suspectId: { $toObjectId: "$suspects.id" } }, pipeline: [ { $match: { $expr: { $eq: ["$_id", "$$suspectId"] } } }, { $project: { _id: 0, fullName: 1, phoneNumber: 1, totalCriminalRecord: 1 } } ], as: "suspectDetails" } }, // 将lookup返回的数组转为单个对象 { $unwind: "$suspectDetails" }, // 合并原嫌疑人对象与详情信息 { $addFields: { "suspects": { $mergeObjects: ["$suspects", "$suspectDetails"] } } }, // 移除临时字段 { $unset: "suspectDetails" }, // 关联lawyers集合获取律师详情 { $lookup: { from: "lawyers", let: { lawyerId: { $toObjectId: "$suspects.lawyer.id" } }, pipeline: [ { $match: { $expr: { $eq: ["$_id", "$$lawyerId"] } } }, { $project: { _id: 0, fullName: 1, phoneNumber: 1, workAddress: 1 } } ], as: "lawyerDetails" } }, // 将lookup返回的数组转为单个对象 { $unwind: "$lawyerDetails" }, // 合并原律师对象与详情信息 { $addFields: { "suspects.lawyer": { $mergeObjects: ["$suspects.lawyer", "$lawyerDetails"] } } }, // 移除临时字段 { $unset: "lawyerDetails" }, // 重新组合suspects数组,还原原文档结构 { $group: { _id: "$_id", crimeNumber: { $first: "$crimeNumber" }, eventDate: { $first: "$eventDate" }, suspects: { $push: "$suspects" } } } ])
关键步骤解析
- 展开数组:用
$unwind拆分suspects数组,确保每个嫌疑人能单独进行关联查询。 - 关联并保留原数据:不再直接覆盖
suspects字段,而是将关联结果存入临时字段(suspectDetails、lawyerDetails),避免丢失原对象中的note等自定义信息。 - 合并对象:通过
$mergeObjects将原对象与关联得到的详情字段合并,保留原字段的同时补充新信息。 - 重组数组:最后用
$group将拆分后的嫌疑人重新组合为数组,还原cases文档的原始结构。
内容的提问来源于stack exchange,提问作者kibar
相关产品推荐
相关产品推荐

