MongoDB按年/月/日分组求和查询问题(PyMongo实现)
MongoDB按年/月/日分组并对value字段求和的正确实现
原代码里有几个明显的问题,导致无法满足需求:
- 字段名不匹配:数据库日期字段是
date,但代码里用了dt,过滤和分组都找不到正确数据 - 求和逻辑错了:年/月分组时用
$sum:1是统计文档数量,不是对value求和,应该用$sum:"$value" - 分组标识格式不对:直接用
$year/$month只能拿到数字,出不来示例里的完整日期格式(比如2022-11-01T00:00:00) - 日分组逻辑有漏洞:只按
dayOfMonth分组会把不同年月的同一天归为一组,结果完全错误
修正后的PyMongo代码
from datetime import datetime # 假设dt_from和dt_upto是传入的日期范围字符串(如"2022-01-01") filter_cond = { "$match": { "date": { "$gte": datetime.fromisoformat(dt_from), "$lte": datetime.fromisoformat(dt_upto) } } } group_cond = {} if group_type == 'year': # 按年分组,生成当年1月1日0点的日期作为分组标识 group_cond = { "$group": { "_id": { "$dateFromParts": { "year": {"$year": "$date"}, "month": 1, "day": 1 } }, "total_value": {"$sum": "$value"} } } elif group_type == 'month': # 按月分组,生成当月1日0点的日期作为分组标识 group_cond = { "$group": { "_id": { "$dateFromParts": { "year": {"$year": "$date"}, "month": {"$month": "$date"}, "day": 1 } }, "total_value": {"$sum": "$value"} } } elif group_type == 'day': # 按日分组,生成当天0点的日期作为分组标识 group_cond = { "$group": { "_id": { "$dateFromParts": { "year": {"$year": "$date"}, "month": {"$month": "$date"}, "day": {"$dayOfMonth": "$date"} } }, "total_value": {"$sum": "$value"} } } sort_cond = {"$sort": {"_id": 1}} # 执行聚合查询 pipeline = coll.aggregate([filter_cond, group_cond, sort_cond]) # 转换成示例要求的输出格式 for result in pipeline: print(f"{group_type}: {result['_id'].isoformat()}") print(f"total: {result['total_value']}") print("---")
修正要点说明
- 字段名统一:把所有
dt替换成数据库实际的日期字段date,确保能正确匹配数据 - 求和逻辑修正:所有分组场景都用
$sum:"$value",实现对value字段的求和 - 生成标准日期:用
$dateFromParts聚合运算符,根据年/月/日数值构造完整日期对象,输出格式完全符合示例要求 - 完整分组维度:日分组时同时包含年、月信息,避免不同年月的同一天被错误合并
- 结果格式化:遍历聚合结果,直接输出示例指定的格式
内容的提问来源于stack exchange,提问作者Alan Dzheliev
相关产品推荐
相关产品推荐

