MongoDB如何单查询获取集合中时间戳最大的所有最新记录
MongoDB 查询所有时间戳为最大值的文档实现方案
适用场景
针对demo集合中存储的设备时序数据,通过单条查询语句实现:筛选指定设备下,所有timestamp字段等于匹配范围内最大值的全量文档,返回结构和普通find查询完全一致。
可用实现
通用兼容写法(支持MongoDB 3.4+全版本)
通过聚合管道分步完成过滤、排序、最大值计算、结果匹配,无版本依赖,语句如下:
db.getCollection('demo').aggregate([ // 前置过滤指定设备数据,缩小后续计算范围 { $match: { "deviceSerial": "S121F1194200003" } }, // 按时间戳倒序排序,最大值排在最前 { $sort: { "timestamp": -1 } }, // 分组取最大时间戳,同时留存所有匹配前置条件的原始文档 { $group: { _id: null, latestTs: { $first: "$timestamp" }, allDocs: { $push: "$$ROOT" } } }, // 过滤出时间戳等于最大值的文档 { $project: { res: { $filter: { input: "$allDocs", cond: { $eq: ["$$this.timestamp", "$latestTs"] } } } } }, // 拆分结果数组为独立文档 { $unwind: "$res" }, // 替换根节点,直接返回原始文档结构 { $replaceRoot: { newRoot: "$res" } } ])
高性能写法(支持MongoDB 5.0及以上版本)
5.0版本新增窗口函数,无需缓存全量文档到数组,大数量级下执行效率更高,语句如下:
db.getCollection('demo').aggregate([ { $match: { "deviceSerial": "S121F1194200003" } }, // 窗口函数计算匹配范围内的最大时间戳 { $setWindowFields: { sortBy: { "timestamp": -1 }, output: { maxTs: { $max: "$timestamp", window: { documents: ["unbounded", "unbounded"] } } } } }, // 仅保留时间戳等于最大值的文档 { $match: { $expr: { $eq: ["$timestamp", "$maxTs"] } } }, // 删除临时添加的maxTs字段,返回原始结构 { $unset: "maxTs" } ])
扩展说明
- 如果需要查询全集合下每个设备各自最新时间戳的记录,只需要把通用写法中
$group阶段的_id: null改为_id: "$deviceSerial"即可,无需其他调整。 - 如果
timestamp字段上建有索引,前置$sort阶段会自动命中索引,查询性能和普通find排序基本一致。
内容的提问来源于stack exchange,提问作者quintin
相关产品推荐
相关产品推荐

