mongodb查询每天X点的最后一条数据

1. 问题描述?

mongodb表结构如下
device_var_code:设备
ymd:年月日时间
time:毫秒级时间戳
value:值

mongodb查询每天X点的最后一条数据

2. 您期望得到的结果?

想要查询出每个设备每天在X点之前的最后一条数据数据

例如查询出每个设备每天在12点之前的最后一条数据数据

device_var_code ymd value 解释
设备1 20230428 88 设备1在20230428这天12点之前的最后一条数据
设备1 20230427 77 设备1在20230427这天12点之前的最后一条数据
设备2 20230428 66 设备2在20230428这天12点之前的最后一条数据
设备2 20230427 55 设备2在20230427这天12点之前的最后一条数据

现在是全部查出来循环进行判断,但是数据量太多了,有没有什么更好的方案或者查询语句

《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 2

ChatGPT的回答

db.collection.aggregate([
  // 将时间字段按照日期和小时分组
  { $group: {
    _id: {
      date: { $dateToString: { format: "%Y-%m-%d", date: "$timeField" } },
      hour: { $hour: "$timeField" }
    },
    lastData: { $last: "$$ROOT" } // 保存每个分组的最后一条记录
  }},
  // 过滤出每天12点的最后一条数据
  { $match: { "_id.hour": 12 }},
  { $replaceRoot: { newRoot: "$lastData" }} // 将结果重新设置为文档
]);

在上述代码中,db.collection代表您的集合名称,timeField代表包含时间信息的字段。该聚合管道将时间字段按照日期和小时分组,然后使用$last操作符获取每个分组的最后一条记录。接下来,我们使用$match操作符过滤出每天12点的最后一条数据,最后使用$replaceRoot操作符将结果重新设置为文档。

请注意,此查询假定您的时间字段是日期对象,而不是字符串。如果您的时间字段是字符串,请将$dateToString操作符的date参数设置为$dateFromString操作符,并将$hour操作符应用于返回的日期对象。

1年前 评论

我想到的是 先根据device_var_code与ymd去查询,然后在根据 time去查找对应数据?
select * from table where time in (select max(time) as time from table group by device_var_code, ymd)
这样应该是可以的 但是不知道从性能的角度考虑如何。
如果表数据十分大的话,更推荐每天凌晨去跑一下昨天的数据存在另一张表里,避免每次都是整表查询。

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!