MongoDB aggregate实现同文档内ID数组替换为对应对象
同文档内ID映射为完整对象的聚合实现方案
你已经完成了目标文档匹配、指定容器提取的步骤,假设当前聚合阶段输出的文档结构参考如下:
{ "_id": ObjectId("xxx"), "allItems": [ {"_id": "item1", "name": "物品1", "price": 10}, {"_id": "item2", "name": "物品2", "price": 20}, {"_id": "item3", "name": "物品3", "price": 30} ], "targetContainer": { "_id": "container1", "name": "容器1", "selectedItems": ["item1", "item3"] } }
因为是同文档内的字段映射,不需要调用$lookup,直接用数组操作算子就能实现替换,提供两种常用实现方案:
方案1:索引匹配实现(性能更高)
用$map遍历ID数组,配合$indexOfArray找到ID在allItems中的对应索引,再用$arrayElemAt取出完整对象,适合allItems中ID唯一的场景。
追加的聚合阶段代码如下:
{ $addFields: { "targetContainer.selectedItems": { $map: { input: "$targetContainer.selectedItems", as: "itemId", in: { $arrayElemAt: [ "$allItems", { $indexOfArray: ["$allItems._id", "$$itemId"] } ] } } } } }
注意:如果selectedItems中存在allItems没有的无效ID,对应位置会返回null,可后续追加$filter阶段过滤空值
方案2:过滤匹配实现(容错性更强)
用$filter筛选匹配ID的item对象,再用$first取出第一个匹配结果,适合可能存在ID重复的场景。
追加的聚合阶段代码如下:
{ $addFields: { "targetContainer.selectedItems": { $map: { input: "$targetContainer.selectedItems", as: "itemId", in: { $first: { $filter: { input: "$allItems", cond: { $eq: ["$$this._id", "$$itemId"] } } } } } } } }
可选收尾阶段
如果不需要返回原始allItems数组,可追加$project阶段删除冗余字段:
{ $project: { allItems: 0 } }
内容的提问来源于stack exchange,提问作者dennis
相关产品推荐
相关产品推荐

