MongoDB Aggregate如何实现嵌套子文档ID到名称的映射替换
MongoDB聚合实现方案
核心逻辑是将对象类型字段转为数组遍历替换值,再转回对象结构,全程不需要$unwind,性能较好。
通用兼容版聚合管道(支持MongoDB 3.4+所有版本)
直接替换代码中的你的集合名为实际集合名称即可执行:
db.你的集合名.aggregate([ { $project: { _id: 1, inv: { $arrayToObject: { $map: { input: { $objectToArray: "$inv" }, as: "invItem", in: { k: "$$invItem.k", v: { $let: { vars: { currentFood: { $first: { $filter: { input: { $objectToArray: "$food" }, cond: { $eq: ["$$this.k", "$$invItem.v"] } } } } }, in: "$$currentFood.v.n" } } } } } } } } ])
MongoDB 5.0+简化版写法
5.0版本新增$getField操作符后,可以省去数组过滤的步骤,写法更简洁:
db.你的集合名.aggregate([ { $project: { _id: 1, inv: { $arrayToObject: { $map: { input: { $objectToArray: "$inv" }, as: "invItem", in: { k: "$$invItem.k", v: { $getField: { field: "n", input: { $getField: { field: "$$invItem.v", input: "$food" } } } } } } } } } } ])
管道阶段说明
$objectToArray: "$inv":将原存储id映射的inv对象转为[{k: "food01", v: "id01"}, ...]格式的键值对数组,方便逐个遍历修改值$map:遍历上述键值对数组,保留原键名(即food01、food02这类库存位置标识),将原存储的食物id替换为对应食物的名称$arrayToObject:将修改完成的键值对数组重新转回对象结构,作为新的inv字段$project:只保留需要的_id和新inv字段,丢弃原food等冗余字段
针对给出的样例文档,上述管道执行后会完全返回期望的输出结构。
内容的提问来源于stack exchange,提问作者quanq
相关产品推荐
相关产品推荐

