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

MongoDB聚合:按产品分组数组元素的实现问题

MongoDB聚合分组调整:按月份+产品统计状态计数

原始数据格式

[
    {
        "_id":{
            "month":"Jan",
            "year":"2022"
        },
        "products":[
            {
                "product":"ProdA",
                "status":"failed",
                "count":15
            },
            {
                "product":"ProdA",
                "status":"success",
                "count":5
            },
            {
                "product":"ProdB",
                "status":"failed",
                "count":20
            },
            {
                "product":"ProdB",
                "status":"success",
                "count":10
            }
        ]
    },
    // 更多类似月份数据
]

期望输出格式

[
    {
        "_id":{
            "month":"Jan",
            "year":"2022"
        },
        "products":[
            {
                "product":"ProdA","status":[{"name":"success","count":5},{"name":"failed","count":15}]
            },
            {
                "product":"ProdB","status":[{"name":"success","count":10},{"name":"failed","count":20}]
            }
         ]
    },
    // 后续月份数据
]

尝试的聚合查询

db.collection.aggregate([{ $unwind: "$products" },
{
    $group: {
        "_id": {
            month: "$_id.month",
            year: "$_id.year"
        },
        products: { $push: { "product": "$product", status: { $push: { name: "$status", count: "$count" } } } }
    }
}]);

问题分析与解决方案

你的查询问题在于:在顶层$group中直接嵌套$push生成status数组是无效的,$push不能在$group的字段定义里嵌套使用。要实现期望结构,需要分两层分组:

正确的聚合步骤

  1. 先用$unwind展开products数组,将每个产品状态条目转为独立文档;
  2. 第一层分组:按年月+产品名称聚合,收集每个产品的所有状态数据;
  3. 第二层分组:按年月聚合,重组同一月份下的所有产品数据。

完整聚合代码

db.collection.aggregate([
  // 展开products数组,拆分每个状态条目为独立文档
  { $unwind: "$products" },
  // 第一级分组:按年月+产品名聚合,生成每个产品的status数组
  {
    $group: {
      "_id": {
        month: "$_id.month",
        year: "$_id.year",
        product: "$products.product"
      },
      status: {
        $push: {
          name: "$products.status",
          count: "$products.count"
        }
      }
    }
  },
  // 第二级分组:按年月聚合,重组products数组
  {
    $group: {
      "_id": {
        month: "$_id.month",
        year: "$_id.year"
      },
      products: {
        $push: {
          product: "$_id.product",
          status: "$status"
        }
      }
    }
  }
])

步骤说明

  • $unwind阶段:将原文档中products数组的每个元素拆分为单独文档,确保后续分组能精准定位到每个产品的状态条目;
  • 第一级$group:以年月+产品名为分组键,把同一产品的不同状态数据收集到status数组中,完成单个产品的状态聚合;
  • 第二级$group:以年月为分组键,将同一月份下的所有产品数据(包含已聚合的status数组)合并到products数组,最终得到符合要求的结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 21:20:33