定义
注意
消歧
本页描述了用作累加器时的 $bottomN。累加器返回一群组输入文档的聚合值。
您还可以使用 $bottomN (window function),它根据指定的排序顺序返回特定窗口中文档的底部 n 元素。
语法
{ $bottomN: { n: <expression>, output: <expression>, sortBy: { <field1>: <sort order>, <field2>: <sort order> ... } } }
选项
字段 | 必要性 | 说明 |
|---|---|---|
| 必需 |
|
| 必需 | 确定群组中每个元素的输出。可以是任何表达式。 |
| 必需 | 定义每个群组内元素的排名顺序,语法类似于 |
行为
Null 和缺失值
$bottomN不筛选空值。$bottomN将缺失值转换为 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", playerId: { $bottomN: { output: [ "$playerId", "$score" ], sortBy: { "score": -1 }, n: 3 } } } } ] )
在本例中:
$documents创建包含玩家分数的字面文档。$group按gameId对文档进行分组。此示例只有一个gameId、G1。PlayerD分数缺失,且PlayerE的score为空。这些值都被视为空值。playerId和score字段指定为output : ["$playerId"," $score"],并以数组值形式返回。由于
sortBy: { "score" : -1 },空值被排序到返回的playerId数组的末尾。
[ { _id: "G1", playerId: [ [ "PlayerA", 1 ], [ "PlayerD", null ], [ "PlayerE", null ] ] } ]
BSON 数据类型排序
对不同类型进行排序时,将使用BSON 数据类型的顺序来确定顺序。 例如,考虑一个其值由字符串和数字组成的collection。
在升序排序中,字符串值排在数值之后。
在降序排序中,字符串值排在数值之前。
db.aggregate( [ { $documents: [ { playerId: "PlayerA", gameId: "G1", score: 1 }, { playerId: "PlayerB", gameId: "G1", score: "2" }, { playerId: "PlayerC", gameId: "G1", score: "" } ] }, { $group: { _id: "$gameId", playerId: { $bottomN: { output: ["$playerId","$score"], sortBy: {"score": -1}, n: 3 } } } } ] )
在本例中:
PlayerA有一个整数分数。PlayerB有一个字符串"2"分数。PlayerC有一个空字符串分数。
由于按降序{ "score" : -1 }排序,因此字符串字面值会排序在PlayerA的数值之前:
[ { _id: "G1", playerId: [ [ "PlayerB", "2" ], [ "PlayerC", "" ], [ "PlayerA", 1 ] ] } ]
示例
本页上的示例使用 sample_mflix 数据集中的数据。有关如何将此数据集加载到自管理MongoDB 部署中的详细信息,请参阅加载样本数据集。如果对示例数据库进行了任何修改,则可能需要删除并重新创建数据库才能运行本页上的示例。
查找单一类型中评分最低的三部电影
您可以使用 $bottomN累加器查找 Short 类型中评分最低的三部电影。
db.movies.aggregate( [ { $match: { genres: "Short", "imdb.rating": { $exists: true } } }, { $group: { _id: "Short", lowestRatedMovies: { $bottomN: { output: [ "$title", "$imdb.rating" ], sortBy: { "imdb.rating": -1, title: 1 }, n: 3 } } } } ] )
示例管道:
查找每种类型评分最低的电影
您可以使用 $bottomN累加器查找每种类型评分最低的电影。
db.movies.aggregate( [ { $unwind: "$genres" }, { $match: { "imdb.rating": { $exists: true } } }, { $group: { _id: "$genres", lowestRatedMovie: { $bottomN: { output: [ "$title", "$imdb.rating" ], sortBy: { "imdb.rating": -1, title: 1 }, n: 3 } } } }, { $sort: { _id: 1 } }, { $limit: 5 } ] )
示例管道:
根据群组密钥动态设置 n
您可以动态分配 n 的值。以下示例使用 $cond表达式根据内容分级返回不同数量的电影。
db.movies.aggregate([ { $match: { rated: { $in: [ "G", "PG", "PG-13", "R" ] }, "imdb.rating": { $exists: true } } }, { $group: { _id: { rated: "$rated" }, movies: { $bottomN: { output: { title: "$title", rating: "$imdb.rating" }, n: { $cond: { if: { $eq: [ "$rated", "PG" ] }, then: 3, else: 1 } }, sortBy: { "imdb.rating": -1 } } } } }, { $sort: { "_id.rated": 1 } } ] )
示例管道: