文档菜单
文档首页
/
MongoDB 手册
/ / /

$maxN(聚合累加器)

在本页中

  • 定义
  • 语法
  • 行为
  • 限制
  • 示例
$maxN

版本中5.2.

返回组内前n个最大值的聚合。如果组内元素少于n个,$maxN将返回组内的所有元素。

{
$maxN:
{
input: <expression>,
n: <expression>
}
}
  • input指定一个表达式,作为$maxN的输入。它对组内的每个元素进行评估,并保留最大的n个值。

  • n限制每个组的结果数量,n必须是正整数表达式,可以是常量或依赖于$group的_id值。$group.

$maxN根据BSON比较顺序比较输入数据,以确定适当的输出类型。当输入数据包含多种数据类型时,$maxN的输出类型是比较顺序中的最高

  • Null和缺失值

$maxN会过滤掉null和缺失值。

db.aggregate( [
{
$documents: [
{ playerId: "PlayerA", gameId: "G1", score: 1 },
{ playerId: "PlayerB", gameId: "G1", score: 2 },
{ playerId: "PlayerC", gameId: "G1", score: 3 },
{ playerId: "PlayerD", gameId: "G1" },
{ playerId: "PlayerE", gameId: "G1", score: null }
]
},
{
$group:
{
_id: "$gameId",
maximumThreeScores:
{
$maxN:
{
input: "$score",
n: 4
}
}
}
}
] )

考虑以下聚合,该聚合从分组中返回最大n个文档

  • 在这个例子中

  • $documents创建包含玩家得分的文档。

  • $groupgameId对文档进行分组。这个例子只有一个gameId,即G1

  • PlayerD的得分为缺失值,PlayerE的得分为null。这两个值都被视为null。maximumThreeScores字段指定为

  • $maxN,输入为: "$score",并以数组形式返回。

[
{
_id: 'G1',
maximumThreeScores: [ 3, 2, 1 ]
}
]

两者 $maxN$topN 累加器可以完成类似的结果。

一般来说

  • $maxN 优点在于可以在没有任何排序顺序的情况下找到最大值。如果您想了解 n 个文档的最大值,请使用 $maxN

  • 如果需要保证特定的排序顺序,请使用 $topN

  • 如果您不打算按输出值进行排序,请使用 $topN

您可以使用 $maxN 作为累加器。

$maxN 支持作为 聚合表达式

$maxN 支持作为 窗口操作符

调用 $maxN 的聚合管道受到 100 MB 限制。如果单个组的此限制被超过,聚合将失败并显示错误。

考虑一个包含以下文档的 gamescores 集合

db.gamescores.insertMany([
{ playerId: "PlayerA", gameId: "G1", score: 31 },
{ playerId: "PlayerB", gameId: "G1", score: 33 },
{ playerId: "PlayerC", gameId: "G1", score: 99 },
{ playerId: "PlayerD", gameId: "G1", score: 1 },
{ playerId: "PlayerA", gameId: "G2", score: 10 },
{ playerId: "PlayerB", gameId: "G2", score: 14 },
{ playerId: "PlayerC", gameId: "G2", score: 66 },
{ playerId: "PlayerD", gameId: "G2", score: 80 }
])

您可以使用$maxN累加器来找到单个游戏中的最高三个分数。

db.gamescores.aggregate( [
{
$match : { gameId : "G1" }
},
{
$group:
{
_id: "$gameId",
maxThreeScores:
{
$maxN:
{
input: ["$score","$playerId"],
n:3
}
}
}
}
] )

示例管道

  • 使用$match来按单个gameId过滤结果。在这种情况下,G1

  • 使用$groupgameId对结果进行分组。在这种情况下,G1

  • 使用input : ["$score","$playerId"]指定输入给$maxN的字段。

  • 使用$maxN返回G1游戏的最高三个分数元素,其中n : 3

该操作返回以下结果

[
{
_id: 'G1',
maxThreeScores: [ [ 99, 'PlayerC' ], [ 33, 'PlayerB' ], [ 31, 'PlayerA' ] ]
}
]

您可以使用$maxN累加器来找到每个游戏中的最高n个分数。

db.gamescores.aggregate( [
{
$group:
{
_id: "$gameId",
maxScores:
{
$maxN:
{
input: ["$score","$playerId"],
n: 3
}
}
}
}
] )

示例管道

  • 使用$groupgameId对结果进行分组。

  • 使用$maxN返回每个游戏的最高三个分数元素,其中n: 3

  • 使用input: ["$score","$playerId"]指定输入给$maxN的字段。

该操作返回以下结果

[
{
_id: 'G1',
maxScores: [ [ 99, 'PlayerC' ], [ 33, 'PlayerB' ], [ 31, 'PlayerA' ] ]
},
{
_id: 'G2',
maxScores: [ [ 80, 'PlayerD' ], [ 66, 'PlayerC' ], [ 14, 'PlayerB' ] ]
}
]

您还可以动态分配 n 的值。在这个例子中,使用了 $cond 表达式在 gameId 字段上。

db.gamescores.aggregate([
{
$group:
{
_id: {"gameId": "$gameId"},
gamescores:
{
$maxN:
{
input: ["$score","$playerId"],
n: { $cond: { if: {$eq: ["$gameId","G2"] }, then: 1, else: 3 } }
}
}
}
}
] )

示例管道

  • 使用$groupgameId对结果进行分组。

  • 使用 input : ["$score","$playerId"] 指定 $maxN 的输入字段。

  • 如果 gameIdG2,则 n 为 1,否则 n 为 3。

该操作返回以下结果

[
{ _id: { gameId: 'G2' }, gamescores: [ [ 80, 'PlayerD' ] ] },
{
_id: { gameId: 'G1' },
gamescores: [ [ 99, 'PlayerC' ], [ 33, 'PlayerB' ], [ 31, 'PlayerA' ] ]
}
]

返回

最大值