MongoDB如何将订单数组项的product字段替换为完整实体数据?
如何将订单中products数组的product字段替换为完整实体数据
需求说明
需要将orders集合中每个订单文档的products数组内,每个元素的product子文档(仅包含_id)替换为products集合中对应的完整产品实体数据,最终得到包含完整产品信息的订单数据。
数据库结构
db={ "orders": [ { "_id": 1, "products": [ { amount: 1, product: { _id: 1 } }, { amount: 1, product: { _id: 2 } } ] }, { "_id": 2, "products": [ { amount: 1, product: { _id: 3 } }, { amount: 1, product: { _id: 4 } } ] } ], "products": [ { "_id": 1, "description": "product 1" }, { "_id": 2, "description": "product 2" }, { "_id": 3, "description": "product 3" }, { "_id": 4, "description": "product 4" } ] }
期望结果
[ { "_id": 1, "products": [ { "amount": 1, "product": { "_id": 1, "description": "product 1" } }, { "amount": 1, "product": { "_id": 2, "description": "product 2" } } ] }, { "_id": 2, "products": [ { "amount": 1, "product": { "_id": 3, "description": "product 3" } }, { "amount": 1, "product": { "_id": 4, "description": "product 4" } } ] } ]
正确查询语句
使用MongoDB聚合管道实现关联替换:
db.orders.aggregate([ // 关联products集合,获取当前订单所有产品的完整信息 { $lookup: { from: "products", let: { orderProductIds: "$products.product._id" }, pipeline: [ { $match: { $expr: { $in: ["$_id", "$$orderProductIds"] } } } ], as: "matchedProducts" } }, // 遍历原products数组,替换product字段为完整实体 { $project: { products: { $map: { input: "$products", as: "item", in: { amount: "$$item.amount", product: { $first: { $filter: { input: "$matchedProducts", cond: { $eq: ["$$this._id", "$$item.product._id"] } } } } } } } } } ])
语句说明
$lookup阶段:
- 指定关联的集合为
products - 通过
let提取当前订单所有产品的_id列表 - 在子管道
pipeline中筛选出_id属于该列表的产品,存入matchedProducts字段
- 指定关联的集合为
$project阶段:
- 使用
$map遍历原products数组的每个元素 - 保留原元素的
amount字段,通过$filter从matchedProducts中匹配对应_id的产品,并用$first取出唯一匹配结果,替换原product字段的值
- 使用
内容的提问来源于stack exchange,提问作者azzlack
相关产品推荐
相关产品推荐

