MongoDB按月按当日7点至次日7点分组数据的查询求助
MongoDB自定义周期(7:00-次日7:00)按月分组统计方案
核心思路
把自定义的24小时周期(当日7点到次日7点)转换为标准自然日:将每条数据的时间字段减去7小时,这样原周期内的时间会被映射到同一个自然日(比如2024-03-01 07:00 ~ 2024-03-02 07:00 减去7小时后,就变成2024-02-29 00:00 ~ 2024-03-01 00:00,对应自然日2024-02-29)。之后就可以基于转换后的日期进行分组,再筛选指定月份的数据。
具体查询语句
适用于MongoDB 5.0+(支持$dateAdd)
假设集合名为your_collection,时间字段为timestamp,统计目标为每个周期的数据条数,指定月份为2024年3月:
db.your_collection.aggregate([ // 步骤1:偏移时间,将自定义周期转为自然日 { $addFields: { adjustedDate: { $dateTrunc: { date: { $dateAdd: { startDate: "$timestamp", unit: "hour", amount: -7 } }, unit: "day" } } } }, // 步骤2:筛选指定月份的数据(这里是2024年3月) { $match: { adjustedDate: { $gte: ISODate("2024-03-01T00:00:00Z"), $lt: ISODate("2024-04-01T00:00:00Z") } } }, // 步骤3:按调整后的日期(即自定义周期)分组统计 { $group: { _id: "$adjustedDate", count: { $sum: 1 }, // 可添加其他统计字段,比如总和:totalAmount: { $sum: "$amount" } } }, // 步骤4:按周期顺序排序 { $sort: { _id: 1 } } ])
适用于MongoDB 4.4及以下版本(用$subtract替代$dateAdd)
db.your_collection.aggregate([ { $addFields: { adjustedDate: { $dateTrunc: { date: { $subtract: ["$timestamp", 7 * 60 * 60 * 1000] }, // 减去7小时的毫秒数 unit: "day" } } } }, { $match: { adjustedDate: { $gte: ISODate("2024-03-01T00:00:00Z"), $lt: ISODate("2024-04-01T00:00:00Z") } } }, { $group: { _id: "$adjustedDate", count: { $sum: 1 } } }, { $sort: { _id: 1 } } ])
关键细节解释
- 时间偏移逻辑:减去7小时后,原
当日7:00会变成前一日0:00,原次日7:00会变成当日0:00,所以整个自定义周期的时间会被统一映射到前一日的自然日,方便分组。 $dateTrunc作用:将偏移后的时间截断到天,确保同一周期内的所有数据都被分到同一个日期组。- 指定月份筛选:通过
adjustedDate的范围筛选,确保只统计目标月份内的自定义周期数据(注意:如果自定义周期跨月,比如2024-03-31 07:00 ~ 2024-04-01 07:00,会被映射到2024-03-31,属于3月的统计范围)。 - 自定义统计字段:在
$group阶段可以根据需求添加其他聚合操作,比如$sum统计金额总和、$avg计算平均值等。
扩展:按月汇总所有周期数据
如果需要将指定月份内的所有自定义周期数据汇总成一个整体统计值,只需调整$group的_id为月份:
db.your_collection.aggregate([ { $addFields: { adjustedDate: { $dateTrunc: { date: { $dateAdd: { startDate: "$timestamp", unit: "hour", amount: -7 } }, unit: "day" } } } }, { $match: { adjustedDate: { $gte: ISODate("2024-03-01T00:00:00Z"), $lt: ISODate("2024-04-01T00:00:00Z") } } }, { $group: { _id: { $dateTrunc: { date: "$adjustedDate", unit: "month" } }, totalCount: { $sum: 1 }, // 其他统计字段 } } ])
内容的提问来源于stack exchange,提问作者sheethal patil
相关产品推荐
相关产品推荐

