MongoDB 4.2 Deployments集合分组统计、条件计数及查询优化咨询
MongoDB 4.2 聚合查询优化解答
问题1:补充不同deploymentStatus的条件计数
在$group阶段新增对应状态的计数字段,通过$cond条件判断实现对应状态的累加:
- 匹配到对应
deploymentStatus时计数+1,不匹配则+0 - 可根据实际需要的状态维度新增对应字段,示例中覆盖
Succeeded、Failed、Cancelled三种状态
问题2:执行时间截断保留2位小数
MongoDB 4.2支持两种精度处理方法,可根据需求选择:
- 若需要截断(直接舍去第三位及之后小数):使用
$trunc运算符,将原有执行时间计算表达式作为第一个参数,第二个参数传2指定保留2位小数 - 若需要四舍五入保留2位小数:使用
$round运算符,参数规则和$trunc一致
问题3:查询优化方案
- 建立覆盖索引:创建联合索引
{startedAt: 1, productId: 1, deploymentStatus: 1, completedAt: 1},该索引覆盖了$match过滤、$group分组、计算所需的所有字段,无需回表查询原始文档,可大幅提升查询效率 - 过滤前置:当前查询已经把
$match放在聚合第一阶段,可提前过滤掉不符合日期范围的文档,减少后续阶段的处理数据量 - 预聚合优化:如果该统计是高频查询,可提前按天/小时维度预计算统计结果存入单独的聚合集合,查询时直接读取预聚合结果,避免每次全量扫描符合条件的原始文档
- 大数据量适配:如果单次查询的符合条件文档超过100MB,可开启
allowDiskUse: true参数允许聚合阶段使用磁盘缓存,避免内存溢出报错
完整修改后聚合查询代码
db.getCollection('Deployments').aggregate([ { $match : { "startedAt": { $gte: new ISODate("2021-10-01"), $lte: new ISODate("2021-11-17") } } }, { $group : { _id: "$productId", count: { $sum: 1 }, // 不同状态计数 succeededCount: { $sum: { $cond: [ { $eq: [ "$deploymentStatus", "Succeeded" ] }, 1, 0 ] } }, failedCount: { $sum: { $cond: [ { $eq: [ "$deploymentStatus", "Failed" ] }, 1, 0 ] } }, cancelledCount: { $sum: { $cond: [ { $eq: [ "$deploymentStatus", "Cancelled" ] }, 1, 0 ] } }, minExecutionTime: { $min: { // 这里使用$trunc是截断保留2位,换成$round就是四舍五入 $trunc: [ { $divide: [ { $subtract: ["$completedAt", "$startedAt"] }, 1000 * 60 ] }, 2 ] } }, maxExecutionTime: { $max: { $trunc: [ { $divide: [ { $subtract: ["$completedAt", "$startedAt"] }, 1000 * 60 ] }, 2 ] } }, avgExecutionTime: { $avg: { $trunc: [ { $divide: [ { $subtract: ["$completedAt", "$startedAt"] }, 1000 * 60 ] }, 2 ] } } } } // 大数据量场景可开启下方参数 // ], { allowDiskUse: true }) ])
内容的提问来源于stack exchange,提问作者Bhanu
相关产品推荐
相关产品推荐

