如何优化MongoDB聚合查询实现按物料和日期分组求和
MongoDB TransactionIB集合聚合查询优化方案
核心优化思路
直接通过$group阶段同时按**Material(物料)和Transaction_Date(交易日期)**分组,对Jumlah字段求和,消除同一日期下的重复数据。如果日期字段包含时分秒,需先统一截断到日期维度,避免同一天不同时间被拆分。
优化后的聚合管道示例
db.TransactionIB.aggregate([ // 第一步:保留原有过滤逻辑,减少后续计算量 { $match: { // 替换为你的实际过滤条件,比如: // Material: { $exists: true }, // Transaction_Date: { $gte: ISODate("2024-01-01"), $lte: ISODate("2024-05-31") } } }, // 核心分组求和:若Transaction_Date含时分秒,直接用$dateTrunc截断为纯日期 { $group: { _id: { Material: "$Material", Transaction_Date: { $dateTrunc: { date: "$Transaction_Date", unit: "day" } } }, Total_Jumlah: { $sum: "$Jumlah" } } }, // 可选:格式化输出,让结果更直观 { $project: { _id: 0, Material: "$_id.Material", Transaction_Date: "$_id.Transaction_Date", Total_Jumlah: 1 } } ])
各阶段说明
- $match阶段:优先过滤不需要的数据,降低后续分组操作的计算负载,保持原有业务过滤逻辑即可。
- $group阶段:
_id同时指定Material和处理后的日期(用$dateTrunc截断时分秒),确保同一物料同一天的记录被归为一组。$sum: "$Jumlah"实现组内数量求和,得到该物料当日的总数量。
- $project阶段:将
_id中的字段拆分出来,移除冗余的_id字段,输出更符合需求的结构。
示例效果
假设原数据为:
[ { Material: "A001", Transaction_Date: ISODate("2024-05-20T10:00:00Z"), Jumlah: 10 }, { Material: "A001", Transaction_Date: ISODate("2024-05-20T15:00:00Z"), Jumlah: 20 }, { Material: "A001", Transaction_Date: ISODate("2024-05-21T09:00:00Z"), Jumlah: 15 }, { Material: "B002", Transaction_Date: ISODate("2024-05-20T12:00:00Z"), Jumlah: 5 } ]
执行查询后输出结果:
[ { Material: "A001", Transaction_Date: ISODate("2024-05-20T00:00:00Z"), Total_Jumlah: 30 }, { Material: "A001", Transaction_Date: ISODate("2024-05-21T00:00:00Z"), Total_Jumlah: 15 }, { Material: "B002", Transaction_Date: ISODate("2024-05-20T00:00:00Z"), Total_Jumlah: 5 } ]
性能优化建议
为Material和Transaction_Date创建复合索引,提升查询效率:
db.TransactionIB.createIndex({ Material: 1, Transaction_Date: 1 })
内容的提问来源于stack exchange,提问作者Josea Samoa
相关产品推荐
相关产品推荐

