• MongoDB聚合运算符:$bottom


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

    语法

    {
       $bottom:
          {
             sortBy: { <field1>: <sort order>, <field2>: <sort order> ... },
             output: <expression>
          }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    字段说明:

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

    用法

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

    关于null和缺失值的处理

    • $bottom不会过滤掉空值,也就是空值也参与排序
    • $bottom会将缺失值转换为null,也就是缺失值会当做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:
                {
                   $bottom:
                      {
                         output: [ "$playerId", "$score" ],
                         sortBy: { "score": -1 }
                      }
                }
          }
       }
    ] )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这个例子中:

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

    举例

    使用下面的命令,创建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 }
    ])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    查找单个游戏的最后一名

    使用$bottom查找单场比赛的最后一名:

    db.gamescores.aggregate( [
       {
          $match : { gameId : "G1" }
       },
       {
          $group:
             {
                _id: "$gameId",
                playerId:
                   {
                      $bottom:
                      {
                         output: [ "$playerId", "$score" ],
                         sortBy: { "score": -1 }
                      }
                   }
             }
       }
    ] )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在本例的管道中:

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

    操作返回下面的结果:

    [ { _id: 'G1', playerId: [ 'PlayerD', 1 ] } ]
    
    • 1

    查所有游戏的最后一名

    使用$bottom查找所有游戏的最后一名:

    db.gamescores.aggregate( [
          {
             $group:
             { _id: "$gameId", playerId:
                {
                   $bottom:
                      {
                         output: [ "$playerId", "$score" ],
                         sortBy: { "score": -1 }
                      }
                }
             }
          }
    ] )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在本例的管道中:

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

    操作返回下面的结果:

    [
       { _id: 'G2', playerId: [ 'PlayerA', 10 ] },
       { _id: 'G1', playerId: [ 'PlayerD', 1 ] }
    ]
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    糖尿病患者应避免这三种食物。
    【云原生之kubernetes实战】Kompose工具的安装使用
    YOLOV7训练自己的yolo数据集
    【React】第六部分 生命周期
    Docker快速入门到项目部署,docker自定义镜像
    Grafana系列-统一展示-9-Jaeger数据源
    Redis的安装以及主从复制&高可用数据库的详解
    Machine Learning(study notes)
    < Python全景系列-4 > 史上最全文件类型读写库大盘点!什么?还包括音频、视频?
    带电机扰动的车辆垂向七自由度主动悬架控制
  • 原文地址:https://blog.csdn.net/superatom01/article/details/136289773