MongoDB聚合运算符:$top

MongoDB聚合运算符:$top

文章目录

$top聚合运算符返回一个指定顺序分组的第一个元素。

语法

js 复制代码
{
   $top:
      {
         sortBy: { <field1>: <sort order>, <field2>: <sort order> ... },
         output: <expression>
      }
}

字段说明:

字段 是否必须 描述
sortBy 指定结果排序方式,跟$sort一样
output 指定分组元素输出的内容,可以是任何合法的表达式

用法

  • $top不支持作为聚合表达式。
  • $top只支持作为window 操作符
  • 聚合管道调用$top受100M的限制,如果单组超过这一限制将报错。

关于null和缺失值的处理

  • $top不会过滤掉空值,也就是空值也参与排序
  • $top会将缺失值转换为null,也就是缺失值会当做null排序

下面的聚合返回分组中得分最高的文档:

js 复制代码
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:
            {
               $top:
                  {
                     output: [ "$playerId", "$score" ],
                     sortBy: { "score": -1 }
                  }
            }
      }
   }
] )

在这个例子中:

  • 使用$documents阶段创建了一些字面量(常量)文档,包含了选手的得分
  • $group阶段根据gameId对文档进行了分组,显然文档中的gameId都是G1
  • PlayerD的得分缺失,PlayerE的得分为null,他们的得分都会被当做null处理
  • playerId字段和score字段被指定为输出:["$playerId"," $score"],以数组的形式返回
  • 指定了排序的方式,按照score逆序:sortBy: { "score": -1 }
  • PlayerDPlayerE并列为第一的元素,PlayerD作为第一个score返回
  • 要解决因为多个元素空值导致的问题,就需要添加更多的字段参与到排序
js 复制代码
[
   {
      _id: 'G1',
      playerId: [ [ 'PlayerD', null ] ]
   }
]

举例

使用下面的命令,创建gamescores集合:

js 复制代码
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 }
])

查找单个游戏的第一名

使用$top查找单场比赛的第一名:

js 复制代码
db.gamescores.aggregate( [
   {
      $match : { gameId : "G1" }
   },
   {
      $group:
         {
            _id: "$gameId",
            playerId:
               {
                  $top:
                  {
                     output: [ "$playerId", "$score" ],
                     sortBy: { "score": -1 }
                  }
               }
         }
   }
] )

在本例的管道中:

  • 使用$match阶段用一个gameId对结果进行筛选,即:G1
  • 使用$group阶段依据gameId对结果进行分组,本例中只有一个分组G1
  • 使用output : ["$playerId"," $score"]top指定输出字段
  • 使用sortBy: { "score": -1 }按照得分进行逆序排序
  • 使用$top返回游戏得分最高的元素

操作返回下面的结果:

js 复制代码
[ { _id: 'G1', playerId: [ 'PlayerC', 99 ] } ]

查所有游戏的第一名

使用$top查找所有游戏的第一名:

js 复制代码
db.gamescores.aggregate( [
      {
         $group:
         { _id: "$gameId", playerId:
            {
               $top:
                  {
                     output: [ "$playerId", "$score" ],
                     sortBy: { "score": -1 }
                  }
            }
         }
      }
] )

在本例的管道中:

  • 使用$group按照groupId对结果排序
  • 使用$top返回所有游戏中得分最低的
  • 使用output : ["$playerId", "$score"]指定top输出的字段
  • 使用sortBy: { "score": -1 }按照得分进行逆序排序

操作返回下面的结果:

js 复制代码
[
   { _id: 'G2', playerId: [ 'PlayerD', 80 ] },
   { _id: 'G1', playerId: [ 'PlayerC', 99 ] }
]
相关推荐
2301_803875612 小时前
PHP 中处理会话数组时的类型错误解析与修复指南
jvm·数据库·python
m0_743623922 小时前
c++如何批量修改文件后缀名_std--filesystem--replace_extension【实战】
jvm·数据库·python
三毛的二哥2 小时前
BEV:典型BEV算法总结
人工智能·算法·计算机视觉·3d
2501_914245933 小时前
CSS如何处理CSS变量作用域冲突_利用特定类名重写变量值
jvm·数据库·python
南宫萧幕3 小时前
自控PID+MATLAB仿真+混动P0/P1/P2/P3/P4构型
算法·机器学习·matlab·simulink·控制·pid
故事和你914 小时前
洛谷-数据结构1-4-图的基本应用1
开发语言·数据结构·算法·深度优先·动态规划·图论
maqr_1104 小时前
MySQL数据库迁移到云端如何保障安全_数据加密与SSL连接配置
jvm·数据库·python
我叫黑大帅4 小时前
为什么map查找时间复杂度是O(1)?
后端·算法·面试
u0109147604 小时前
MySQL如何限制触发器递归调用的深度_防止触发器死循环方法
jvm·数据库·python
weixin_381288184 小时前
MySQL中如何使用HEX函数转换十六进制_MySQL进制转换函数
jvm·数据库·python