MongoDB聚合查询:按Product对象汇总Price与Quantity
解决MongoDB产品分类聚合问题
你的核心问题在于products.items是嵌套对象(键为产品ID),而非数组,直接用$group按$products.items分组无法遍历每个独立产品。我们需要先将这个对象转换为数组,再执行聚合求和,最后调整为你期望的输出格式。
完整聚合管道代码
db.sales.aggregate([ // 第一步:将products.items对象转为数组,每个元素为 {k: 产品ID, v: 产品详情} { $addFields: { productArray: { $objectToArray: "$products.items" } } }, // 第二步:展开数组,让每个产品成为独立文档 { $unwind: "$productArray" }, // 第三步:按产品ID分组,求和price和quantity { $group: { _id: "$productArray.k", // 产品ID(对应原对象的键) sum_price: { $sum: "$productArray.v.price" }, sum_quantity: { $sum: "$productArray.v.quantity" } } }, // 第四步:将分组结果转为你期望的键值对格式(可选,若需要对象形式而非数组) { $group: { _id: null, products: { $push: { k: "$_id", v: { sum_price: "$sum_price", sum_quantity: "$sum_quantity" } } } } }, { $replaceRoot: { newRoot: { $arrayToObject: "$products" } } } ])
代码分步解释
- $addFields + $objectToArray:把
products.items这个键值对对象,转换成[{k: "产品ID", v: {...产品详情}}, ...]的数组,这样我们才能遍历每个产品。 - $unwind:将数组展开,每个产品单独成为一条文档,此时每条文档只包含一个产品的信息。
- $group:按产品ID(
productArray.k)分组,对每个产品的price和quantity分别求和。 - 可选的格式转换:如果需要输出为你展示的
{产品ID: {sum_price: ..., sum_quantity: ...}}这种对象格式,就用最后两步将分组后的数组转回对象;如果接受数组格式(每个元素是{_id: 产品ID, sum_price: ..., sum_quantity: ...}),可以去掉最后两步。
针对你的示例文档的输出
如果执行上述完整管道,输出会是:
{ "5d515979736802000415a561": { "sum_price": 220, "sum_quantity": 2 }, "5d515aba736802000415a562": { "sum_price": 80, "sum_quantity": 1 }, "5d515dbf736802000415a564": { "sum_price": 150, "sum_quantity": 1 } }
(注:示例文档里只有一笔订单,所以求和结果就是该订单里的对应值;如果有多笔订单,会自动累加所有订单中对应产品的数值)
内容的提问来源于stack exchange,提问作者Carlos Alexandre Silveira
相关产品推荐
相关产品推荐

