MongoDB聚合查询问题:如何获取文档中最近20年的电影?
修正MongoDB获取最近20年电影的聚合查询
你的聚合查询存在两个核心问题:
$group阶段会把所有电影文档合并成单个文档(仅包含maxYear),后续阶段无法再访问原始的电影数据进行筛选。$match阶段默认只能引用集合的原始字段,无法直接使用前面$project生成的minYear字段。
方法一:分步查询(高效推荐)
先获取数据库中电影的最大年份,再用这个值计算最小年份,最后直接筛选符合条件的文档:
// 获取最大年份 var maxYear = db.movies.find().sort({year: -1}).limit(1).toArray()[0].year; // 计算最近20年的起始年份 var minYear = maxYear - 20; // 查询符合条件的电影 db.movies.find({year: {$gte: minYear}});
方法二:单聚合管道完成
如果需要用聚合一步实现,可以通过$group保存所有原始文档,再计算年份阈值后筛选:
db.movies.aggregate([ // 聚合所有文档,记录最大年份并保存原始电影数据 { $group: { _id: null, maxYear: {$max: "$year"}, allMovies: {$push: "$$ROOT"} } }, // 添加最近20年的起始年份字段 { $addFields: { minYear: {$subtract: ["$maxYear", 20]} } }, // 展开电影数组,回到单个文档处理 { $unwind: "$allMovies" }, // 使用$expr引用聚合阶段生成的字段,筛选符合年份条件的电影 { $match: { $expr: {$gte: ["$allMovies.year", "$minYear"]} } }, // 可选:将电影数据恢复为根文档结构 { $replaceRoot: {newRoot: "$allMovies"} } ])
两种方法对比
- 方法一性能更优:避免了聚合中对所有文档的内存存储,适合大数据量场景。
- 方法二无需分步执行:适合需要在单一管道中完成逻辑的场景,但数据量较大时
$push会占用较多内存。
内容的提问来源于stack exchange,提问作者Guido Biante
相关产品推荐
相关产品推荐

