MongoDB按日期范围统计并按item_id分组排名的问题
解决方案
要实现先按item_id分组聚合统计,再进行排名的需求,你需要调整聚合管道的顺序,先完成分组计算,再执行窗口函数排名。以下是修改后的查询:
user_stats_2022_12.aggregate([ // 过滤目标数据 {"$match": {"company_id": 5, "created_date": {"$gte": "2022-12-04", "$lte": "2022-12-06"}}}, // 按item_id分组,聚合各统计字段的总和 {"$group": { "_id": "$item_id", "company_id": {"$first": "$company_id"}, "total_door_knocks": {"$sum": "$door_knocks"}, "total_lead_count": {"$sum": "$lead_count"}, "total_appointment_count": {"$sum": "$appointment_count"}, "total_customer_count": {"$sum": "$customer_count"}, "total_video_viewed": {"$sum": "$video_viewed"} }}, // 按公司分区,按总door_knocks降序计算排名 {"$setWindowFields": { "partitionBy": "$company_id", "sortBy": {"total_door_knocks": -1}, "output": { "item_rank": {"$denseRank": {}} } }}, // 分页和元数据处理 {"$facet": { "metadata": [{"$count": "total"}], "data": [{"$sort": {"item_rank": 1}}, {"$skip": 0}, {"$limit": 100}] }} ])
关键调整说明:
- $group阶段:新增该阶段按
item_id分组,对每个用户的每日统计字段做求和聚合(比如total_door_knocks是该用户所有日期的door_knocks总和),同时用$first保留company_id(同一item_id属于同一公司)。 - $setWindowFields阶段:排序字段改为聚合后的
total_door_knocks,确保排名基于用户的总数据,而非单条每日记录。 - $facet阶段:将
$sort移至$skip和$limit之前,保证分页结果是按排名顺序排列的正确数据。
修改后,同一个item_id只会得到一个排名,排名依据是该用户在指定日期范围内的总统计数据。
内容的提问来源于stack exchange,提问作者Jitender Thakur
相关产品推荐
相关产品推荐

