MongoDB聚合运算符:$topN
MongoDB聚合运算符:$topN
文章目录
- MongoDB聚合运算符:$topN
- 语法
- 用法
- 关于null和缺失值的处理
- BSON数据类型排序
- 举例
- 查找三个得分最高的
- 查找全部游戏中三个最高的得分
- 基于分组key来计算参数n
$topN
聚合运算符返回分组中指定顺序的最前面
n
个元素,如果分组中的元素数量小于
n
,则返回分组的全部元素。从MongoDB5.2开始支持。
语法
{$topN:{n: <expression>,sortBy: { <field1>: <sort order>, <field2>: <sort order> ... },output: <expression>}
}
n
用于限制每组结果的数量,必须是正整数表达式,要么是常数,要么取决于$group
的_id
值sortBy
制定返回结果的顺序,语法类似于$sort
output
指定分组元素输出的内容,可以是任何合法的表达式。
用法
$topN
不支持作为聚合表达式。$topN
只支持作为window 操作符
。- 聚合管道调用
$topN
受100M的限制,如果单组超过这一限制将报错。
关于null和缺失值的处理
$topN
不会过滤掉空值$topN
会将缺失值转换为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:{$topN:{output: [ "$playerId", "$score" ],sortBy: { "score": 1 },n: 3}}}}
] )
在这个例子中:
- 使用
$documents
阶段创建了一些字面量(常量)文档,包含了选手的得分 $group
阶段根据gameId
对文档进行了分组,显然文档中的gameId
都是G1
PlayerD
的得分缺失,PlayerE
的得分为null
,他们的得分都会被当做null
处理playerId
字段和score
字段被指定为输出:["$playerId"," $score"]
,以数组的形式返回sortBy: { "score": 1 }
指定了排序的方式,空值被排在最前面,返回playerId
数组
如下:
[{_id: 'G1',playerId: [ [ 'PlayerD', null ], [ 'PlayerE', null ], [ 'PlayerA', 1 ] ]}
]
BSON数据类型排序
当不同类型排序是,使用BSON数据类型的顺序进行排序:
- 当进行正序排序时(由小到大),字符串的优先级在数值之前
- 当进行逆序排序时(由大到小),字符串的优先级在数值之前
下面的例子中包含了字符串和数值类型:
db.aggregate( [{$documents: [{ playerId: "PlayerA", gameId: "G1", score: 1 },{ playerId: "PlayerB", gameId: "G1", score: "2" },{ playerId: "PlayerC", gameId: "G1", score: "" }]},{$group:{_id: "$gameId",playerId: {$topN:{output: ["$playerId","$score"],sortBy: {"score": -1},n: 3}}}}
] )
在这个例子中:
PlayerA
的得分是整数1
PlayerB
的得分是字符串"2"
PlayerC
的得分是空字符串""
因为排序指定为逆序{ "score" : -1 }
,字符串的字面量排在PlayerA
的数值得分之前:
[{_id: "G1",playerId: [ [ "PlayerB", "2" ], [ "PlayerC", "" ], [ "PlayerA", 1 ] ]}
]
举例
使用下面的命令创建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 }
])
查找三个得分最高的
使用$topN
查找单个游戏中得分最高的3个:
db.gamescores.aggregate( [{$match : { gameId : "G1" }},{$group:{_id: "$gameId",playerId:{$topN:{output: ["$playerId", "$score"],sortBy: { "score": -1 },n:3}}}}
] )
本例中:
- 使用
$match
阶段用一个gameId
对结果进行筛选,即:G1
- 使用
$group
阶段依据gameId
对结果进行分组,本例中只有一个分组G1
- 使用
sortBy: { "score": -1 }
按照得分进行逆序排序 - 使用
output : ["$playerId"," $score"]
为$topN
指定输出字段 - 使用
$topN
返回游戏得分最高的3个选手和得分
结果如下:
[{_id: 'G1',playerId: [ [ 'PlayerC', 99 ], [ 'PlayerB', 33 ], [ 'PlayerA', 31 ] ]}
]
与下面的SQL查询等价:
SELECT T3.GAMEID,T3.PLAYERID,T3.SCORE
FROM GAMESCORES AS GS
JOIN (SELECT TOP 3GAMEID,PLAYERID,SCOREFROM GAMESCORESWHERE GAMEID = 'G1'ORDER BY SCORE DESC) AS T3ON GS.GAMEID = T3.GAMEID
GROUP BY T3.GAMEID,T3.PLAYERID,T3.SCOREORDER BY T3.SCORE DESC
查找全部游戏中三个最高的得分
使用$topN
查找所有游戏中得分最高的三个
db.gamescores.aggregate( [{$group:{ _id: "$gameId", playerId:{$topN:{output: [ "$playerId","$score" ],sortBy: { "score": -1 },n: 3}}}}
] )
在本例中:
- 使用
$group
按照groupId
对结果排序 - 使用
output : ["$playerId", "$score"]
指定bottom
输出的字段 - 使用
sortBy: { "score": -1 }
按照得分进行逆序排序 - 使用
$topN
返回所有游戏中得分最高的三个
结果如下:
[{_id: 'G1',playerId: [ [ 'PlayerC', 99 ], [ 'PlayerB', 33 ], [ 'PlayerA', 31 ] ]},{_id: 'G2',playerId: [ [ 'PlayerD', 80 ], [ 'PlayerC', 66 ], [ 'PlayerB', 14 ] ]}
]
这个操作与下面的SQL语句等价:
SELECT PLAYERID,GAMEID,SCORE
FROM(SELECT ROW_NUMBER() OVER (PARTITION BY GAMEID ORDER BY SCORE DESC) AS GAMERANK,GAMEID,PLAYERID,SCOREFROM GAMESCORES
) AS T
WHERE GAMERANK <= 3
ORDER BY GAMEID
基于分组key来计算参数n
可以动态指定n
的值,在本例中$cond
表达式用在gameId
字段:
db.gamescores.aggregate([{$group:{_id: {"gameId": "$gameId"},gamescores:{$topN:{output: "$score",n: { $cond: { if: {$eq: ["$gameId","G2"] }, then: 1, else: 3 } },sortBy: { "score": -1 }}}}}
] )
在本例中:
- 使用
$group
按照groupId
对结果排序 - 使用
output : "$score"
指定$topN
输出的字段 - 如果
gameId
是G2
则n
为1,否则n
为3 - 使用
sortBy: { "score": -1 }
按照得分进行逆序排序
操作结果如下:
[{ _id: { gameId: 'G1' }, gamescores: [ 99, 33, 31 ] },{ _id: { gameId: 'G2' }, gamescores: [ 80 ] }
]
相关文章:
MongoDB聚合运算符:$topN
MongoDB聚合运算符:$topN 文章目录 MongoDB聚合运算符:$topN语法用法关于null和缺失值的处理BSON数据类型排序 举例查找三个得分最高的查找全部游戏中三个最高的得分基于分组key来计算参数n $topN聚合运算符返回分组中指定顺序的最前面 n个元素…...
什么是顶级域名、二级域名、三级域名?
什么是顶级域名、二级域名、三级域名? 一般域名都由两部分组成,中间用“.”隔开,一个域名是几级域名,简单的可以通过数“.”的方式来判断。 如baidu.com,它是由baidu和后缀“.com”组成,我们可以认定它是顶…...

