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

Mongo聚合:合并连续时间区间文档生成非连续块方案

MongoDB合并连续时间块的聚合解决方案

针对你需要合并连续/重叠时间块的需求,可以通过以下聚合管道实现,适配百万级数据量的处理场景:

完整聚合管道代码

db.collection.aggregate([
  // 1. 按start时间升序排序(必须步骤,保证时间顺序正确)
  { $sort: { start: 1 } },
  
  // 2. 用窗口函数标记连续时间块的分组ID
  {
    $setWindowFields: {
      partitionBy: null, // 全局所有文档统一处理
      sortBy: { start: 1 },
      output: {
        prevEnd: { $lag: "$end" }, // 获取前一个文档的end时间
        groupId: {
          $sum: {
            $cond: [
              // 当前文档是第一个,或start晚于前一个文档的end → 标记为新分组
              { $or: [{ $eq: ["$prevEnd", null] }, { $gt: ["$start", "$prevEnd"] }] },
              1,
              0
            ]
          }
        }
      }
    }
  },
  
  // 3. 按分组ID聚合,合并连续时间块
  {
    $group: {
      _id: "$groupId",
      start: { $min: "$start" },
      end: { $max: "$end" }
    }
  },
  
  // 4. 整理输出格式,移除无关字段
  {
    $project: {
      _id: 0,
      start: 1,
      end: 1
    }
  },
  
  // 可选:按start重新排序结果
  { $sort: { start: 1 } }
])

核心逻辑说明

  • $sort阶段:必须先对start字段排序,确保后续窗口函数能正确关联前后文档。建议给start创建单字段索引:db.collection.createIndex({ start: 1 }),大幅提升百万级数据的排序速度。
  • $setWindowFields阶段:通过$lag获取前序文档的结束时间,用条件判断生成分组ID——连续/重叠的时间块会被分配相同的groupId。
  • $group阶段:按groupId聚合,取分组内最早的start和最晚的end,完成时间块合并。

性能优化提示

  • 若数据量超过千万级,可先按时间范围拆分查询(比如按天/周分片),再合并各分片的结果,进一步降低单管道的处理压力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:03:28