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

MongoDB Shell中按天分组并按class字段统计指定月份每日数据的实现咨询

问题分析与解决方案

你的聚合查询有几个关键问题,导致没法得到预期结果:


1. 丢失了关键统计字段meta.class

在第一个$project阶段,你只提取了年、月、日信息,完全丢掉了meta.class字段——后面的分组阶段根本没有这个字段可以用来做分类统计,这是核心问题。

2. 分组逻辑顺序颠倒

你先按日期分组统计总数量,再试图按class分组,这和你想要的「先按日期+class统计单类数量,再把同日期的各类统计结果聚合到一起」的逻辑完全相反。

3. 语法小瑕疵

$match阶段末尾多了个冗余逗号,虽然MongoDB可能兼容,但属于不规范写法;另外用$$NOW结合$subtract来计算日期,比直接用ISODate().getTime()更符合MongoDB聚合的规范。


修改后的正确聚合查询

db.collection.aggregate([
    // 筛选近30天的记录,用$$NOW更简洁规范
    {
        $match: {
            "created_at": {
                $gt: { $subtract: [$$NOW, 1000*60*60*24*30] }
            }
        }
    },
    // 提取日期字段,同时保留meta.class(绝对不能丢!)
    {
        $project: {
            "year": { $year: "$created_at" },
            "month": { $month: "$created_at" },
            "day": { $dayOfMonth: "$created_at" },
            "class": "$meta.class" 
        }
    },
    // 第一级分组:按「日期+class」组合分组,统计单日期单class的数量
    {
        $group: {
            _id: {
                year: "$year",
                month: "$month",
                day: "$day",
                class: "$class"
            },
            total: { $sum: 1 }
        }
    },
    // 第二级分组:按日期分组,把同日期的class统计结果整理成数组
    {
        $group: {
            _id: {
                year: "$_id.year",
                month: "$_id.month",
                day: "$_id.day"
            },
            count: {
                $push: {
                    _id: "$_id.class",
                    total: "$total"
                }
            }
        }
    },
    // 可选:按日期排序,让结果更整齐易读
    {
        $sort: {
            "_id.year": 1,
            "_id.month": 1,
            "_id.day": 1
        }
    }
])

逻辑拆解说明

  1. $match阶段:用聚合内置变量$$NOW替代手动生成日期,语法更规范,精准筛选近30天的记录。
  2. $project阶段:在提取日期字段的同时,必须保留meta.class,这是后续分类统计的核心依据。
  3. 第一级$group:先按「日期+class」的组合维度分组,得到每个日期下每个class的独立统计结果,比如{_id: {year:2021, month:10, day:1, class:"class1"}, total:2}。
  4. 第二级$group:按日期维度合并结果,用$push把同日期的所有class统计项打包成count数组,完全匹配你想要的输出格式。
  5. $sort阶段:可选但推荐,让结果按日期从小到大排序,避免输出顺序混乱。

用你提供的示例数据测试,这个查询会输出:

[
    {
        "_id" : { "year" : 2021, "month" : 10, "day" : 1 },
        "count" : [ { "_id" : "class1", "total" : 2 }, { "_id" : "class2", "total" : 1 } ]
    }
]

(注:你的示例数据里10月1日实际有3条记录:class1两条、class2一条,和你写的示例预期略有出入,应该是笔误~)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 00:12:32