如何在MongoDB中按日分组查询指定月内的时间区间数据?
可以通过单个聚合查询实现需求
你可以通过以下聚合管道完成一个月内按日分组、每日再按_id统计的需求,无需多次手动修改日期:
完整聚合查询
db.collection.aggregate([ // 筛选目标月份的所有文档(这里以2022年11月为例) { "$match": { "time": { "$gte": ISODate("2022-11-01T00:00:00.000+05:30"), "$lte": ISODate("2022-11-30T23:59:59.999+05:30") } } }, // 将time字段截断到"日"级别,生成当日的起始日期(匹配文档时区) { "$addFields": { "day": { "$dateTrunc": { date: "$time", unit: "day", timezone: "+05:30" } } } }, // 按「日+_id」分组,统计每个_id当日的value总和与最早记录时间 { "$group": { "_id": { "day": "$day", "id": "$_id" }, "total_value": { "$sum": "$value" }, "first_time": { "$min": "$time" } } }, // 可选:将同一日的所有_id统计结果聚合到一组,结构更清晰 { "$group": { "_id": "$_id.day", "daily_stats": { "$push": { "id": "$_id.id", "total": "$total_value", "first_record_time": "$first_time" } } } }, // 可选:按日期升序排序 { "$sort": { "_id": 1 } } ])
关键阶段说明
- $dateTrunc:精准将时间截断到"日"级别,指定
timezone确保和文档时区一致,避免跨时区导致的日期分组错误。 - 双层
$group:第一层先按「日期+_id」分组计算单id当日统计值;第二层把同一日期的所有id统计结果整合到数组中,方便查看每日整体数据。
查询结果示例
{ "_id": ISODate("2022-11-05T00:00:00.000+05:30"), "daily_stats": [ { "id": 1, "total": 2, "first_record_time": ISODate("2022-11-05T23:58:43.818+05:30") }, { "id": 2, "total": 1, "first_record_time": ISODate("2022-11-05T23:58:43.818+05:30") } ] }, { "_id": ISODate("2022-11-06T00:00:00.000+05:30"), "daily_stats": [ { "id": 1, "total": 1, "first_record_time": ISODate("2022-11-06T23:58:43.818+05:30") }, { "id": 2, "total": 1, "first_record_time": ISODate("2022-11-06T23:58:43.818+05:30") } ] }
内容的提问来源于stack exchange,提问作者Marcus
相关产品推荐
相关产品推荐

