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

MongoDB中按指定时间计算近5分钟数据的温湿度平均值

MongoDB 每日指定时间点温湿度平均值计算方案

针对你需要获取每日6:00、12:00、22:00三个时间点前5分钟内数据的温湿度平均值需求,可以通过MongoDB聚合管道实现,具体查询语句及解释如下:

聚合查询代码

db.sensor_data.aggregate([
  // 可选:限定查询时间范围,减少数据处理量,按需调整
  {
    $match: {
      "acquisition-time": {
        $gte: ISODate("2022-05-01T00:00:00.000Z"),
        $lte: ISODate("2022-05-15T23:59:59.000Z")
      }
    }
  },
  // 提取日期并生成三个目标时间的基础窗口信息
  {
    $addFields: {
      date: { $dateToString: { format: "%Y-%m-%d", date: "$acquisition-time" } },
      target_windows: [
        {
          target_time: "06:00",
          start_time: { $dateFromParts: { year: { $year: "$acquisition-time" }, month: { $month: "$acquisition-time" }, day: { $dayOfMonth: "$acquisition-time" }, hour: 6, minute: 0, second: 0 } },
          end_time: { $dateFromParts: { year: { $year: "$acquisition-time" }, month: { $month: "$acquisition-time" }, day: { $dayOfMonth: "$acquisition-time" }, hour: 6, minute: 0, second: 0 } }
        },
        {
          target_time: "12:00",
          start_time: { $dateFromParts: { year: { $year: "$acquisition-time" }, month: { $month: "$acquisition-time" }, day: { $dayOfMonth: "$acquisition-time" }, hour: 12, minute: 0, second: 0 } },
          end_time: { $dateFromParts: { year: { $year: "$acquisition-time" }, month: { $month: "$acquisition-time" }, day: { $dayOfMonth: "$acquisition-time" }, hour: 12, minute: 0, second: 0 } }
        },
        {
          target_time: "22:00",
          start_time: { $dateFromParts: { year: { $year: "$acquisition-time" }, month: { $month: "$acquisition-time" }, day: { $dayOfMonth: "$acquisition-time" }, hour: 22, minute: 0, second: 0 } },
          end_time: { $dateFromParts: { year: { $year: "$acquisition-time" }, month: { $month: "$acquisition-time" }, day: { $dayOfMonth: "$acquisition-time" }, hour: 22, minute: 0, second: 0 } }
        }
      ]
    }
  },
  // 将每个目标窗口的起始时间调整为目标时间前5分钟
  {
    $addFields: {
      target_windows: {
        $map: {
          input: "$target_windows",
          as: "window",
          in: {
            target_time: "$$window.target_time",
            start_time: { $subtract: ["$$window.start_time", 5 * 60 * 1000] },
            end_time: "$$window.end_time"
          }
        }
      }
    }
  },
  // 展开目标窗口数组,让每个文档对应一个窗口判断
  { $unwind: "$target_windows" },
  // 筛选出采集时间落在当前窗口内的文档
  {
    $match: {
      $expr: {
        $and: [
          { $gte: ["$acquisition-time", "$target_windows.start_time"] },
          { $lte: ["$acquisition-time", "$target_windows.end_time"] }
        ]
      }
    }
  },
  // 按日期和目标时间分组计算平均值
  {
    $group: {
      _id: { date: "$date", target_time: "$target_windows.target_time" },
      avg_temperature: { $avg: "$temperature" },
      avg_humidity: { $avg: "$humidity" },
      data_count: { $sum: 1 } // 统计参与计算的数据条数,可选
    }
  },
  // 整理输出格式,保留两位小数
  {
    $project: {
      _id: 0,
      date: "$_id.date",
      target_time: "$_id.target_time",
      avg_temperature: { $round: ["$avg_temperature", 2] },
      avg_humidity: { $round: ["$avg_humidity", 2] },
      data_count: 1
    }
  },
  // 按日期和目标时间排序结果
  {
    $sort: { date: 1, target_time: 1 }
  }
])

关键阶段解释

  1. $match(可选):先缩小查询的时间范围,避免处理全量数据,提升效率。
  2. $addFields(生成基础字段):提取文档的日期字符串,同时生成三个目标时间点的基础时间对象。
  3. $addFields(调整窗口):通过$subtract将每个目标时间的窗口起始点向前推5分钟(转换为毫秒计算)。
  4. $unwind:将包含三个目标窗口的数组展开,让每个文档对应一个窗口的判断条件。
  5. $match:过滤出采集时间落在当前窗口内的有效数据,确保只有符合规则的数据进入计算。
  6. $group:按日期和目标时间分组,计算温湿度的平均值,同时统计数据条数用于验证数据覆盖情况。
  7. $project:优化输出格式,隐藏默认的_id字段,并将平均值保留两位小数,让结果更易读。
  8. $sort:对结果按日期和目标时间升序排列,方便查看时序数据。

性能优化建议

  • 为acquisition-time字段创建单字段索引,大幅提升时间范围查询的效率:
    db.sensor_data.createIndex({ "acquisition-time": 1 })
    

注意事项

  • 若某一天的某个目标时间窗口内没有数据,该分组不会出现在结果中。如果需要强制显示所有日期的所有目标时间(包括无数据的情况),可以预先生成包含所有日期和目标时间的集合,再通过$lookup关联查询结果。

内容的提问来源于stack exchange,提问作者Abdullah Al Mamun

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 15:48:18