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

如何从MongoDB集合中将每分钟数据转换为每小时粒度数据?

调整MongoDB聚合查询为每小时粒度的实现方案

首先纠正原查询中的一个错误:timestampISO的范围条件写反了,$lt应指向更大的时间戳,$gte指向更小的时间戳,否则会查询不到数据。

要将每分钟粒度的结果转为每小时粒度,核心是通过时间分组+聚合统计实现,具体修改后的聚合管道如下:

mongo_client.db("db")
  .collection(collection)
  .aggregate([
    // 1. 转换时间戳为长整型,并计算每小时起始时间戳
    {
      $addFields: {
        timestampISO: { $toLong: "$periodicMessageBase.messageTimestamp" },
        // 将毫秒级时间戳截断到每小时起始点(1小时=3600000毫秒)
        hourlyTimestamp: {
          $multiply: [
            { $floor: { $divide: ["$timestampISO", 3600000] } },
            3600000
          ]
        }
      },
    },
    // 2. 过滤目标设备和时间范围(已修正条件顺序)
    {
      $match: {
        deviceId: deviceId,
        periodicMessageBase: { $exists: true },
        timestampISO: {
          $gte: "1694008207000", // 起始时间戳(小值)
          $lt: "1695002207000"   // 结束时间戳(大值)
        },
      },
    },
    // 3. 提取需要的字段
    {
      $project: {
        _id: 0,
        DeviceID: "$deviceId",
        HourlyTimestamp: "$hourlyTimestamp",
        L1_VoltageAngleMean: {
          $ifNull: [
            { $arrayElemAt: ["$periodicMessageBase.vAngle.meanVal", 0] },
            0
          ],
        }
      },
    },
    // 4. 按设备+每小时时间戳分组,聚合统计
    {
      $group: {
        _id: {
          DeviceID: "$DeviceID",
          HourlyTimestamp: "$HourlyTimestamp"
        },
        // 计算该小时内L1_VoltageAngleMean的平均值,可根据需求替换为$max/$min/$first/$last等
        L1_VoltageAngleMean: { $avg: "$L1_VoltageAngleMean" },
        // 可选:统计该小时内的原始数据条数
        dataCount: { $sum: 1 }
      }
    },
    // 5. 整理输出字段格式
    {
      $project: {
        _id: 0,
        DeviceID: "$_id.DeviceID",
        Timestamp: "$_id.HourlyTimestamp",
        L1_VoltageAngleMean: 1,
        dataCount: 1 // 不需要可删除
      }
    },
    // 6. 按时间降序排序
    {
      $sort: { Timestamp: -1 }
    }
  ])

关键改动说明:

  • 每小时时间戳计算:通过$divide将毫秒时间戳除以3600000(1小时的毫秒数),再用$floor取整后乘以3600000,得到当前时间所在小时的起始时间戳(如1694008800000对应某小时的0分0秒)。
  • 分组聚合:使用$group按设备ID和每小时时间戳分组,通过$avg计算该小时内电压角度均值的平均值。如果不需要平均值,可替换为其他聚合操作符:
    • $max:取该小时内的最大值
    • $min:取该小时内的最小值
    • $first:取该小时内最早的一条数据值
    • $last:取该小时内最晚的一条数据值
  • 修正时间范围:原查询中$lt和$gte的数值顺序错误,已调整为正确的时间范围逻辑。

内容的提问来源于stack exchange,提问作者vignesh ramesh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 13:10:07