MongoDB聚合:同集合相邻文档GFL值比较及差值求和实现
MongoDB聚合:计算相邻文档GFL差值累加总和
集合结构与需求
集合Generators的文档结构示例:
_id: 64b7561db1fac11016dccfdb TS: "1689736733498" SID: "A005" GEN: [ { GID: 1, GVT: 1, GTS: 1689735100493938200, GFL: 0.65 } ] __v: 0
需求:针对同一SID、指定TS时间戳范围内的文档,按TS降序排列后,依次比较相邻文档(最新的doc1与doc2,doc2与doc3……),若后一个文档的GFL小于前一个,计算两者差值并累加所有符合条件的差值总和。
已完成的聚合阶段
- $sort阶段:
{ SID: 1, TS: -1 }
- $match阶段:
{ SID: "A005", TS: { $gte: "1689742109823", $lte: "1689744959849" } }
注:建议将
$match放在$sort之前,先过滤数据再排序能提升查询效率
- $group阶段:
{ _id: "$SID", data: { $push: "$$ROOT" } }
将符合条件的文档存入data数组
4. $unwind阶段:
{ path: "$data", includeArrayIndex: "index", preserveNullAndEmptyArrays: true }
展开数组并添加索引字段index
后续聚合阶段实现
1. 获取前一个文档的GFL值(使用$setWindowFields)
通过窗口函数$lag获取当前文档的前一个邻接文档的GFL值,以_id(即SID)为分区键,按index升序排列(对应TS降序的顺序):
{ $setWindowFields: { partitionBy: "$_id", sortBy: { index: 1 }, output: { prevGFL: { $lag: "$data.GEN.0.GFL", offset: 1 } } } }
这里假设每个
GEN数组只有一个元素,若有多个元素需根据需求调整(比如取第一个/指定GID的元素)
2. 计算有效差值并标记
筛选出prevGFL存在(即不是第一个文档)且当前文档GFL小于前一个的情况,计算差值:
{ $addFields: { validDiff: { $cond: [ { $and: [ { $ne: ["$prevGFL", null] }, { $lt: ["$data.GEN.0.GFL", "$prevGFL"] } ] }, { $subtract: ["$prevGFL", "$data.GEN.0.GFL"] }, 0 ] } } }
3. 累加所有有效差值
按SID分组,累加所有validDiff得到总和:
{ $group: { _id: "$_id", totalFuelConsumption: { $sum: "$validDiff" } } }
4. (可选)美化输出字段
如果需要将SID从_id中取出:
{ $project: { _id: 0, SID: "$_id", totalFuelConsumption: 1 } }
内容的提问来源于stack exchange,提问作者Ke_Sandaru
相关产品推荐
相关产品推荐

