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

MongoDB聚合查询:动态统计最大年份前20年的电影数量

问题描述

MongoDB中存储了多部电影文档,包含title(电影标题)和year(上映年份)字段,示例文档如下:

{"_id" : ObjectId("63a994974ac549c5ea982d2b"),"title" : "Destroyer","year" : 2018},
{"_id" : ObjectId("63a994974ac549c5ea982d2a"),"title" : "Aquaman","year" : 2014},
{"_id" : ObjectId("63a994974ac549c5ea982d29"),"title" : "On the Basis of Sex","year" : 1998},
{"_id" : ObjectId("63a994974ac549c5ea982d28"),"title" : "Holmes and Watson","year" : 1940},
{"_id" : ObjectId("63a994974ac549c5ea982d27"),"title" : "Conundrum: Secrets Among Friends","year" : 1957},
{"_id" : ObjectId("63a994974ac549c5ea982d26"),"title" : "Welcome to Marwen","year" : 2000},
{"_id" : ObjectId("63a994974ac549c5ea982d25"),"title" : "Mary Poppins Returns","year" : 1997},
{"_id" : ObjectId("63a994974ac549c5ea982d24"),"title" : "Bumblebee","year" : 2018}

需求是统计上映年份处于文档中最大年份及其前20年区间内的电影数量,示例中最大年份为2018,区间为1998-2018,期望结果为4部。

尝试代码

var query1 = {"$addFields": {maxium: {$max: "$year"}, minimum : {$subtract: [{$max: "$year"}, 20]}}}
var filter = {"year": {"$lte": maximum, "$gte": minimum}}
var logic = {$match: {$and: [filter]}}
var query1 = {$group: {"_id": null, "count": {$sum:1}}}
var stage = [logic, query1]
db.movies.aggregate(stage)

错误信息

{"message" : "maximum is not defined", "stack" : "script:3:32"}
错误原因
  1. 变量未定义:代码中maximum和minimum是未声明的变量,聚合阶段按顺序执行,无法在前面阶段直接引用后续阶段才会生成的字段值。
  2. 聚合管道逻辑缺失:定义的$addFields阶段未加入到聚合管道stage中,等于完全没执行最大年份计算,直接匹配自然报错。
  3. $max使用错误:$addFields中直接用$max: "$year"只会取当前文档的年份值,而非整个集合的全局最大年份,需通过$group先计算全局最大值。
正确实现方案

方式一:单聚合管道完成

通过聚合管道分步计算全局最大年份、筛选区间内文档、统计数量:

db.movies.aggregate([
  // 计算全局最大年份,并保留所有文档数据
  {
    $group: {
      _id: null,
      maxYear: { $max: "$year" },
      movies: { $push: "$$ROOT" }
    }
  },
  // 计算区间最小值,筛选符合条件的电影
  {
    $project: {
      eligibleMovies: {
        $filter: {
          input: "$movies",
          cond: {
            $and: [
              { $gte: ["$$this.year", { $subtract: ["$maxYear", 20] }] },
              { $lte: ["$$this.year", "$maxYear"] }
            ]
          }
        }
      }
    }
  },
  // 统计符合条件的电影数量
  {
    $project: {
      count: { $size: "$eligibleMovies" },
      _id: 0
    }
  }
])

方式二:分步查询(更直观)

先获取全局最大年份,再基于年份区间统计数量:

// 获取集合中的最大年份
var maxYear = db.movies.find().sort({year: -1}).limit(1)[0].year;
// 计算区间最小年份
var minYear = maxYear - 20;
// 统计区间内的电影数量
db.movies.countDocuments({
  year: {
    $gte: minYear,
    $lte: maxYear
  }
})

内容的提问来源于stack exchange,提问作者DatBigD

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 18:50:24