[Android]四大组件简介
在 Android 开发中,“四大组件”(Four Major Components)是指构成 Android 应用程序的四种核心组件,它们通过各自的方式与系统交互,实现应用的多样功能。这些组件是:Activity、Service、Broadcast Receiver…...

一次完整的GC流程
Java堆中内存区分 Java的堆由新生代(Young Generation)和老年代(Old Generation)组成。新生代存放新分配的对象,老年代存放长期存在的对象。 新生代(Young)由年轻区(Eden&a…...

GAME101-Lecture06学习
前言 上节课主要讲的是三角形的光栅化。重要的思想是要利用像素的中心对三角形可见性的函数进行采样。 这节课主要就是反走样。 课程链接:Lecture 06 Rasterization 2 (Antialiasing and Z-Buffering)_哔哩哔哩_bilibili 反走样引入 通过采样,得到…...
202203青少年软件编程(Python)等级考试试卷(二级)
第 1 题 【单选题】 关于Python中的列表,下列描述错误的是?( ) A :列表是Python中内置可变序列,是若干元素的有序集合; B :列表中的每一个数据称为“元素”; C :在Python中,一个列表中的数据类型可以各不相同; D :可以使用s[1]来获取列表s的第一个元素。 正确答案…...

带有-i选项的sed命令在Linux上执行成功,但在MacOS上失败了
问题: 我已经成功地使用以下 sed 命令在Linux中搜索/替换文本: sed -i s/old_string/new_string/g /path/to/file然而,当我在Mac OS X上尝试时,我得到: command i expects \ followed by text我以为我的Mac运行的是…...

[Linux_IMX6ULL驱动开发]-GPIO子系统和Pinctrl子系统
目录 Pinctrl子系统的概念 GPIO子系统的概念 定义自己的GPIO节点 GPIO子系统的函数 引脚号的确定 基于GPIO子系统的驱动程序 驱动程序 设备树修改 之前我们进行驱动开发的时候,对于硬件的操作是依赖于ioremap对寄存器的物理地址进行映射,以此来达…...

Elasticsearch:理解人工智能相似性搜索
理解相似性搜索(也称为语义搜索)的指南,这是人工智能最新阶段的关键发现之一。 最新阶段人工智能的关键发现之一是根据相似性搜索和查找文档的能力。相似性搜索是一种比较信息的方法,其基于含义而非关键字。 相似性搜索也被称为语…...

Mac YOLO V9推理测试(基于ultralytics)
环境: Mac M1 (MacOS Sonoma 14.3.1) Python 3.11PyTorch 2.1.2 一、准备工作 使用YOLO一般都会接触ultralytics这个框架,今天来试试用该框架进行YOLO V9模型的推理。 YOLOv9目前提供了四种模型下载:yolov9-c.pt、yolov9-e.pt、gelan-c.p…...
OuterClass.this cannot be referenced from a static context
目标,定义了一个内部类,然后把这个内部类设置为单例 一 使用非静态内部类 public class OuterClass {public class InnerClass {} } 直接定义单例: .OuterClass.this cannot be referenced from a static context public class OuterClass …...

CAP与BASE分布式理论
一、分布式理论 1.CAP理论 CAP理论是说对于分布式数据存储,最多只能同时满足一致性(C,Consistency)、可用性(A, Availability)、分区容忍性(P,Partition Tolerance&…...
JavaScript性能优化策略
JavaScript性能优化策略可以分为以下几个方面: 减少内存使用:避免创建不必要的对象和数组,使用对象池或数组缓存来重复利用已有的对象和数组。此外,及时释放不再需要的对象和数组,避免内存泄漏。 减少重绘和回流&…...
curl访问流式非流式大模型openai api接口
参考:https://platform.openai.com/docs/api-reference/making-requests 命令行访问: 直接是vllm的openai api接口 curl http://192.168.***:10860/v1/chat/completions -H "Content-Type: application/json" -H "Authorization: EMPTY" -d {"mod…...
Go 使用 MongoDB
MongoDB 安装(Docker)安装 MongoDB Go 驱动使用 Go Driver 连接到 MongoDB在 Go 里面使用 BSON 对象CRUD 操作 插入文档更新文档查询文档删除文档 下一步 MongoDB 安装(Docker) 先装个 mongo,为了省事就用 docker 了。 docker 的 daemon.json 加一个国内的源地址…...
什么是g++-arm-linux-gnueabihf
2024年5月3日,周五晚上 g-arm-linux-gnueabihf 是针对 ARM 架构(ARMv7 和 ARMv8)的 Linux 系统开发的 GNU C 编译器套件,可以在 x86 或 x86_64 架构的主机上使用,用于交叉编译 ARM Linux 应用程序和库。 与 gcc-arm-l…...
Unity延时触发的几种常规方法
目录 1、使用协程Coroutine2、使用Invoke、InvokeRepeating函数3、使用Time.time4、使用Time.deltaTime5、使用DOTween。6、使用Vision Timer。 1、使用协程Coroutine public class Test : MonoBehaviour {// Start is called before the first frame updatevoid Start(){ …...

CSS文字描边,文字间隔,div自定义形状切割
clip-path: polygon( 0 0, 68% 0, 100% 32%, 100% 100%, 0 100% );//这里切割出来是少一角的正方形 letter-spacing: 1vw; //文字间隔 -webkit-text-stroke: 1px #fff; //文字描边1px uniapp微信小程序顶部导航栏设置透明,下拉改变透明度 onP…...

XWiki 服务没有正确部署在tomcat中,如何尝试手动重新部署?
1. 停止 Tomcat 服务 首先,您需要停止正在运行的 Tomcat 服务器,以确保在操作文件时不会发生冲突或数据损坏: sudo systemctl stop tomcat2. 清空 webapps 下的 xwiki 目录和 work 目录中相关的缓存 删除 webapps 下的 xwiki 目录和 work …...
【退役之重学Java】关于 Redis
一、Redis 都有哪些数据类型 String 最基本的类型,普通的set和get,做简单的kv缓存hash 这是一个类似map 的一种结构,这个一般可以将结构化的数据,比如一个对象(前提是这个对象没有嵌套其他的对象)给缓存在…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
文章目录 一、开启慢查询日志,定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...

【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...