MongoDB聚合查询嵌套数组对象:$lookup结果格式修正需求
MongoDB 实现嵌套数组元素的$lookup关联
直接用localField: 'positions.position_id'做关联会把原数组转成对象,要给数组每个元素嵌入对应的详情,可采用以下两种方案:
场景还原
原projects集合数据:
[ { "name": "projectName1", "positions": [ { "position_id": "63d78e5096109914dc963431", "use": true, "wage": 0, "default": true }, { "position_id": "63d78e5096109914dc963433", "use": true, "wage": 0, "default": true } ] } ]
关联的positions集合数据:
[ { "_id": "63d78e5096109914dc963431", "field": "electrical", "regularName": "elc" }, { "_id": "63d78e5096109914dc963433", "field": "mechanic", "regularName": "mec" } ]
推荐方案(MongoDB 3.6+)
用$map遍历数组,结合子查询版$lookup,无需拆分合并,效率更高:
db.projects.aggregate([ { $addFields: { positions: { $map: { input: "$positions", as: "pos", in: { $mergeObjects: [ "$$pos", { positionDetails: { $arrayElemAt: [ { $lookup: { from: "positions", localField: "$$pos.position_id", foreignField: "_id", as: "temp" } }, 0 ] } } ] } } } } } ])
逻辑说明
$map遍历每个positions元素,通过$mergeObjects将原元素与关联结果合并- 由于
$lookup默认返回数组,用$arrayElemAt取第一个元素转为单个对象,匹配预期的详情结构
兼容旧版本方案
若使用MongoDB版本低于3.6,可通过拆分数组再合并的方式实现:
db.projects.aggregate([ // 拆分数组,保留空数组的文档 { $unwind: { path: "$positions", preserveNullAndEmptyArrays: true } }, // 关联详情 { $lookup: { from: "positions", localField: "positions.position_id", foreignField: "_id", as: "positions.positionDetails" } }, // 把数组转成单个对象 { $addFields: { "positions.positionDetails": { $arrayElemAt: ["$positions.positionDetails", 0] } } }, // 按原文档_id合并数组 { $group: { _id: "$_id", name: { $first: "$name" }, positions: { $push: "$positions" } } } ])
注意事项
- 必须添加
preserveNullAndEmptyArrays: true,否则没有positions的文档会被过滤掉
内容的提问来源于stack exchange,提问作者Mehdi M
相关产品推荐
相关产品推荐

