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

如何用Mongoose实现硬币数据按国家、系列多级聚合?

MongoDB聚合实现「国家-系列-硬币」层级结构输出

问题描述

在MongoDB中存储了大量硬币数据,后端基于Mongoose+Express开发,需要实现接口将硬币数据按「国家-系列-硬币」的层级结构聚合输出,方便前端调用。现有聚合代码无法将硬币正确归入对应系列。

输入数据示例

[
  {
    "_id": "643d5bf4637daa055466d8f0",
    "country": "AND",
    "denomination": 0.01,
    "series": 1
  },
  {
    "_id": "643d5bf4637daa055466d8f1",
    "country": "AND",
    "denomination": 0.02,
    "series": 1
  },
  {
    "_id": "643d5bf4637daa055466d8f2",
    "country": "USA",
    "denomination": 1,
    "series": 2
  }
]

期望输出格式

[
  {
    "country": "AND",
    "series": [
      {
        "series": 1,
        "coins": [
          {
            "_id": "643d5bf4637daa055466d8f0",
            "country": "AND",
            "denomination": 0.01,
            "series": 1
          },
          {
            "_id": "643d5bf4637daa055466d8f1",
            "country": "AND",
            "denomination": 0.02,
            "series": 1
          }
        ]
      }
    ]
  },
  {
    "country": "USA",
    "series": [
      {
        "series": 2,
        "coins": [
          {
            "_id": "643d5bf4637daa055466d8f2",
            "country": "USA",
            "denomination": 1,
            "series": 2
          }
        ]
      }
    ]
  }
]

现有代码(存在问题)

const coins = await Coin.aggregate([
    {
      $group: {
        _id: '$country',
        series: { $addToSet: { series: '$series', coins: [] } },
      },
    },
    {
      $addFields: { country: '$_id' },
    },
    {
      $project: {
        _id: 0,
      },
    },
    {
      $sort: { country: 1 },
    },
 ]);

完整聚合解决方案

要实现目标层级结构,需要分两次分组:先按「国家+系列」聚合硬币数据,再按「国家」聚合系列信息。完整代码如下:

const coins = await Coin.aggregate([
  // 第一步:按国家+系列分组,收集同系列下的所有硬币
  {
    $group: {
      _id: {
        country: '$country',
        series: '$series'
      },
      coins: { $push: '$$ROOT' } // 将当前完整硬币文档加入coins数组
    }
  },
  // 第二步:按国家分组,整合同一国家的所有系列数据
  {
    $group: {
      _id: '$_id.country',
      series: {
        $push: {
          series: '$_id.series',
          coins: '$coins'
        }
      }
    }
  },
  // 将国家名称从_id转移到country字段
  {
    $addFields: { country: '$_id' }
  },
  // 移除默认_id字段,匹配期望输出结构
  {
    $project: {
      _id: 0
    }
  },
  // 按国家名称升序排序
  {
    $sort: { country: 1 }
  }
]);

代码说明

  1. 第一次$group:

    • 用{country: '$country', series: '$series'}作为分组ID,确保同一国家同系列的硬币被归为一组
    • 通过$push: '$$ROOT'保留硬币的完整文档,存入coins数组
  2. 第二次$group:

    • 按国家维度重新分组,将第一次分组得到的系列对象(包含系列编号和对应硬币数组)整合到series数组中
  3. 后续阶段:

    • $addFields将国家名称从_id字段转移到country字段,符合输出格式
    • $project移除默认生成的_id字段
    • $sort保证输出结果按国家名称有序排列

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:17:51