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

Mongoose查询需求:获取近24小时内每小时一条气象传感器数据

嘿,这个需求用MongoDB的聚合框架就能完美解决!单纯的find查询没法直接实现按小时分组并只保留单条记录的逻辑,咱们用聚合管道来一步步实现:

核心思路

通过聚合的几个阶段组合,先筛选出近24小时的数据,再按小时分组,每组只保留一条记录(比如该小时的第一条或最后一条数据),最后按时间排序方便绘图。

具体实现代码

const last24HoursData = await Measurements.aggregate([
  // 1. 筛选近24小时的所有测量数据
  {
    $match: {
      createdAt: { $gt: new Date(Date.now() - 24 * 60 * 60 * 1000) }
    }
  },
  // 2. 按小时分组,每组取该小时的最后一条记录(也可以换成$first取第一条)
  {
    $group: {
      _id: {
        // 把时间截断到小时级别,MongoDB 5.0+支持$dateTrunc
        $dateTrunc: {
          date: "$createdAt",
          unit: "hour"
        }
      },
      temperature: { $last: "$temperature" },
      humidity: { $last: "$humidity" },
      // 保留该条记录的具体创建时间
      recordTime: { $last: "$createdAt" }
    }
  },
  // 3. 按小时顺序排序,让结果从最早到最晚排列
  {
    $sort: { "_id": 1 }
  },
  // 4. 可选:重命名字段让结果更易读
  {
    $project: {
      _id: 0,
      hourStart: "$_id", // 该小时的起始时间(比如2024-05-20 18:00:00)
      temperature: 1,
      humidity: 1,
      recordTime: 1
    }
  }
]);

针对旧版本MongoDB的兼容方案

如果你的MongoDB版本低于5.0(不支持$dateTrunc),可以用$dateToString来生成小时级别的字符串作为分组键:

// 在$group的_id里替换成这个
_id: {
  $dateToString: {
    format: "%Y-%m-%d %H:00:00",
    date: "$createdAt"
  }
}

小提示

  • 如果你想取每小时的第一条数据,只需要把所有的$last换成$first就行。
  • 因为你的传感器每5分钟发一次数据,每个小时都会有12条记录,所以每个分组都会有数据返回,不会出现空小时的情况(如果需要处理空小时的场景,还需要额外的逻辑,但你的需求里应该不用)。

内容的提问来源于stack exchange,提问作者Aleksander Sadaj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:31:52