日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

学习MongoDB 十一: MongoDB聚合(Aggregation Pipeline基础篇上)(三)

發布時間:2024/8/26 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 学习MongoDB 十一: MongoDB聚合(Aggregation Pipeline基础篇上)(三) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、Aggregate簡介?


? ? ? ? ? ? ? ??db.collection.aggregate()是基于數據處理的聚合管道,每個文檔通過一個由多個階段(stage)組成的管道,可以對每個階段的管道進行分組、過濾等功能,然后經過一系列的處理,輸出相應的結果。

? ? ? ? ? ? ? ?

? ? ???圖來自https://docs.mongodb.com/manual/aggregation/ 官方網

??? ? ? 我們通過這張圖,可以清晰的了解Aggregate處理的過程

??

? ? ? ? ?1db.collection.aggregate()可以多個管道,能方便的進行數據的處理。

? ? ? ? ?2db.collection.aggregate()使用了MongoDB內置的原生操作,聚合效率非常高,支持類似于SQL Group By操作的功能,而不再需要用戶編寫自定義的JavaScript例程。

? ? ? ? ?3?每個階段管道限制為100MB內存。如果一個節點管道超過這個極限,MongoDB將產生一個錯誤。為了能夠在處理大型數據集,可以設置allowDiskUsetrue來在聚合管道節點把數據寫入臨時文件。這樣就可以解決100MB內存的限制。

? ? ? ? ?4、db.collection.aggregate()可以作用在分片集合,但結果不能輸在分片集合,MapReduce可以 作用在分片集合,結果也可以輸在分片集合。

? ? 5、db.collection.aggregate()方法可以返回一個指針(cursor),數據放在內存中,直接操作。跟Mongo shell 一樣指針操作。

? ? ? ? ?6db.collection.aggregate()輸出的結果只能保存在一個文檔中,BSON Document大小限制為16M。可以通過返回指針解決,版本2.6中后面:DB.collect.aggregate()方法返回一個指針,可以返回任何結果集的大小。

? ? ? ? ?

?二、aggregate語法:

?

? ? ? db.collection.aggregate(pipeline, options)

?

? ? ?【pipeline ?$group參數】

?

? ? ? ? ?pipeline?類型是Array ?語法:?db.collection.aggregate( [ { <stage> }, ... ] )?

? ? ? ?$group :?將集合中的文檔分組,可用于統計結果,$group首先將數據根據key進行分組。

? ? ? $group語法:?{ $group: { _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ... } }

? ? ? ? ? _id?是要進行分組的key

? ? ? ?$group:可以分組的數據執行如下的表達式計算:

? ? ? ? ? ?$sum:計算總和。

? ? ? ? ? ?$avg:計算平均值。

? ? ? ? ? ?$min:根據分組,獲取集合中所有文檔對應值得最小值。

? ? ? ? ? ?$max:根據分組,獲取集合中所有文檔對應值得最大值。

? ? ? ? ? ?$push:將指定的表達式的值添加到一個數組中。

? ? ? ? ? ?$addToSet:將表達式的值添加到一個集合中(無重復值)。

? ? ? ? ? ?$first:返回每組第一個文檔,如果有排序,按照排序,如果沒有按照默認的存儲的順序的第一個文檔。

? ? ? ? ? ?$last:返回每組最后一個文檔,如果有排序,按照排序,如果沒有按照默認的存儲的順序的最后個文檔。

?

? ? ?我們可以通過Aggregation pipeline一些使用sql用法一樣,我們能很清晰的怎么去使用

?

? ? ? ? ? ?pipeline ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sql

? ? ? ? ? ?$avg ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?avg

? ? ? ? ? ?$min ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?min

? ? ? ? ? ?$max ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??max?

? ? ? ? ? ?$group ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? group by

? ? ? ? ? ?$sort ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? order by

? ? ? ? ? ?$limit ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? limit? ? ? ? ? ? ? ? ? ?

? ? ? ? ? ?$sum ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sum()

? ? ? ? ? ?$sum ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?count()


? ?三、pipeline $group 簡單的例子


? ? ??【數據 】?

