MongoDB聚合框架如何关联Parent、Mapper表为Items集合补充Type字段
实现方案
MongoDB原生$lookup只支持左连接,要保留全部Items记录,最直接的方式是把Items作为聚合起始集合,全程用左连接关联其他表,不需要额外实现右连接逻辑,完整查询代码如下:
db.Items.aggregate([ // 关联Mapper集合,通过Identifier匹配对应Type { $lookup: { from: "Mapper", localField: "Identifier", foreignField: "Identifier", as: "mapper_info" } }, // 打平关联结果,未匹配到的记录保留为null { $unwind: { path: "$mapper_info", preserveNullAndEmptyArrays: true } }, // 关联Parent集合,过滤ParentName=GP的匹配记录 { $lookup: { from: "Parent", let: { mapper_type: "$mapper_info.Type" }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ["$ParentName", "GP"] }, { $eq: ["$Type", "$$mapper_type"] } ] } } }, { $project: { Type: 1, _id: 0 } } ], as: "parent_info" } }, // 打平Parent关联结果,未匹配到的记录保留为null { $unwind: { path: "$parent_info", preserveNullAndEmptyArrays: true } }, // 输出最终字段,未匹配到Type的记录不返回该字段 { $project: { _id: 0, Name: 1, Identifier: 1, Type: "$parent_info.Type" } } ]).pretty()
备选方案(小数据量适用)
如果要沿用你之前先筛选GP对应有效映射的思路,可以先查出映射关系再批量补到Items中:
// 先查询GP对应的所有有效Type-Identifier映射 const validMappings = db.Parent.aggregate([ { $match: { ParentName: "GP" } }, { $lookup: { from: "Mapper", localField: "Type", foreignField: "Type", as: "mapper" } }, { $unwind: "$mapper" }, { $project: { _id: 0, Type: 1, Identifier: "$mapper.Identifier" } } ]).toArray() // 遍历Items补全Type字段 const result = db.Items.find().map(item => { const match = validMappings.find(m => m.Identifier === item.Identifier) if (match) item.Type = match.Type delete item._id return item }) printjson(result)
内容的提问来源于stack exchange,提问作者thewaterwalker
相关产品推荐
相关产品推荐

