You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB优化查询:按资产类统计最新运行日期的测试用例结果

MongoDB聚合查询优化:按资产类统计最新运行日期的测试用例结果

需求说明

获取每个asset_class(资产类)对应**最新run_date(运行日期)**的failed(失败)与passed(通过)测试用例总数。

集合示例文档

{"failed": 2,"passed": 4,"asset_class": "A","run_date": ISODate("2024-08-28")},
{"failed": 1,"passed": 3,"asset_class": "A","run_date": ISODate("2024-08-29")},
{"failed": 5,"passed": 1,"asset_class": "A","run_date": ISODate("2024-08-29")},
{"failed": 2,"passed": 4,"asset_class": "B","run_date": ISODate("2024-08-22")},
{"failed": 5,"passed": 8,"asset_class": "B","run_date": ISODate("2024-08-22")},
{"failed": 5,"passed": 1,"asset_class": "B","run_date": ISODate("2024-08-26")}

期望输出

{"failed": 6,"passed": 4,"asset_class": "A","run_date": ISODate("2024-08-29")},
{"failed": 5,"passed": 1,"asset_class": "B","run_date": ISODate("2024-08-26")}

现有查询及问题

已创建复合索引{asset_class:1, run_date:1},现有聚合查询可运行,但存在字段冗余和性能优化空间:

db.getCollection("test").aggregate([
{ $group: {
    _id: {asset_class: "$asset_class", run_date: "$run_date"},
    passed: {$sum: "$passed"},
    failed: {$sum: "$failed"},
    run_date: {
      $push: "$run_date"
    },
    asset_class: {
      $push: "$asset_class"
   }
  }
},
{$sort: {asset_class:1, run_date:1}},
 {$group: {
 _id: "$_id.asset_class",
  "result": {$last: "$$ROOT"}
 }},
{$replaceRoot: {newRoot: "$result"}}
])

更高效的优化写法

方案1:利用索引先排序再分组(性能最优)

直接复用已创建的复合索引,通过排序+分组的组合减少冗余操作:

db.getCollection("test").aggregate([
  // 利用复合索引直接排序,避免内存排序开销
  { $sort: { asset_class: 1, run_date: -1 } },
  // 按资产类分组,直接取最新日期并求和统计
  {
    $group: {
      _id: "$asset_class",
      run_date: { $first: "$run_date" },
      passed: { $sum: "$passed" },
      failed: { $sum: "$failed" },
      asset_class: { $first: "$asset_class" }
    }
  },
  // 调整输出格式,移除默认的_id字段
  {
    $project: {
      _id: 0,
      asset_class: 1,
      run_date: 1,
      passed: 1,
      failed: 1
    }
  }
])

方案2:使用窗口函数(MongoDB 5.0+,可读性更高)

如果使用MongoDB 5.0及以上版本,可通过窗口函数直观筛选最新日期的分组:

db.getCollection("test").aggregate([
  // 按资产类分区,计算每个分区内的最新运行日期
  {
    $setWindowFields: {
      partitionBy: "$asset_class",
      sortBy: { run_date: -1 },
      output: {
        latest_run_date: { $max: "$run_date", window: { documents: ["current", "unbounded"] } }
      }
    }
  },
  // 只保留属于最新运行日期的文档
  { $match: { $expr: { $eq: ["$run_date", "$latest_run_date"] } } },
  // 按资产类+日期分组统计总数
  {
    $group: {
      _id: { asset_class: "$asset_class", run_date: "$run_date" },
      passed: { $sum: "$passed" },
      failed: { $sum: "$failed" }
    }
  },
  // 调整输出格式
  {
    $project: {
      _id: 0,
      asset_class: "$_id.asset_class",
      run_date: "$_id.run_date",
      passed: 1,
      failed: 1
    }
  }
])

性能说明

  • 方案1完全利用已创建的复合索引(可反向使用{asset_class:1, run_date:1}索引实现降序排序),排序阶段无需占用内存,分组逻辑简洁,是性能最优的选择。
  • 方案2适合需要复杂窗口计算的场景,代码可读性更强,但多了一次过滤阶段,性能略逊于方案1。

内容的提问来源于stack exchange,提问作者Sachin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 17:55:16