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

如何计算平均时长差值?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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:37:39