MongoDB聚合運算符:$bottomN

$bottomN聚合運算符返回分組中指定順序的最后n個元素,如果分組中的元素數量小于n,則返回分組的全部元素。從MongoDB5.2開始支持。

語法

{$bottomN:{n: <expression>,sortBy: { <field1>: <sort order>, <field2>: <sort order> ... },output: <expression>}
}
  • n用于限制每組結果的數量,必須是正整數表達式,要么是常數,要么取決于$group_id
  • sortBy制定返回結果的順序,語法類似于$sort
  • output指定分組元素輸出的內容,可以是任何合法的表達式。

用法

  • $bottom不支持作為聚合表達式。
  • $bottom只支持作為window 操作符
  • 聚合管道調用$bottom受100M的限制,如果單組超過這一限制將報錯。

關于null和缺失值的處理

  • $bottom不會過濾掉空值
  • $bottom會將缺失值轉換為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的得分為null,他們的得分都會被當做null處理
  • playerId字段和score字段被指定為輸出:["$playerId"," $score"],以數組的形式返回
  • sortBy: { "score": -1 }指定了排序的方式,空值被排在最后,返回playerId數組

如下:

[{_id: "G1",playerId: [ [ "PlayerA", 1 ], [ "PlayerD", null ], [ "PlayerE", null ] ]}
]

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: {$bottomN:{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 }
])

查找三個得分最低的

使用$bottomN查找單個游戲中得分最低的3個:

db.gamescores.aggregate( [{$match : { gameId : "G1" }},{$group:{_id: "$gameId",playerId:{$bottomN:{output: ["$playerId", "$score"],sortBy: { "score": -1 },n:3}}}}
] )

本例中:

  • 使用$match階段用一個gameId對結果進行篩選,即:G1
  • 使用$group階段依據gameId對結果進行分組,本例中只有一個分組G1
  • 使用output : ["$playerId"," $score"]bottom指定輸出字段
  • 使用sortBy: { "score": -1 }按照得分進行逆序排序
  • 使用$bottomN返回游戲得分最低的3個選手和得分

結果如下:

[{_id: "G1",playerId: [ [ "PlayerB", 33 ], [ "PlayerA", 31 ], [ "PlayerD", 1 ] ]}
]

與下面的SQL查詢等價:

SELECT T3.GAMEID,T3.PLAYERID,T3.SCORE
FROM GAMESCORES AS GS
JOIN (SELECT TOP 3GAMEID,PLAYERID,SCOREFROM GAMESCORESWHERE GAMEID = "G1"ORDER BY SCORE) AS T3ON GS.GAMEID = T3.GAMEID
GROUP BY T3.GAMEID,T3.PLAYERID,T3.SCOREORDER BY T3.SCORE DESC

查找全部游戲中三個最低的得分

使用$bottomN查找所有游戲中得分最低的三個

db.gamescores.aggregate( [{$group:{ _id: "$gameId", playerId:{$bottomN:{output: [ "$playerId","$score" ],sortBy: { "score": -1 },n: 3}}}}
] )

在本例中:

  • 使用$group按照groupId對結果排序
  • 使用output : ["$playerId", "$score"]指定bottom輸出的字段
  • 使用sortBy: { "score": -1 }按照得分進行逆序排序
  • 使用$bottomN返回所有游戲中得分最低的三個

結果如下:

[{_id: "G1",playerId: [ [ "PlayerB", 33 ], [ "PlayerA", 31 ], [ "PlayerD", 1 ] ]},{_id: "G2",playerId: [ [ "PlayerC", 66 ], [ "PlayerB", 14 ], [ "PlayerA", 10 ] ]}
]

這個操作與下面的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 >= 2
ORDER BY GAMEID

基于分組key來計算參數n

可以動態指定n的值,在本例中$cond表達式用在gameId字段:

db.gamescores.aggregate([{$group:{_id: {"gameId": "$gameId"},gamescores:{$bottomN:{output: "$score",n: { $cond: { if: {$eq: ["$gameId","G2"] }, then: 1, else: 3 } },sortBy: { "score": -1 }}}}}
] )

在本例中:

  • 使用$group按照groupId對結果排序
  • 使用output : "$score"指定$bottomN輸出的字段
  • 如果gameIdG2n為1,否則n為3
  • 使用sortBy: { "score": -1 }按照得分進行逆序排序

操作結果如下:

