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 的一种结构,这个一般可以将结构化的数据,比如一个对象(前提是这个对象没有嵌套其他的对象)给缓存在…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...

Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...

Vue3 PC端 UI组件库我更推荐Naive UI
一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用,前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率,还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库(Naive UI、Element …...