You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 12:52:48