MongoDB查询指定日期范围记录并按月分组统计用户数
没问题,我来帮你搞定这个MongoDB的统计需求!
实现思路
我们可以用MongoDB的聚合框架来完成这个需求,核心步骤是:筛选时间范围内的文档 → 按月份分组计数 → 排序 → 整理成目标数组格式。
完整聚合查询代码
把下面的yourCollectionName替换成你实际的集合名称即可:
db.yourCollectionName.aggregate([ // 1. 筛选创建时间在目标区间内的文档 { $match: { created: { $gte: ISODate("2017-01-01T00:00:00.000Z"), $lt: ISODate("2018-05-01T00:00:00.000Z") // 用小于5月1日确保包含4月30日全天的记录 } } }, // 2. 按年+月分组,统计每组用户数 { $group: { _id: { year: { $year: "$created" }, month: { $month: "$created" } }, count: { $sum: 1 } } }, // 3. 按年份、月份升序排序,保证顺序正确 { $sort: { "_id.year": 1, "_id.month": 1 } }, // 4. 格式化月份为YYYY-MM格式(补前导零),同时清理冗余字段 { $project: { _id: 0, month: { $concat: [ { $toString: "$_id.year" }, "-", { $toString: { $cond: [{ $lt: ["$_id.month", 10] }, { $concat: ["0", { $toString: "$_id.month" }] }, "$_id.month"] } } ] }, count: 1 } }, // 5. 将所有月份统计结果合并成一个数组 { $group: { _id: null, monthlyCounts: { $push: "$$ROOT" } } }, // 6. 只保留最终的数组字段 { $project: { _id: 0, monthlyCounts: 1 } } ])
返回结果示例
执行后会得到类似这样的结构:
{ "monthlyCounts": [ { "month": "2017-01", "count": 120 }, { "month": "2017-02", "count": 156 }, ... { "month": "2018-04", "count": 198 } ] }
可选调整:只返回纯计数数组
如果你只需要[120,156,...198]这样的纯数字数组,可以把最后两个聚合阶段改成:
{ $group: { _id: null, monthlyCounts: { $push: "$count" } } }, { $project: { _id: 0, monthlyCounts: 1 } }
额外提示
- 性能优化:如果
created字段没有索引,建议创建一个单字段索引:db.yourCollectionName.createIndex({ created: 1 }),能大幅提升大集合下的查询速度。 - 时区适配:默认
$year/$month用UTC时间统计,如果你的业务用的是其他时区,可以改用$dateToString指定时区,比如:$dateToString: { format: "%Y-%m", date: "$created", timezone: "Asia/Shanghai" // 替换成你的业务时区 }
内容的提问来源于stack exchange,提问作者Michel El Hajj
相关产品推荐
相关产品推荐

