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

如何用MongoDB Aggregate计算pType B与A的createdAt差值之和

MongoDB聚合计算:B类型元素与最近前置A类型元素的时间差求和

聚合管道实现方案

以下是满足需求的完整聚合操作,核心通过窗口函数定位每个B类型元素对应的最近前置A类型元素,再计算时间差并求和:

db.collection.aggregate([
  // 按时间戳升序排序,确保文档时间顺序正确
  { $sort: { createdAt: 1 } },
  // 用窗口函数获取当前文档之前最近的A类型元素的createdAt
  {
    $setWindowFields: {
      sortBy: { createdAt: 1 },
      output: {
        prevAcreatedAt: {
          $last: {
            $cond: [{ $eq: ["$pType", "A"] }, "$createdAt", null]
          },
          window: { documents: ["unbounded", "current"] }
        }
      }
    }
  },
  // 筛选出有对应前置A的B类型文档
  {
    $match: {
      pType: "B",
      prevAcreatedAt: { $ne: null }
    }
  },
  // 计算当前B与最近前置A的时间差
  {
    $addFields: {
      diff: { $subtract: ["$createdAt", "$prevAcreatedAt"] }
    }
  },
  // 对所有时间差求和
  {
    $group: {
      _id: null,
      sum_of_diff: { $sum: "$diff" }
    }
  },
  // 格式化结果,仅保留目标字段
  {
    $project: {
      _id: 0,
      sum_of_diff: { $toString: "$sum_of_diff" }
    }
  }
])

关键阶段说明

  • $sort:必须按createdAt升序排序,否则无法正确定位“最近的前一个A类型元素”。
  • $setWindowFields:通过window: ["unbounded", "current"]定义窗口范围为从集合起始到当前文档,用$last结合$cond筛选出窗口内最后一个(即最近的)A类型元素的时间戳,存入prevAcreatedAt字段。
  • $match:过滤出仅pType为B的文档,同时排除无对应前置A的B元素,避免无效计算。
  • $addFields:用$subtract计算时间差值,得到每个B元素与对应A元素的时间差。
  • $group:以_id: null为分组键,对所有diff字段求和,得到最终的sum_of_diff。
  • $project:将求和结果转为字符串(匹配预期格式),并移除默认的_id字段。

示例验证

  • 针对ex1数据集,执行后将得到{ "sum_of_diff": "8859" }
  • 针对ex2数据集,执行后将得到{ "sum_of_diff": "5859" }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 17:31:57