[{ _id: { gameId: "G2" }, gamescores: [ 10 ] },{ _id: { gameId: "G1" }, gamescores: [ 33, 31, 1 ] }
]

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/715206.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/715206.shtml
英文地址,請注明出處:http://en.pswp.cn/news/715206.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

精品SSM的教學管理系統課程作業成績

《[含文檔PPT源碼等]精品基于SSM的教學管理系統[包運行成功]》該項目含有源碼、文檔、PPT、配套開發軟件、軟件安裝教程、項目發布教程、包運行成功&#xff01; 軟件開發環境及開發工具&#xff1a; Java——涉及技術&#xff1a; 前端使用技術&#xff1a;HTML5,CSS3、Jav…

esp32 C3和S3 開發板電流對比

出去好奇用合宙家的 lot power 測了兩塊開發板的運行電流。 esp32 S3 (嘉立創開發板 8N8 版本) 模式 電流downloa模式49 毫安空代碼91 毫安light mode27 毫安deep mode25 毫安delay 40 毫安 esp32 C3 無串口芯片 &#xff08;合宙 9.9 元版本&#xff09; 模式 …

uniapp npx update-browserslist-db@lates 問題解決

在uniapp運行項目時&#xff0c;會有這種報錯&#xff0c;其實這是表明browserslistlatest版本低了&#xff0c;在催你升級版本&#xff0c;browserslistlatest是用來支持解析css用的&#xff0c;當然&#xff0c;你也可以直接忽略這個報錯提示&#xff0c;也可以正常運行項目。…

探索數據結構:深入了解順序表的奧秘

?? 歡迎大家來到貝蒂大講堂?? &#x1f388;&#x1f388;養成好習慣&#xff0c;先贊后看哦~&#x1f388;&#x1f388; 所屬專欄&#xff1a;數據結構與算法 貝蒂的主頁&#xff1a;Betty’s blog 1. 什么是順序表 順序表是用一段物理地址連續的存儲單元依次存儲數據元…

【初中生講機器學習】13. 決策樹算法一萬字詳解!一篇帶你看懂!

創建時間&#xff1a;2024-03-02 最后編輯時間&#xff1a;2024-03-02 作者&#xff1a;Geeker_LStar 你好呀~這里是 Geeker_LStar 的人工智能學習專欄&#xff0c;很高興遇見你~ 我是 Geeker_LStar&#xff0c;一名初三學生&#xff0c;熱愛計算機和數學&#xff0c;我們一起加…

取送貨問題(Pickup and Delivery Problem)

取送貨問題及其變體 廣義取送貨問題&#xff08;General Pickup and Delivery Problems&#xff0c;GPDP&#xff09;可以分為兩類&#xff1a; Vehicle Routing Problems with Backhauls&#xff0c;VRPB&#xff1a;從配送中心&#xff08;depot&#xff09;取貨運輸貨物到客…

測試/測試開發八股——找大廠測試實習基礎篇

第一部分:基礎概念 1. 軟件測試是什么? 在規定的條件下對一個產品或者程序進行操作,以發現程序錯誤,衡量軟件質量,并對其是否能滿足設計要求進行評估的過程。 軟件測試工程師的任務 2. 軟件測試工程師的任務 軟件測試工程師主要工作是檢查軟件是否有bug、是否具有穩定…

5.設備驅動程序

5. 設備驅動程序 Linux 內核是一個比較龐大的系統&#xff0c;深入理解內核可以減少在系統移植中的障礙。在系統移植中設備驅動開發是一項很復雜的工作&#xff0c;由于 Linux 內核提供了一部分源代碼&#xff0c;同時還提供了對某些公共部分的支持&#xff0c;例如&#xff0c…

數據結構與算法:堆

朋友們大家好啊&#xff0c;本篇文章來到堆的內容&#xff0c;堆是一種完全二叉樹&#xff0c;再介紹堆之前&#xff0c;我們首先對樹進行講解 樹與堆 1.樹的介紹1.1節點的分類 2.樹的存儲結構3.二叉樹的概念和結構3.1 二叉樹的特點3.2 特殊的二叉樹3.3二叉樹的存儲結構 4.堆的…

Acwing---1460. 我在哪?

我在哪&#xff1f; 1.題目2.基本思想3.代碼實現 1.題目 農夫約翰出門沿著馬路散步&#xff0c;但是他現在發現自己可能迷路了&#xff01; 沿路有一排共 N N N 個農場。 不幸的是農場并沒有編號&#xff0c;這使得約翰難以分辨他在這條路上所處的位置。 然而&#xff0c;…

