如何用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
相关产品推荐
相关产品推荐