[sql]?view plaincopy
  • db.items.insert(?[??
  • ??{??
  • ???"quantity"?:?2,??
  • ???"price"?:?5.0,??
  • ???"pnumber"?:?"p003",??
  • ??},{??
  • ???"quantity"?:?2,??
  • ???"price"?:?8.0,??
  • ???"pnumber"?:?"p002"??
  • ??},{??
  • ???"quantity"?:?1,??
  • ???"price"?:?4.0,??
  • ???"pnumber"?:?"p002"??
  • ??},{??
  • ???"quantity"?:?2,??
  • ???"price"?:?4.0,??
  • ???"pnumber"?:?"p001"??
  • ??},{??
  • ???"quantity"?:?4,??
  • ???"price"?:?10.0,??
  • ???"pnumber"?:?"p003"??
  • ??},{??
  • ???"quantity"?:?10,??
  • ???"price"?:?20.0,??
  • ???"pnumber"?:?"p001"??
  • ??},{??
  • ???"quantity"?:?10,??
  • ???"price"?:?20.0,??
  • ???"pnumber"?:?"p003"??
  • ??},{??
  • ???"quantity"?:?5,??
  • ???"price"?:?10.0,??
  • ???"pnumber"?:?"p002"??
  • ??}??
  • ])???????

  • ? ??【$group】

    ?

    ??????1、將集合中的文檔分組,可用于統計結果,$group首先將數據根據key進行分組。

    ? ? ? ? ? ? ?_id?是要進行分組的key,如果_idnull ?相當于select ?count(*) from table


    ??【 $sum】 ?

    ?????1、 我們統計items有幾條,相當于SQL: ?select count(1) as count from items

    [sql]?view plaincopy
  • >?db.items.count()??
  • 8??
  • >?db.items.aggregate([{$group:{_id:null,count:{$sum:1}}}])??
  • {?"_id"?:?null,?"count"?:?8?}??

  • ????2、我們統計一下數量,相當于SQL: select sum(quantity) as total ?from ?items

    [sql]?view plaincopy
  • >?db.items.aggregate([{$group:{_id:null,total:{$sum:"$quantity"}}}])??
  • {?"_id"?:?null,?"total"?:?36?}??

  • ? 3、我們通過產品類型來進行分組,然后在統計賣出的數量是多少,相當于SQL:select sum(quantity) as total from ?items ?group by pnumber

    [sql]?view plaincopy
  • ??>?db.items.aggregate([{$group:{_id:"$pnumber",total:{$sum:"$quantity"}}}])??
  • {?"_id"?:?"p001",?"total"?:?12?}??
  • {?"_id"?:?"p002",?"total"?:?8?}??
  • {?"_id"?:?"p003",?"total"?:?16?}??

  • 【$min?、?$max 】?

    ? ?1、我們通過相同的產品類型來進行分組,然后查詢相同產品類型賣出最多的訂單詳情 ,相當于SQL: select max(quantity) as quantity from ?items ?group by pnumber

    [sql]?view plaincopy
  • >?db.items.aggregate([{$group:{_id:"$pnumber",max:{$max:"$quantity"}}}])??
  • {?"_id"?:?"p001",?"max"?:?10?}??
  • {?"_id"?:?"p002",?"max"?:?5?}??
  • {?"_id"?:?"p003",?"max"?:?10?}??

  • ? ??2、我們通過相同的產品類型來進行分組,然后查詢相同產品類型賣出最多的訂單詳情 ,相當于SQL:select min(quantity) as quantity from ?items ?group by pnumber

    [sql]?view plaincopy
  • >?db.items.aggregate([{$group:{_id:"$pnumber",min:{$min:"$quantity"}}}])??
  • {?"_id"?:?"p001",?"min"?:?2?}??
  • {?"_id"?:?"p002",?"min"?:?1?}??
  • {?"_id"?:?"p003",?"min"?:?2?}??

  • ? 3、我們通過相同的產品類型來進行分組,統計各個產品數量,然后獲取最大的數量,相當于SQL:?select max(t.total) from (select sum(quantity) as total from ?items ?group by pnumber) t

    [sql]?view plaincopy
  • >?db.items.aggregate([{$group:{_id:"$pnumber",total:{$sum:"$quantity"}}}])??
  • {?"_id"?:?"p001",?"total"?:?12?}??
  • {?"_id"?:?"p002",?"total"?:?8?}??
  • {?"_id"?:?"p003",?"total"?:?16?}??
  • >?db.items.aggregate([{$group:{_id:"$pnumber",total:{$sum:"$quantity"}}},{$group:{_id:null,max:{$max:"$total"}}}])??
  • {?"_id"?:?null,?"max"?:?16?}??

  • 【$avg】

    ??? 先根據$group,在計算平均值,只會針對數字的進行計算,會對字符串忽略

    ?

    ? ? 1、我們通過相同的產品類型來進行分組,然后查詢每個訂單詳情相同產品類型賣出的平均價格,相當于SQL:select avg(price) as price from ?items ?group by pnumber

    [sql]?view plaincopy
  • ???
  • >?db.items.aggregate([{$group:{_id:"$pnumber",price:{$avg:"$price"}}}])??
  • {?"_id"?:?"p001",?"price"?:?12?}??
  • {?"_id"?:?"p002",?"price"?:?7.333333333333333?}??
  • {?"_id"?:?"p003",?"price"?:?11.666666666666666?}??

  • 【$push】

    ??????將指定的表達式的值添加到一個數組中,這個值不要超過16M,不然會出現錯誤

    ? ? 1、我們通過相同的產品類型來進行分組,然后查詢每個相同產品賣出的數量放在數組里面

    [sql]?view plaincopy
  • >?db.items.aggregate([{$group:{_id:"$pnumber",quantitys:{$push:"$quantity"}}}])??
  • {?"_id"?:?"p001",?"quantitys"?:?[?2,?10?]?}??
  • {?"_id"?:?"p002",?"quantitys"?:?[?2,?1,?5?]?}??
  • {?"_id"?:?"p003",?"quantitys"?:?[?2,?4,?10?]?}??
  • [sql]?view plaincopy
  • >?db.items.aggregate([{$group:{_id:"$pnumber",quantitys:{$push:{quantity:"$quantity",price:"$price"}}}}])??
  • {?"_id"?:?"p001",?"quantitys"?:?[?{?"quantity"?:?2,?"price"?:?4?},?{?"quantity":?10,?"price"?:?20?}?]?}??
  • {?"_id"?:?"p002",?"quantitys"?:?[?{?"quantity"?:?2,?"price"?:?8?},?{?"quantity":?1,?"price"?:?4?},?{?"quantity"?:?5,?"price"?:?10?}?]?}??
  • {?"_id"?:?"p003",?"quantitys"?:?[?{?"quantity"?:?2,?"price"?:?5?},?{?"quantity":?4,?"price"?:?10?},?{?"quantity"?:?10,?"price"?:?20?}?]?}??

  • 【 $addToSet】

    ? ? ? ?將表達式的值添加到一個數組中(無重復值),這個值不要超過16M,不然會出現錯誤

    [sql]?view plaincopy
  • >?db.items.aggregate([{$group:{_id:"$pnumber",quantitys:{$addToSet:"$quantity"}}}])??
  • {?"_id"?:?"p001",?"quantitys"?:?[?10,?2?]?}??
  • {?"_id"?:?"p002",?"quantitys"?:?[?5,?1,?2?]?}??
  • {?"_id"?:?"p003",?"quantitys"?:?[?10,?4,?2?]?}??

  • 【 $first、?$last】

    ? ? $first:返回每組第一個文檔,如果有排序,按照排序,如果沒有按照默認的存儲的順序的第一個文檔。

    ? ? $last:返回每組最后一個文檔,如果有排序,按照排序,如果沒有按照默認的存儲的順序的最后個文檔。

    [sql]?view plaincopy
  • >?db.items.aggregate([{$group:{_id:"$pnumber",quantityFrist:{$first:"$quantity"}}}])??
  • {?"_id"?:?"p001",?"quantityFrist"?:?2?}??
  • {?"_id"?:?"p002",?"quantityFrist"?:?2?}??
  • {?"_id"?:?"p003",?"quantityFrist"?:?2?}??


  • ? ? ??我們這篇主要介紹了aggregate ?pipeline的$group 基礎操作,后續介紹了 pipeline其他參數和options使用

    總結

    以上是生活随笔為你收集整理的学习MongoDB 十一: MongoDB聚合(Aggregation Pipeline基础篇上)(三)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。