Mybatis | 動態SQL

目錄: 動態SQL中的 “元素” :\<if>元素\<choose>、\<when>、\<otherwise>元素\<where>、\<trim>元素\<set>元素\<foreach>元素\<bind>元素 作者簡介 &#xff1a;一只大皮卡丘&#xff0c;計算機專業學生&#xff0c;正…

單細胞Seurat - 降維與細胞標記(4)

本系列持續更新Seurat單細胞分析教程&#xff0c;歡迎關注&#xff01; 非線形降維 Seurat 提供了幾種非線性降維技術&#xff0c;例如 tSNE 和 UMAP&#xff0c;來可視化和探索這些數據集。這些算法的目標是學習數據集中的底層結構&#xff0c;以便將相似的細胞放在低維空間中…

__vueParentComponent和__vue__獲取dom元素上的vue實例

vue2: 使用__vue__ const el document.querySelector(.xxx); const vueInstance el.__vue__;vue3: 使用 __vueParentComponent const el document.querySelector(.xxx); const vueInstance el.__vueParentComponent;

Python錯題集-4:NameError:(變量名錯誤)

1問題描述 Traceback (most recent call last): File "D:\pycharm\projects\1-可視化學習\8.3更改小提琴圖的中位數、均值、顏色等.py", line 8, in <module> violin_parts plt.violinplot(data, showmediansTrue, showmeansTrue) …

代碼隨想錄算法訓練營第四十四天 完全背包 、零錢兌換 II 、組合總和 Ⅳ

代碼隨想錄算法訓練營第四十四天 | 完全背包 、零錢兌換 II 、組合總和 Ⅳ 完全背包 題目鏈接&#xff1a;題目頁面 (kamacoder.com) 解釋一、01背包 一維 &#xff1a;為什么要倒序遍歷背包&#xff1f; 首先要明白二維數組的遞推過程&#xff0c;然后才能看懂二維變一維的…

【MATLAB源碼-第150期】基于matlab的開普勒優化算法(KOA)機器人柵格路徑規劃,輸出做短路徑圖和適應度曲線。

操作環境&#xff1a; MATLAB 2022a 1、算法描述 開普勒優化算法&#xff08;Kepler Optimization Algorithm, KOA&#xff09;是一個虛構的、靈感來自天文學的優化算法&#xff0c;它借鑒了開普勒行星運動定律的概念來設計。在這個構想中&#xff0c;算法模仿行星圍繞太陽的…

項目風險:測試大佬結合實例告訴你如何應對!

項目有風險 今天下午15點&#xff0c;團隊成員D向他的主管Z反饋他測試的項目有風險&#xff1a;項目在測試周期內&#xff0c;但在用例評審時發現有一處功能邏輯有爭議&#xff0c;需要產品經理跟業務方確認&#xff0c;可能出現的情況有&#xff1a; 1 不變更需求&#xff0…

【技巧】SpringCloud Gateway實現多子域(單個應用開放多個端口)

0. 目錄 1. 需求背景2. 實現3. 額外 - 其它Servlet容器實現3.1 Undertow3.2 Tomcat 4. 相關 1. 需求背景 瀏覽器針對單個網站地址(ipport)存在“6個請求”限制&#xff1b;通過多子域配置可以突破這個限制&#xff0c;增加網站的響應效率&#xff0c;尤其是針對三維服務這類大…

【深入了解設計模式】組合設計模式

組合設計模式 組合模式是一種結構型設計模式&#xff0c;它允許你將對象組合成樹狀結構來表現“整體-部分”關系。組合模式使得客戶端可以統一對待單個對象和組合對象&#xff0c;從而使得代碼更加靈活和易于擴展。 概述 ? 對于這個圖片肯定會非常熟悉&#xff0c;上圖我們可…

Carla自動駕駛仿真九:車輛變道路徑規劃

文章目錄 前言一、關鍵函數二、完整代碼效果 前言 本文介紹一種在carla中比較簡單的變道路徑規劃方法&#xff0c;主要核心是調用carla的GlobalRoutePlanner模塊和PID控制模塊實現變道&#xff0c;大體的框架如下圖所示。 一、關鍵函數 1、get_spawn_point(),該函數根據指定r…