MongoDB聚合求助:重组深层嵌套对象数组并恢复原结构
MongoDB聚合:深层嵌套数组Lookup后恢复原结构
针对深层嵌套数组的关联查询并还原原结构,核心思路是先逐层解构数组完成关联,再重新组装回原始层级。以下用通用示例演示完整实现步骤:
模拟输入文档
假设你有如下结构的父集合文档:
{ "_id": ObjectId("60d21b4667d0d8992e610c85"), "name": "Parent Doc", "nestedArrays": [ { "groupName": "Group A", "items": [ { "itemId": ObjectId("60d21b4667d0d8992e610c86"), "quantity": 2 }, { "itemId": ObjectId("60d21b4667d0d8992e610c87"), "quantity": 3 } ] } ] }
目标输出结构
将itemId关联items集合的详情后,保留原嵌套层级:
{ "_id": ObjectId("60d21b4667d0d8992e610c85"), "name": "Parent Doc", "nestedArrays": [ { "groupName": "Group A", "items": [ { "itemId": ObjectId("60d21b4667d0d8992e610c86"), "quantity": 2, "itemDetails": { "_id": ObjectId("60d21b4667d0d8992e610c86"), "name": "Item 1", "price": 10 } }, { "itemId": ObjectId("60d21b4667d0d8992e610c87"), "quantity": 3, "itemDetails": { "_id": ObjectId("60d21b4667d0d8992e610c87"), "name": "Item 2", "price": 20 } } ] } ] }
完整聚合管道
db.parentCollection.aggregate([ // 1. 解构外层嵌套数组 { $unwind: "$nestedArrays" }, // 2. 解构内层items数组,让每个item独立以便关联 { $unwind: "$nestedArrays.items" }, // 3. 执行Lookup关联items集合 { $lookup: { from: "items", localField: "nestedArrays.items.itemId", foreignField: "_id", as: "nestedArrays.items.itemDetails" } }, // 4. 将Lookup返回的数组展开为单个对象 { $unwind: "$nestedArrays.items.itemDetails" }, // 5. 重新组装内层items数组 { $group: { _id: { docId: "$_id", groupName: "$nestedArrays.groupName" }, name: { $first: "$name" }, items: { $push: "$nestedArrays.items" } } }, // 6. 重新组装外层nestedArrays数组,还原原结构 { $group: { _id: "$_id.docId", name: { $first: "$name" }, nestedArrays: { $push: { groupName: "$_id.groupName", items: "$items" } } } }, // 可选:指定字段顺序,与原文档对齐 { $project: { _id: 1, name: 1, nestedArrays: 1 } } ])
关键注意事项
- 若嵌套层级更深,只需重复**$unwind -> Lookup -> $group**的逻辑逐层处理
- 若Lookup可能返回多个结果,可改用
$arrayElemAt取指定结果,避免$unwind丢失数据 - 若原数组存在空值,需给
$unwind添加preserveNullAndEmptyArrays: true参数,防止文档被过滤
内容的提问来源于stack exchange,提问作者boulepick
相关产品推荐
相关产品推荐

