定义
$maxN 累加器可在以下阶段使用:
注意
$maxN 的其他用途
本页介绍了 $maxN 用作 累加器 时的情况。累加器对一组输入文档返回聚合值,如总和、最大值或最小值。
您还可以在这些其他上下文中使用 $maxN:
$maxN (expression),返回数组中最大的n个值。$maxN (window function),用于在$setWindowFields阶段中返回某个窗口中文档的最大n值。
语法
{ $maxN: { input: <expression>, n: <expression> } }
字段 | 类型 | 说明 |
|---|---|---|
| 表达式(expression) | 对组中的每个元素求值的表达式。 |
| 表达式(expression) | The number of elements that |
行为
结果类型
$maxN 比较不同类型的值时,类型的顺序遵循 BSON 比较顺序。
Null 和缺失值
$maxN 过滤掉空值和缺失值。
以下聚合演示了 $maxN 如何处理空值和缺失值:
db.aggregate( [ { $documents: [ { title: "Fight Club", genre: "Drama", rating: 8.9 }, { title: "The Matrix", genre: "Drama", rating: 8.7 }, { title: "The Green Mile", genre: "Drama", rating: 8.5 }, { title: "Magnolia", genre: "Drama" }, { title: "Dogma", genre: "Drama", rating: null } ] }, { $group: { _id: "$genre", topFourRatings: { $maxN: { input: "$rating", n: 4 } } } } ] )
[ { _id: 'Drama', topFourRatings: [ 8.9, 8.7, 8.5 ] } ]
在本例中:
$documents创建包含电影评分的字面文档。$group按genre对文档进行分组。此示例只有一个genre、Drama。Magnoliarating缺失,且Dogma的rating为空。两个值都被过滤器过滤掉。由于只有 3 个文档具有有效评级,
$maxN返回 3 个值,即使n = 4。
$maxN 和 $topN 累加器的比较
您可以使用 $maxN 或 $topN 从组中返回排名最高的 n 元素。它们之间的选择取决于您的输入文档是否已经排序。
如果输入文档已经排序,使用
$maxN返回最大n个值。如果您需要同时排序并选择前
n个元素,则可以使用$topN通过单个累加器完成这两项任务。
示例
本页上的示例使用来自 sample_mflix 数据集的数据。有关如何将此数据集加载到您的自管理 MongoDB 部署中的详细信息,请参阅 加载示例数据集。如果您对示例数据库进行了任何修改,您可能需要删除并重新创建数据库,才能运行此页面上的示例。
查询单一年份评分最高的三部电影
可以使用 $maxN 累加器查找对于在单个年份发布的电影的 IMDb 评分最高的前三个。
db.movies.aggregate( [ { $match: { year: 1999, "imdb.rating": { $exists: true } } }, { $group: { _id: 1999, topThreeRatings: { $maxN: { input: "$imdb.rating", n: 3 } } } } ] )
前面的管道:
使用
$match过滤器1999年发行的具有imdb.rating字段的电影。将所有匹配的文档分组为单一组,使用
_id: 1999。将
"$imdb.rating"指定为input,用于$maxN。使用
$maxN返回具有n: 3的三个最高评级。
查找多年间评分最高的三部电影
可以使用 $maxN 累加器查找给定年份范围内每年评分最高的三部电影。
db.movies.aggregate( [ { $match: { year: { $in: [ 1999, 2000, 2001 ] }, "imdb.rating": { $exists: true } } }, { $group: { _id: "$year", topThreeRatings: { $maxN: { input: "$imdb.rating", n: 3 } } } }, { $sort: { _id: 1 } } ] )
前面的管道:
根据群组密钥设置 n
您可以根据组密钥动态地赋值 n 的值。在此示例中,$cond 表达式使用 year 字段更改 n 的值:
db.movies.aggregate( [ { $match: { year: { $in: [ 1999, 2000, 2001 ] }, "imdb.rating": { $exists: true } } }, { $group: { _id: { year: "$year" }, topRatedMovies: { $maxN: { input: "$imdb.rating", n: { $cond: { if: { $eq: [ "$year", 2001 ] }, then: 3, else: 1 } } } } } }, { $sort: { "_id.year": 1 } } ] )
前面的管道:
在
1999、2000或2001发行的具有imdb.rating字段的电影过滤器。按
year分组电影。使用
$cond表达式返回3年2001的评级和所有其他年份的1评级。
在输出中,2001 返回三个评级,而 1999 和 2000 则各自返回一个评级。