MongoDB如何查询最近两次解析周期赛事且重复赛事仅保留最新版
实现方案
核心逻辑
你需要通过MongoDB聚合管道实现需求,整体分四个步骤:
- 定位最近两次解析周期的
parseCount值 - 过滤出属于这两个周期的所有赛事文档
- 按赛事唯一标识(示例中用
command1+command2判断为同一赛事,可根据实际业务替换为赛事ID等字段)分组,每组保留parseCount更大的最新版本 - 还原文档结构返回结果
通用实现方案(兼容所有MongoDB版本,不受parseCount是否连续限制)
db.collection.aggregate([ // 提取所有去重的解析周期编号,倒序取最近2个 { $group: { _id: null, allParseCounts: { $addToSet: "$parseCount" } } }, { $project: { recentTwoCounts: { $slice: [ { $sortArray: { input: "$allParseCounts", sortBy: -1 } }, 2 ] }, _id: 0 } }, // 关联原集合,筛选出这两个周期的所有文档 { $lookup: { from: "collection", // 替换为你的实际集合名 let: { recentTwo: "$recentTwoCounts" }, pipeline: [ { $match: { $expr: { $in: [ "$parseCount", "$$recentTwo" ] } } } ], as: "matchedDocs" } }, { $unwind: "$matchedDocs" }, { $replaceRoot: { newRoot: "$matchedDocs" } }, // 按赛事唯一标识分组,保留最新周期的版本 { $group: { _id: { command1: "$command1", command2: "$command2" // 业务有专属赛事唯一字段可替换此处,比如 matchId: "$matchId" }, latestDoc: { $top: { sortBy: { parseCount: -1 }, output: "$$ROOT" } } } }, // 输出最终文档 { $replaceRoot: { newRoot: "$latestDoc" } } ])
注:如果你的MongoDB版本低于5.2不支持
$top操作符,可将分组阶段替换为:{ $group: { _id: { command1: "$command1", command2: "$command2" }, maxParseCount: { $max: "$parseCount" }, docs: { $push: "$$ROOT" } } }, { $unwind: "$docs" }, { $match: { $expr: { $eq: [ "$docs.parseCount", "$maxParseCount" ] } } }, { $replaceRoot: { newRoot: "$docs" } }
高性能简化方案(适合parseCount连续递增的场景)
如果你的解析周期parseCount是严格每次加1、不会跳号的,可以用这个性能更高的方案,提前过滤数据避免全表扫描:
// 先查询最新的解析周期编号 const latestCount = db.collection.findOne({}, { sort: { parseCount: -1 }, projection: { parseCount: 1 } }).parseCount; // 直接聚合最近两个周期的数据 db.collection.aggregate([ { $match: { parseCount: { $in: [latestCount, latestCount - 1] } } }, { $group: { _id: { command1: "$command1", command2: "$command2" }, latestDoc: { $top: { sortBy: { parseCount: -1 }, output: "$$ROOT" } } } }, { $replaceRoot: { newRoot: "$latestDoc" } } ])
以上方案运行在你提供的示例数据上,会返回预期的3条结果:parseCount=2的A+B赛事、parseCount=1的C+D赛事、parseCount=2的E+F赛事。
内容的提问来源于stack exchange,提问作者Dmytro
相关产品推荐
相关产品推荐

