MongoDB按日期分组并统计指定类别文档数的实现方法
解决MongoDB按日期分组并统计指定类别文档数的问题
没问题,这是个很常见的聚合场景,我一步步给你讲清楚怎么实现。假设你的集合名为articles,文档里包含publishDate(发布日期,ISODate类型)和categories(类别数组)字段。
核心思路
我们通过MongoDB的聚合管道完成三个关键步骤:筛选目标类别文档 → 格式化日期为统一的「年-月-日」格式 → 按日期分组统计数量。
完整聚合代码示例
假设你要统计**类别为「技术」**的文章,按发布日期分组的数量:
db.articles.aggregate([ // 第一步:筛选出包含指定类别的文档,减少后续处理数据量 { $match: { categories: "技术" // 若categories是数组,此写法会匹配数组中包含该值的所有文档 } }, // 第二步:将ISODate格式转为YYYY-MM-DD字符串,确保同一天的文章归为一组 { $addFields: { publishDateStr: { $dateToString: { format: "%Y-%m-%d", date: "$publishDate" } } } }, // 第三步:按格式化后的日期分组,统计每组文档数 { $group: { _id: "$publishDateStr", // 分组键:格式化后的日期字符串 count: { $sum: 1 } // 累加每组的文档数量 } }, // 可选:按日期升序排列结果(换成-1就是降序) { $sort: { _id: 1 } } ])
代码细节解释
- $match阶段:先过滤出符合类别要求的文档,避免无效数据进入后续聚合,提升整体效率。如果需要匹配多个类别,可以用
categories: { $in: ["技术", "教程"] }。 - $addFields阶段:新增一个
publishDateStr字段,把原始的ISODate日期转成统一的字符串格式,确保同一天的文章会被分到同一组(直接用ISODate分组会精确到时分秒,不符合按天统计的需求)。 - $group阶段:以格式化后的日期作为分组标识,用
$sum:1统计每组的文档数量,最终得到每个日期的指定类别文章数。 - $sort阶段:可选步骤,让结果按日期顺序排列,方便查看时间趋势。
扩展场景:同时统计多个类别
如果需要按「日期+类别」分组,统计每天不同指定类别的文章数量,可以调整管道如下:
db.articles.aggregate([ { $match: { categories: { $in: ["技术", "教程"] } // 先筛选包含目标类别的文档 } }, { $unwind: "$categories" // 展开categories数组,每个类别单独成为一条记录 }, { $match: { categories: { $in: ["技术", "教程"] } // 再次过滤,仅保留目标类别 } }, { $addFields: { publishDateStr: { $dateToString: { format: "%Y-%m-%d", date: "$publishDate" } } } }, { $group: { _id: { date: "$publishDateStr", category: "$categories" }, count: { $sum: 1 } } }, { $sort: { "_id.date": 1, "_id.category": 1 } } ])
这个版本会输出类似{ _id: { date: "2024-05-20", category: "技术" }, count: 5 }的结果,清晰展示每天每个指定类别的文章数量。
内容的提问来源于stack exchange,提问作者Grigory Babajanyan
相关产品推荐
相关产品推荐

