MongoDB聚合实现按日期、教育字段分组统计记录数
MongoDB 多维度分组统计实现方案
问题场景
MongoDB集合中存储了带日期、教育领域标签的记录数据,样例数据如下:
[ { "id":1, "year": "2022-10-01", "Area":{ "Education":"Engineering" } }, { "id":2, "year": "2022-10-01", "Area":{ "Education":"Commerce" } }, { "id":3, "year": "2022-10-01", "Area":{ "Education":"Arts" } }, { "id":4, "year": "2022-10-01", "Area":{ "Education":"Arts" } }, { "id":5, "year": "2022-01-01", "Area":{ "Education":"Engineering" } }, { "id":6, "year": "2022-01-01", "Area":{ "Education":"Engineering" } } ]
需求说明
需要实现聚合统计逻辑,规则如下:
- 先按
year日期字段分组 - 同日期分组内,再按嵌套字段
Area.Education二次分组 - 统计每个日期下各教育领域对应的记录数量,最终输出结构以日期为顶级key,嵌套各教育领域的计数值
注:你给出的预期输出中2021-01-01为笔误,实际输入数据中对应日期为2022-01-01
聚合查询代码
直接在MongoDB shell或对应驱动中执行以下聚合管道即可:
db.你的集合名.aggregate([ // 第一阶段:按 日期+教育领域 双维度分组,统计基础计数 { $group: { _id: { year: "$year", eduType: "$Area.Education" }, total: { $sum: 1 } } }, // 第二阶段:按日期维度归组,整理同日期下各领域的键值对 { $group: { _id: "$_id.year", eduCountList: { $push: { k: "$_id.eduType", v: "$total" } } } }, // 第三阶段:构造单日期下的Education嵌套结构 { $project: { _id: 0, dateKey: "$_id", dateValue: { Education: { $arrayToObject: "$eduCountList" } } } }, // 第四阶段:将所有日期结果合并为顶级键值对结构 { $group: { _id: null, resultList: { $push: { k: "$dateKey", v: "$dateValue" } } } }, // 第五阶段:替换根节点,输出最终格式 { $replaceRoot: { newRoot: { $arrayToObject: "$resultList" } } } ])
输出结果
执行上述代码后,得到的返回结果如下:
{ "2022-10-01": { "Education": { "Engineering": 1, "Commerce": 1, "Arts": 2 } }, "2022-01-01": { "Education": { "Engineering": 2 } } }
补充说明
如果需要强制显示计数为0的领域(比如2022-01-01下的Commerce、Arts显示为0),需要额外通过$setUnion先枚举全量教育领域值,再通过$map遍历补全缺失的0值项——因为MongoDB聚合默认不会统计不存在的记录项,不会自动生成0值。
内容的提问来源于stack exchange,提问作者mu-Stack
相关产品推荐
相关产品推荐

