You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过MongoDB聚合查询直接按月份分组统计各公司交易数?

问题:MongoDB聚合查询直接转换为按月份分组的公司交易统计格式

需求说明

希望直接通过MongoDB聚合查询,按月份统计各公司的交易数量并输出目标格式,不用后续循环处理结果。

现有数据格式

[{
    "id": "1",
    "month": "October",
    "company": "tesla",
    "saleId": "111"
},
{ 
    "id": "2",
    "month": "October",
    "company": "ford",
    "saleId": "222"
},
{
  "id": "3",
  "month": "October",
  "company": "tesla",
  "saleId": "333"
},
{
    "id": "4",
    "month": "November",
    "company": "tesla",
    "saleId": "444"
},
{
    "id": "5",
    "month": "December",
    "company": "kia",
    "saleId": "555"
},
{
    "id": "6",
    "month": "December",
    "company": "ford",
    "saleId": "666"
}]

期望输出格式

{
    "October": [{
            "company": "tesla",
            "count": 2
        },
        {
            "company": "ford",
            "count": 1
        }
    ],
    "November": [{
        "company": "tesla",
        "count": 1
    }],
    "December": [{
            "company": "kia",
            "count": 1
        },
        {
            "company": "ford",
            "count": 1
        }
    ]
}

当前聚合查询及结果

当前查询代码

let result = await con.aggregate([
    { 
      $group : { 
        _id:{
          month: "$month",
          company: "$company",
        }, 
        count:{$sum:1}
      }
    }
]).toArray();

当前查询结果

[
    { "_id": { "month": "October", "company": "tesla" }, "count": 2 },
    { "_id": { "month": "November", "company": "tesla" }, "count": 1 },
    { "_id": { "month": "October", "company": "ford" }, "count": 1 },
    { "_id": { "month": "December", "company": "ford" }, "count": 1 },
    { "_id": { "month": "December", "company": "kia" }, "count": 1 }
]

解决方案:扩展聚合管道完成格式转换

可以通过添加额外的聚合阶段,直接在查询层面得到目标格式,无需后续处理。修改后的聚合管道如下:

let result = await con.aggregate([
    // 第一步:按月份+公司分组统计交易数量
    { 
      $group : { 
        _id:{
          month: "$month",
          company: "$company",
        }, 
        count: {$sum: 1}
      }
    },
    // 第二步:按月份重新分组,把同月份的公司统计结果整理为数组
    {
      $group: {
        _id: "$_id.month",
        companyStats: {
          $push: {
            company: "$_id.company",
            count: "$count"
          }
        }
      }
    },
    // 第三步:将文档转为键值对形式,月份作为键,统计数组作为值
    {
      $replaceRoot: {
        newRoot: {
          $arrayToObject: [[{
            k: "$_id",
            v: "$companyStats"
          }]]
        }
      }
    },
    // 第四步:将所有月份的统计结果合并为单个对象(可选,需要单个对象而非数组时用)
    {
      $group: {
        _id: null,
        merged: { $mergeObjects: "$$ROOT" }
      }
    },
    {
      $replaceRoot: { newRoot: "$merged" }
    }
]).toArray();

各阶段作用说明

  • 第一阶段:和原查询逻辑一致,先按月份+公司的组合分组,统计每组的交易次数。
  • 第二阶段:以月份为分组键,把每个月份下的公司统计数据(包含公司名和数量)收集到一个数组里。
  • 第三阶段:用$arrayToObject把当前文档转换成「月份: 统计数组」的键值对结构,再替换根文档。
  • 第四阶段:如果需要最终结果是单个对象而不是多个对象的数组,就通过$group和$mergeObjects把所有月份的统计结果合并成一个对象,最后替换根文档得到目标格式。

执行这个查询后,就能直接得到你想要的输出格式,不用再做后续循环处理。


内容的提问来源于stack exchange,提问作者Dev1ce

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 13:40:24