如何计算平均时长差值?MongoDB聚合结果顺序异常求助
我来帮你搞定MongoDB聚合遇到的这两个问题——结果排序异常和avgduration差值计算:
1. 解决聚合结果顺序异常问题
MongoDB的聚合管道默认不保证输出结果的顺序,除非你在管道的最后(或者需要排序的阶段)显式添加$sort操作。如果你的结果顺序乱了,大概率是没加这个阶段。
举个例子,如果你想按CREATE_DATE升序、再按STATUS排序,只需要在聚合管道末尾加上:
{ $sort: { CREATE_DATE: 1, STATUS: 1 } // 1表示升序,-1表示降序 }
如果你的聚合过程中有$group阶段,记得把$sort放在$group之后,这样才会对分组后的结果生效。比如完整的管道可能是:
db.yourCollection.aggregate([ // 你的其他聚合阶段(比如$match、$group等) { $match: { SWITCHID: "Z4-W40-SS451A/5" } }, // ... 其他阶段 { $sort: { SWITCHID: 1, STATUS: 1 } } ])
2. 计算avgduration的差值
从你给出的示例数据看,同一个SWITCHID对应LIGHTS ON和LIGHTS OFF两个文档,要计算这两个状态下avgduration的差值,可以通过两种方式实现,对应不同场景:
场景1:每个SWITCHID每个状态只有一条文档
这种情况可以直接在分组时用$cond提取对应状态的avgduration,再计算差值:
db.yourCollection.aggregate([ // 可选:先过滤目标SWITCHID { $match: { SWITCHID: "Z4-W40-SS451A/5" } }, // 按SWITCHID分组,提取ON和OFF的avgduration { $group: { _id: "$SWITCHID", onAvgDuration: { $first: { $cond: [{ $eq: ["$STATUS", "LIGHTS ON"] }, "$avgduration", null] } }, offAvgDuration: { $first: { $cond: [{ $eq: ["$STATUS", "LIGHTS OFF"] }, "$avgduration", null] } } } }, // 计算差值(这里用OFF的avgduration减去ON的,可根据需求调整顺序) { $addFields: { avgDurationDiff: { $subtract: ["$offAvgDuration", "$onAvgDuration"] } } } ])
执行后,你会得到类似这样的结果:
{ "_id": "Z4-W40-SS451A/5", "onAvgDuration": 202.50562416666668, "offAvgDuration": 269.5074988888889, "avgDurationDiff": 67.00187472222222 }
场景2:每个SWITCHID每个状态有多条文档
如果同一个SWITCHID下同一状态有多个文档,需要先计算每个状态的平均avgduration,再求差值:
db.yourCollection.aggregate([ // 第一步:按SWITCHID+STATUS分组,计算每个状态的平均avgduration { $group: { _id: { SWITCHID: "$SWITCHID", STATUS: "$STATUS" }, avgDuration: { $avg: "$avgduration" } } }, // 第二步:按SWITCHID分组,把每个状态的平均结果收集起来 { $group: { _id: "$_id.SWITCHID", durationByStatus: { $push: { status: "$_id.STATUS", avgDuration: "$avgDuration" } } } }, // 第三步:提取ON和OFF的平均值,计算差值 { $addFields: { onAvg: { $arrayElemAt: ["$durationByStatus.avgDuration", { $indexOfArray: ["$durationByStatus.status", "LIGHTS ON"] }] }, offAvg: { $arrayElemAt: ["$durationByStatus.avgDuration", { $indexOfArray: ["$durationByStatus.status", "LIGHTS OFF"] }] }, avgDurationDiff: { $subtract: [ { $arrayElemAt: ["$durationByStatus.avgDuration", { $indexOfArray: ["$durationByStatus.status", "LIGHTS OFF"] }] }, { $arrayElemAt: ["$durationByStatus.avgDuration", { $indexOfArray: ["$durationByStatus.status", "LIGHTS ON"] }] } ] } } } ])
内容的提问来源于stack exchange,提问作者Naresh G
相关产品推荐
相关产品推荐

