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

如何在MongoDB的$group阶段生成固定长度的分类统计数组?

问题:统计2000-2010年间每年出版书籍总数及各分类数量

集合数据

假设MongoDB中存在books集合,数据插入语句如下:

db.books.insertMany([
    { "name": "foo", "category": 0, publishedAt: ISODate("2008-09-14T00:00:00Z") },
    { "name": "bar", "category": 1, publishedAt: ISODate("1945-08-17T00:00:00Z") },
    { "name": "baz", "category": 1, publishedAt: ISODate("2002-03-01T00:00:00Z") },
    { "name": "qux", "category": 2, publishedAt: ISODate("2002-01-21T00:00:00Z") },
    { "name": "quux", "category": 4, publishedAt: ISODate("2018-04-18T00:00:00Z") },
])

其中category为枚举整数,对应5个分类:0(Fiction)、1(Fantasy)、2(Classic)、3(Horror)、4(Comic)。

现有实现与当前输出

已完成年份分组及总数统计的聚合管道如下:

db.books.aggregate([
    {
        $match: {
            publishedAt: {
                $gte: ISODate("2000-01-01T00:00:00Z"),
                $lt: ISODate("2011-01-01T00:00:00Z"),
            },
        },
    },
    {
        $group: {
            _id: {
                $year: "$publishedAt",
            },
            totalCount: {
                $count: {},
            },
        },
    },
    {
        $sort: {
            _id: 1,
        },
    },
]);

当前输出结果:

[
    {
        _id: 2002,
        totalCount: 2,
    },
    {
        _id: 2008,
        totalCount: 1,
    },
]

需求补充

需要新增固定长度为5的categoryCount数组字段,数组下标对应category编号,值为该分类的书籍数量,期望输出如下:

[
    {
        _id: 2002,
        totalCount: 2,
        categoryCount: [0, 1, 1, 0, 0],
    },
    {
        _id: 2008,
        totalCount: 1,
        categoryCount: [1, 0, 0, 0, 0],
    },
]

解决方案

修改聚合管道,在$group阶段分别统计每个分类的数量,再通过$project将这些统计值组合成目标数组:

db.books.aggregate([
    {
        $match: {
            publishedAt: {
                $gte: ISODate("2000-01-01T00:00:00Z"),
                $lt: ISODate("2011-01-01T00:00:00Z"),
            },
        },
    },
    {
        $group: {
            _id: { $year: "$publishedAt" },
            totalCount: { $count: {} },
            // 分别统计每个分类的数量
            cat0: { $sum: { $cond: [{ $eq: ["$category", 0] }, 1, 0] } },
            cat1: { $sum: { $cond: [{ $eq: ["$category", 1] }, 1, 0] } },
            cat2: { $sum: { $cond: [{ $eq: ["$category", 2] }, 1, 0] } },
            cat3: { $sum: { $cond: [{ $eq: ["$category", 3] }, 1, 0] } },
            cat4: { $sum: { $cond: [{ $eq: ["$category", 4] }, 1, 0] } }
        },
    },
    {
        $project: {
            _id: 1,
            totalCount: 1,
            // 将分类统计值组合成数组
            categoryCount: ["$cat0", "$cat1", "$cat2", "$cat3", "$cat4"]
        }
    },
    {
        $sort: { _id: 1 },
    },
]);

说明

  1. $group阶段:通过$cond判断每条文档的category值,匹配则计数1,否则0,再用$sum累加得到每个分类的年度总数。
  2. $project阶段:将每个分类的统计字段按顺序放入categoryCount数组,确保下标与分类编号一一对应。
  3. 执行后即可得到符合需求的输出结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 17:25:37