MongoDB聚合:嵌套数组Lookup并将结果合并至对应索引
正确的MongoDB聚合实现方式
步骤1:展开嵌套的child数组
先用$unwind将parent.child数组拆分为单个文档,让每个child元素成为独立的处理单元:
{ $unwind: "$parent.child" }
步骤2:关联Lookup集合
通过$lookup根据subjectId匹配目标集合,仅返回需要的subject_name和cost字段:
{ $lookup: { from: "subjects", // 替换为你的Lookup集合名称 localField: "parent.child.subjectId", foreignField: "_id", as: "subjectDetails" } }
步骤3:合并关联结果到child元素
$lookup返回的是数组结构,用$arrayElemAt取出唯一匹配项,再通过$mergeObjects将child原字段与subject详情合并:
{ $set: { "parent.child": { $mergeObjects: [ "$parent.child", { $arrayElemAt: ["$subjectDetails", 0] } ] } } }
步骤4:恢复数组结构并清理临时字段
删除临时生成的subjectDetails字段,再用$group按主文档_id聚合,将拆分的child元素重新组合为数组:
{ $unset: "subjectDetails" }, { $group: { _id: "$_id", parent: { $first: "$parent" }, // 若主文档有其他顶层字段,需用$first保留,例如: // username: { $first: "$username" } childList: { $push: "$parent.child" } } }, { $set: { "parent.child": "$childList" } }, { $unset: "childList" }
完整聚合管道示例
替换集合名称和额外字段后,完整的聚合语句如下:
db.main.aggregate([ { $unwind: "$parent.child" }, { $lookup: { from: "subjects", localField: "parent.child.subjectId", foreignField: "_id", as: "subjectDetails" } }, { $set: { "parent.child": { $mergeObjects: [ "$parent.child", { $arrayElemAt: ["$subjectDetails", 0] } ] } } }, { $unset: "subjectDetails" }, { $group: { _id: "$_id", parent: { $first: "$parent" }, childList: { $push: "$parent.child" } } }, { $set: { "parent.child": "$childList" } }, { $unset: "childList" } ])
注意事项
- 确保主集合的
subjectId与Lookup集合的_id字段类型一致(避免ObjectId与字符串不匹配的情况) - 若存在
subjectId无匹配项的场景,可在$mergeObjects中用$ifNull处理,例如{ $ifNull: [{ $arrayElemAt: ["$subjectDetails", 0] }, {}] },防止出现null值 - 主文档的所有顶层字段都需要在
$group阶段用$first保留,否则会丢失
内容的提问来源于stack exchange,提问作者Supawat Pothisomphop
相关产品推荐
相关产品推荐

