MongoDB聚合查询实现:筛选每个key对应最大version的文档
按key维度取最高version完整文档的MongoDB聚合实现
针对当前集合的结构特点:每条文档带key、version、date、status四个核心字段,同一个key可以挂载多条历史版本文档,全集合范围内所有文档的version、date、status取值唯一,我们可以通过固定的聚合管道逻辑,精准筛出每个key对应、version最大的完整文档。
最终跑出来的结果和预期完全对齐:
- key为1时,匹配到version=2、date为Feb/10、status为DRAFT的文档
- key为2时,匹配到version=1、date为March/10、status为ACTIVE的文档
- key为3时,匹配到version=3、date为Jun/10、status为DRAFT的文档
聚合管道分步拆解
整套逻辑没有多余的计算开销,一共分三个核心阶段:
- 预排序阶段
对全量文档按key升序、version降序做全局排序,让同一个key分组内,version值最高的文档排在最靠前的位置,从源头减少后续的匹配计算量。对应管道配置:{ $sort: { key: 1, version: -1 } } - 分组聚合阶段
以key值作为分组的主键,用$first算子直接读取当前分组下排序后排在第一位的完整文档(也就是该组内version最高的文档),同时用$max算子算出组内的最高version值,做结果校验避免取数偏差。对应管道配置:{ $group: { _id: "$key", latestDoc: { $first: "$$ROOT" }, maxVersion: { $max: "$version" } } } - 文档结构还原阶段
经过上一步分组后,我们要的完整文档是内嵌在latestDoc字段下的,这里用$replaceRoot算子把这个内嵌文档提升为聚合输出的根节点,去掉分组生成的冗余字段(比如分组用的_id、用来校验的maxVersion),最终输出的文档结构和原始集合的文档结构完全一致。对应管道配置:{ $replaceRoot: { newRoot: "$latestDoc" } }
方案优势
- 比起「分组时先算出组内maxVersion,再遍历组内所有文档数组匹配对应记录」的写法,先排序再取首条的实现不需要遍历全量历史文档,在文档量较大的生产场景下执行性能更好
- 逻辑鲁棒性更强,就算后续出现同key下version重复的极端场景,也能稳定输出结果,不会因为数组匹配的逻辑偏差出现结果异常
内容的提问来源于stack exchange,提问作者Boat
相关产品推荐
相关产品推荐

