MongoDB聚合查询按月/年汇总total_teus异常,求排查
MongoDB聚合查询按月汇总total_teus异常问题排查
问题背景
bookings集合中文档结构如下:
{ "_id": "asdkbasdkjcbhsajcbh", "created_at": 1662712231, "total_teus": 4, ... }
需要编写聚合查询按月/年汇总total_teus的总和,但执行后仅得到1970-01的结果,无法得到多月份数据。
原查询语句:
db.bookings.aggregate([{ "$match": { "created_at": { "$gte": 1648771200 }, "company_id": { "$nin": ["ln_exports1582702220", "marico_limited1588656327", "star_fisheries_pvt_ltd1576862831", "td_infotech1569314187", "Xportify1561638979", "msuyash1572972166", "demo_account1587548110", "production_testing1586152669", "abc_tech_pvt._ltd.1571657756"] } } }, { "$addFields": { "created_date_long": { "$toLong": "$created_at" } } }, { "$addFields": { "created_date": { "$toDate": "$created_date_long" } } }, { "$group": { "_id": { "$dateToString": { "date": "$created_date", "format": "%Y-%m" } }, "teus_exported": { "$sum": "$total_teus" } } }])
执行结果仅返回:
{ "_id": "1970-01", "teus_exported": 234 }
期望得到多月份汇总列表:
[{ "_id": "1970-01", "teus_exported": 234 }, { "_id": "1970-02", "teus_exported": 654 }, { "_id": "1970-03", "teus_exported": 623 }]
问题原因
核心问题是时间戳单位不匹配:
- 文档中的
created_at是秒级时间戳(如1662712231对应2022年9月) - MongoDB的
$toDate函数默认接受毫秒级时间戳,直接转换秒级时间戳会得到1970年1月的初始日期,导致所有数据被归到同一个月份分组。 - 额外的
$toLong转换完全多余,因为created_at本身就是数值类型,转成Long不解决单位问题。
修正后的查询
直接将秒级时间戳乘以1000转换为毫秒级,再转成日期,同时合并冗余的$addFields步骤:
db.bookings.aggregate([ { "$match": { "created_at": { "$gte": 1648771200 }, "company_id": { "$nin": ["ln_exports1582702220", "marico_limited1588656327", "star_fisheries_pvt_ltd1576862831", "td_infotech1569314187", "Xportify1561638979", "msuyash1572972166", "demo_account1587548110", "production_testing1586152669", "abc_tech_pvt._ltd.1571657756"] } } }, { "$addFields": { "created_date": { "$toDate": { "$multiply": ["$created_at", 1000] } } } }, { "$group": { "_id": { "$dateToString": { "date": "$created_date", "format": "%Y-%m" } }, "teus_exported": { "$sum": "$total_teus" } } }, // 可选:按月份排序,让结果更直观 { "$sort": { "_id": 1 } } ])
补充说明
如果需要按年汇总,只需修改$dateToString的格式为"%Y"即可:
"_id": { "$dateToString": { "date": "$created_date", "format": "%Y" } }
内容的提问来源于stack exchange,提问作者Anuj Panchal
相关产品推荐
相关产品推荐

