MongoDB聚合分组问题:按sucursal合并同producto的kilos值
MongoDB聚合分组问题:合并同分店同产品的重量
原始数据
[ { "sucursal": 1, "productos": [ { "producto": 1, "kilos": 50 } ] }, { "sucursal": 2, "productos": [ { "producto": 1, "kilos": 30 }, { "producto": 2, "kilos": 50 } ] }, { "sucursal": 1, "productos": [ { "producto": 1, "kilos": 50 }, { "producto": 2, "kilos": 40 } ] } ]
期望结果
[ { "sucursal": 1, "productos": [ { "producto": 1, "kilos": 100 }, { "producto": 2, "kilos": 40 } ] }, { "sucursal": 2, "productos": [ { "producto": 1, "kilos": 30 }, { "producto": 2, "kilos": 50 } ] } ]
错误代码
const ordenesTotal = await OrdCompCli.aggregate([ { $match: { fechaEntrega: new Date(fecha), estado: { $gt: 0, $lt: 5 } } }, { $unwind: "$productos" }, { $group: { _id: "$sucursal", productos: { $addToSet: { producto: "$productos.producto", totalKilos: { $sum: "$productos.kilos" } } } } }, { $project: { _id: 0, sucursal: "$_id", productos: 1 }, }, ])
问题分析
你的代码核心问题是分组层级错误:
- 直接按
sucursal分组后,$sum写在$addToSet内部,只能计算当前单条文档的产品重量,无法跨文档累加同产品的总重量。 $addToSet会将每个独立的产品对象(哪怕producto相同)都加入数组,导致同一产品重复出现。
修正后的代码
const ordenesTotal = await OrdCompCli.aggregate([ // 过滤目标文档 { $match: { fechaEntrega: new Date(fecha), estado: { $gt: 0, $lt: 5 } } }, // 展开产品数组,让每个产品成为独立文档 { $unwind: "$productos" }, // 第一步分组:按「分店+产品」组合累加重量 { $group: { _id: { sucursal: "$sucursal", producto: "$productos.producto" }, totalKilos: { $sum: "$productos.kilos" } } }, // 第二步分组:按分店重组产品数组 { $group: { _id: "$_id.sucursal", productos: { $push: { producto: "$_id.producto", kilos: "$totalKilos" } } } }, // 调整输出字段格式 { $project: { _id: 0, sucursal: "$_id", productos: 1 } } ])
步骤说明
$match:保留原过滤逻辑,只处理指定日期和状态的文档。$unwind:展开产品数组,将每个产品条目转为独立文档,为后续分组累加做准备。- 第一次
$group:用{sucursal, producto}作为分组键,确保同一分店的同一产品被归为一组,通过$sum累加所有对应重量。 - 第二次
$group:按分店重新分组,用$push将已累加好重量的产品组装为数组。 $project:调整输出结构,将_id映射为sucursal字段,移除原始_id。
内容的提问来源于stack exchange,提问作者Mizrain
相关产品推荐
相关产品推荐

