<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          NoSQL | MongoDB入門實(shí)戰(zhàn)教程(6)

          共 3147字,需瀏覽 7分鐘

           ·

          2021-07-19 12:14

          【NoSQL| 總結(jié)/Edison Zhou

          通過(guò)前面幾篇的學(xué)習(xí),作為后端開(kāi)發(fā)的我們基本可以應(yīng)付70%的開(kāi)發(fā)場(chǎng)景。接下來(lái),我們就來(lái)看點(diǎn)進(jìn)階一點(diǎn)的東西,首先是聚合查詢。

          1聚合框架簡(jiǎn)介

          前面的學(xué)習(xí)我們都是針對(duì)單個(gè)Collection操作的,雖然在MongoDB中針對(duì)Collection的設(shè)計(jì)就已經(jīng)是無(wú)模式的,因此我們大部分場(chǎng)景都是針對(duì)單個(gè)Collection進(jìn)行操作。

          但是,我們?cè)趯?shí)際應(yīng)用場(chǎng)景中還是會(huì)遇到想要SQL查詢中的 GROUP BY、LEFT OUTER JOIN、AS等操作。

          好在,MongoDB提供了一套聚合框架(Aggregation Framework),它可以幫助我們?cè)谝粋€(gè)或多個(gè)Collection上,對(duì)Collection中的數(shù)據(jù)進(jìn)行一系列的計(jì)算,并將這些數(shù)據(jù)轉(zhuǎn)化為期望的格式。

          整個(gè)聚合計(jì)算的過(guò)程也被稱之為管道(Pipeline),由多個(gè)步驟(Stage)組成,這一點(diǎn)和Jenkins Pipeline比較類似。其中,每個(gè)管道需要:

          (1)接受一系列Document(原始數(shù)據(jù))

          (2)每個(gè)步驟對(duì)這些Document進(jìn)行一系列的運(yùn)算

          (3)結(jié)果Document輸出給下一個(gè)步驟

          整個(gè)管道的過(guò)程如下圖所示:

          聚合計(jì)算的基本格式如下所示:

          pipeline = [$stage1, $stage2, ...$stageN];
          db.<CollectionName>.aggregate(pipeline,{ options });
          2聚合操作實(shí)例

          示例數(shù)據(jù)數(shù)據(jù)庫(kù)

          這里我們使用《MongoDB入門實(shí)戰(zhàn)教程(3)》中使用Mongo Tools進(jìn)行恢復(fù)的Mock數(shù)據(jù)庫(kù)中的orders集合來(lái)進(jìn)行應(yīng)用。

          在orders集合中,約有100000條記錄。

          每個(gè)order文檔的數(shù)據(jù)模型如下所示:

          練習(xí)1:目前為止的訂單總銷量

          假設(shè)我們需要針對(duì)orders集合進(jìn)行一個(gè)操作,計(jì)算到目前為止的所有訂單的總銷售額:

          db.orders.aggregate([  { $group:    {      _id: null,      total: { $sum: "$total" }    }  }]);

          這里我們使用到了一個(gè)常見(jiàn)的步驟(Stage):$group,它和SQL中的GROUP BY等價(jià),用于對(duì)數(shù)據(jù)進(jìn)行分組。這里我們僅僅是做一個(gè)求和,不需要對(duì)誰(shuí)進(jìn)行分組。

          然后,我們還用到了一個(gè)分組步驟中常用的運(yùn)算符:$sum,它和SQL中的SUM等價(jià),用于對(duì)指定列的數(shù)據(jù)進(jìn)行求和。這里我們需要對(duì)total字段進(jìn)行一個(gè)求和。

          下圖是查詢結(jié)果:

          練習(xí)2:某個(gè)日期區(qū)間的訂單金額匯總

          假設(shè)我們需要查詢?cè)?019年第一季度已完成訂單的訂單總金額和訂單總數(shù)。

          說(shuō)明:第一季度為1月1日~3月31日,訂單狀態(tài)為completed。

          db.orders.aggregate([// 步驟1:匹配條件{ $match: { status: "completed", orderDate: {                                $gte: ISODate("2019-01-01"),                                $lt: ISODate("2019-04-01") } } },// 步驟二:聚合訂單總金額、總運(yùn)費(fèi)、總數(shù)量{ $group: {              _id: null,              total: { $sum: "$total" },              shippingFee: { $sum: "$shippingFee" },              count: { $sum: 1 } } },{ $project: {              // 計(jì)算總金額              grandTotal: { $add: ["$total", "$shippingFee"] },              count: 1,              _id: 0 } }])

          可以看到,這是一個(gè)較為復(fù)雜的查詢,我們可以將其分為三步:

          第一步,使用$match進(jìn)行匹配,這一點(diǎn)是做的SQL中的WHERE操作。

          第二步,使用$group進(jìn)行分組,目的是為了使用SUM運(yùn)算符求和。

          第三步,使用$project進(jìn)行投影,目的是選擇需要的或排除不需要的字段顯示。

          下圖是查詢結(jié)果:

          3MQL vs SQL

          分頁(yè)查詢對(duì)比

          在SQL中常使用SKIP 和 LIMIT 進(jìn)行分頁(yè)查詢,在MQL中也有等價(jià)操作:

          -- SQLSELECT  FIRST_NAME AS `名`,  LAST_NAME AS `姓`FROM UsersWHERE GENDER = '男'SKIP 100LIMIT 20-- MQLdb.users.aggregate([  {$match: {gender: "男"}},  {$skip: 100},  {$limit: 20},  {$project: {    '名': '$first_name',    '姓': '$last_name'  }}]);

          分組查詢對(duì)比

          在SQL中常使用GROUP BY + HAVING 的分組高級(jí)查詢,在MQL中也有等價(jià)操作:

          -- SQLSELECT DEPARTMENT,  COUNT(NULL) AS EMP_QTYFROM UsersWHERE GENDER = '女'GROUP BY DEPARTMENT HAVINGCOUNT(*) < 10-- MQLdb.users.aggregate([  {$match: {gender: '女'}},  {$group: {    _id: '$DEPARTMENT’,    emp_qty: {$sum: 1}  }},  {$match: {emp_qty: {$lt: 10}}}]);

          unwind

          在MQL中有一個(gè)特有的步驟 unwind,它可以實(shí)現(xiàn)將文檔中的某一個(gè)數(shù)組類型字段拆分成多條,每條包含數(shù)組中的一個(gè)值。

          > db.students.findOne(){  name:'張三',  score:[    {subject:'語(yǔ)文',score:84},    {subject:'數(shù)學(xué)',score:90},    {subject:'外語(yǔ)',score:69}  ]}
          > db.students.aggregate([{$unwind: '$score'}]){name: '張三', score: {subject: '語(yǔ)文', score: 84}}{name: '張三', score: {subject: '數(shù)學(xué)', score: 90}}{name: '張三', score: {subject: '外語(yǔ)', score: 69}}
          End總結(jié)

          本文簡(jiǎn)單介紹了MongoDB的Aggregation Framework 以及 如何使用聚合框架進(jìn)行聚合查詢。

          下一篇,我們會(huì)學(xué)習(xí)MongoDB的模式設(shè)計(jì)中的一些設(shè)計(jì)模式。


          參考資料

          唐建法,《MongoDB高手課》(極客時(shí)間)

          郭遠(yuǎn)威,《MongoDB實(shí)戰(zhàn)指南》(圖書(shū))

          △推薦訂閱學(xué)習(xí)

          歡迎各位讀者加入微信群一起學(xué)習(xí)交流,
          在公眾號(hào)后臺(tái)回復(fù)“加群”即可~~

          ?

          ?

          瀏覽 113
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产精品99久久久精品无码 | 青青青草娱乐 | 午夜成人激情视频 | 国产精品二区高清在线苍井空 | 又大又粗又硬免费视频 |