MongoDB单查询合并两集合数据为单数组并实现价格求和
MongoDB跨集合取数合并并计算总价解决方案
问题描述
刚接触MongoDB,希望通过单次查询从store和store1两个集合中获取数据,将所有结果合并为一个数组,以便对price字段求和。目前已获取两个店铺的产品ID数组,需根据这些ID从对应集合获取数据,计算总价后返回给客户端。
当前使用的聚合查询
db.store.aggregate([ { "$lookup": { "from": "store1", pipeline: [ { $match: { $expr: { "$in": [ "$id", { "$map": { // your payload from client here "input": [ "63da2f1f7662144569f78dd6", "63da2f1f7662144569f78dd7", ], "as": "id", "in": { "$toObjectId": "$$id" } } } ] } } }, ], as: "store1" } }, { $match: { $expr: { "$in": [ "$id", { "$map": { // your payload from client here "input": [ "63da2f1f7662144569f78ddd", "63da2f1f7662144569f78ddb", "63da2f1f7662144569f78dda" ], "as": "id", "in": { "$toObjectId": "$$id" } } } ] } } }, { $project: { _id: 0, } } ])
期望输出
[ { "id": ObjectId("63da2f1f7662144569f78ddd"), "name": "bat", "price": 56, }, { "id": ObjectId("63da2f1f7662144569f78ddb"), "name": "cap", "price": 100, }, { "id": ObjectId("63da2f1f7662144569f78dda"), "name": "red", "price": 50, }, { "id": ObjectId("63da2f1f7662144569f78dd6"), "name": "bat", "price": 56 }, { "id": ObjectId("63da2f1f7662144569f78dd7"), "name": "ball", "price": 58 } ]
优化后的查询方案
使用$unionWith操作符可以直接合并两个集合的查询结果,更贴合需求。以下是完整的聚合查询:
db.store.aggregate([ // 匹配store集合中的目标产品ID { $match: { _id: { $in: [ ObjectId("63da2f1f7662144569f78ddd"), ObjectId("63da2f1f7662144569f78ddb"), ObjectId("63da2f1f7662144569f78dda") ] } } }, // 投影出需要的字段,将_id重命名为id以匹配期望输出 { $project: { _id: 0, id: "$_id", name: 1, price: 1 } }, // 合并store1集合的匹配结果 { $unionWith: { coll: "store1", pipeline: [ { $match: { _id: { $in: [ ObjectId("63da2f1f7662144569f78dd6"), ObjectId("63da2f1f7662144569f78dd7") ] } } }, { $project: { _id: 0, id: "$_id", name: 1, price: 1 } } ] } }, // 可选:如果需要直接计算总价,添加此阶段 { $group: { _id: null, totalPrice: { $sum: "$price" }, products: { $push: "$$ROOT" } } }, // 投影最终输出结构,可根据需求调整 { $project: { _id: 0, totalPrice: 1, products: 1 } } ])
方案说明
$match阶段:分别在两个集合的查询管道中匹配目标产品ID,过滤出需要的数据。$project阶段:格式化输出字段,将MongoDB默认的_id字段重命名为id,同时保留name和price字段。$unionWith阶段:将store集合的查询结果与store1集合的查询结果合并为一个数组,实现扁平化的结果集。- 可选的
$group阶段:如果需要直接得到所有产品的总价,可以通过$sum对price字段求和,同时用$push保留所有产品的详细数据。
内容的提问来源于stack exchange,提问作者Rajesh Senapati
相关产品推荐
相关产品推荐

