如何编写Mongo查询获取日期范围内指定字段的每日分组计数?
解决MongoDB按天统计指定日期范围水果食用次数的问题
我来帮你补全并优化这个聚合查询,完全满足你按天统计每种水果食用次数的需求~
完整的聚合查询代码
db.getCollection('fruits').aggregate([ // 第一步:筛选指定日期范围的数据 { "$match": { "dates": { "$gte": new Date(2018, 02, 19, 00, 00, 00), "$lt": new Date(2018, 02, 22, 00, 00, 00) // 注意:这里用22号才能包含3月21日全天的数据 } } }, // 第二步:按日期+水果分组,统计次数 { "$group": { "_id": { year: { $year: "$dates" }, month: { $month: "$dates" }, day: { $dayOfMonth: "$dates" }, fruit: "$fruit" }, "eat_count": { "$sum": 1 } // 统计每组的记录数,也就是食用次数 } }, // 可选:按日期和水果排序,让结果更清晰 { "$sort": { "_id.year": 1, "_id.month": 1, "_id.day": 1, "_id.fruit": 1 } }, // 可选:重新整理结果结构,让输出更友好(把_id里的字段提出来) { "$project": { "_id": 0, "year": "$_id.year", "month": "$_id.month", "day": "$_id.day", "fruit": "$_id.fruit", "eat_count": 1 } } ])
关键细节解释
- $match阶段的日期范围:MongoDB的
Date构造函数中月份是从0开始索引的(0=1月,2=3月),这点你已经用对了。另外要注意:如果需要包含3月21日全天的数据,必须用$lt new Date(2018, 02, 22),否则原来的$lt new Date(2018, 02, 21)只会统计到3月20日23:59:59的数据,会漏掉3月21日的所有记录。 - $group阶段的分组依据:把
year、month、day和fruit一起作为_id,就能实现“按天+按水果”的分组统计,$sum:1会自动统计每组内的记录数量,也就是该水果当天的食用次数。 - $sort和$project阶段:这两个是可选的,
$sort让结果按时间和水果名称有序排列,$project则把嵌套在_id里的字段提取到顶层,让输出结构更直观易读。
举个输出结果的例子,会是这样的:
{ "year" : 2018, "month" : 3, "day" : 19, "fruit" : "apple", "eat_count" : 5 } { "year" : 2018, "month" : 3, "day" : 19, "fruit" : "banana", "eat_count" : 3 } { "year" : 2018, "month" : 3, "day" : 20, "fruit" : "apple", "eat_count" : 2 }
内容的提问来源于stack exchange,提问作者Milos
相关产品推荐
相关产品推荐

