MongoDB聚合实现按供应商分组统计订单产品金额小计
最新版MongoDB完全支持通过单条聚合管道实现该需求,以下是具体实现方案。
实现思路
- 首先过滤无关文档:仅保留
orderType为CUST的客户订单,排除SUPP类型的供应商采购单,这类文档不包含需要统计的客户订单产品明细。 - 拆分嵌套产品数组:通过
$unwind将每个客户订单下custPO.products的嵌套数组拆分为独立的中间记录,每条记录对应订单内的单个产品项。 - 按维度分组求和:以订单号、客户信息、供应商名称为分组键,对同组产品的
valueTotal字段求和,得到每个订单下各供应商对应的累计金额;没有供应商信息的项(如运费),供应商名称自动取null。 - 整理输出结构:再次按订单号、客户信息分组,将同个订单下所有供应商的统计结果整理为
totals数组,调整字段顺序后匹配预期输出格式。
可直接运行的聚合语句
db.orderCollection.aggregate([ // 筛选客户类型订单 { $match: { orderType: "CUST" } }, // 拆分产品数组 { $unwind: "$custPO.products" }, // 按订单+客户+供应商维度计算金额总和 { $group: { _id: { orderNo: "$orderNo", company: "$company", supplierName: "$custPO.products.product.supplier.company.name" }, supplierTotal: { $sum: "$custPO.products.valueTotal" } } }, // 按订单维度聚合,组装供应商统计数组 { $group: { _id: { orderNo: "$_id.orderNo", company: "$_id.company" }, totals: { $push: { supplierName: "$_id.supplierName", supplierTotal: "$supplierTotal" } } } }, // 调整输出字段,去掉自动生成的_id字段 { $project: { _id: 0, orderNo: "$_id.orderNo", company: "$_id.company", totals: 1 } } ])
补充说明
- 针对你提供的示例数据,执行上述语句返回的结果和预期完全一致:
SUPPLIER ONE GMBH对应累计金额56,SUPPLIER TWO GMBH对应累计金额40,无供应商的运费项对应累计金额50,总金额和订单grandTotal_eur字段值146完全对齐。 - 若你需要严格仅统计标记了
toBuy: true的产品,只需要在$unwind阶段后新增如下匹配阶段即可,此时运费这类无toBuy标记的非采购项会被排除:
{ $match: { "custPO.products.product.toBuy": true } }
内容的提问来源于stack exchange,提问作者REALSOFO
相关产品推荐
相关产品推荐

