聚合操作
文章目錄
-
- 聚合操作
-
- 一、集合管道
-
- 1、管道介紹
- group中的操作表達式
- 2、管道優化
- 二、映射化簡
-
- 1、映射化簡的JavaScript方法
- 2、映射化簡的特點
- 三、單一目的聚合方法
聚合操作處理資料記錄并傳回計算結果。聚合操作将來自多個文檔的值分組在一起,并且可以對分組的資料執行各種操作以傳回單個結果。MongoDB提供了三種執行聚合的方法:聚合管道,map-reduce函數和單一目的聚合方法。
一、集合管道
1、管道介紹
聚合管道是一個基于資料處理管道概念模組化的資料聚合架構。文檔進入多階段管道,一個管道處理完畢後交給下一個管道,該管道将文檔轉換為彙總結果。
文法:db.collection_name.aggregate([{管道1},{管道2},{管道3},…])
常用的管道操作 | |
---|---|
$project | 修改輸入文檔的結構。可以用來重命名、增加或修改域,也可以用于建立計算結果以及嵌套文檔。 |
$match | 用于過濾資料,隻輸出符合條件的文檔。使用MongoDB的标準查詢操作。 |
$limit | 用來限制MongoDB聚合管道傳回的文檔數 |
$skip | 在聚合管道中跳過指定數量的文檔,并傳回餘下的文檔 |
$group | 将集合中的文檔分組,可用于統計結果 |
$sort | 将輸入文檔排序後輸出。 |
group中的操作表達式
表達式 | 描述 |
---|---|
$sum | 計算總和 |
$avg | 計算平均值 |
$min | 擷取集合中所有文檔對應值的最小值 |
$max | 擷取集合中所有文檔對應值得最大值 |
$first | 根據資源文檔的排序擷取第一個文檔資料 |
$last | 根據資源文檔的排序擷取最後一個文檔資料 |
練習:
1.查詢每個年齡段的人員數量:
db.school.aggregate([{$group:{_id:"$age",total:{$sum:1}}}])
2.查詢總共有多少人
db.school.aggregate([{$group:{_id:null,total:{$sum:1}}}])
2、管道優化
-
+$sort
$match
順序優化
如果管道中,sort後面跟着match,可以先使用match進行篩選,這樣會減少之後排序的對象。
-
+$skip
$match
順序優化
如果你的管道中,skip後面跟着limit,優化器會把limit移到skip前面,這個時候limit的會值加上skip的個數。
-
+$redact
順序優化$match
-
+$ project
或$ skip
序列優化$ limit
-
+$ sort
合并$ limit
-
+$ limit
合并$ limit
-
+$ skip
合并$ skip
-
+$ match
合并$ match
-
+$ lookup
合并$ unwind
-
+$ sort
+$ skip
順序$ limit
-
+$ limit
+$ skip
+$ limit
順序$ skip
二、映射化簡
1、映射化簡的JavaScript方法
在MongoDB中,map-reduce操作使用自定義javaScript函數将值映射或關聯到鍵。如果一個鍵具有映射到它的多個值,則該操作會将鍵的值減少到單個對象。
例如,當處理一個文檔的時候,映射函數可以映射多個鍵值對或者一個也不映射。映射化簡還可以在結束的時候使用JavaScript對聚合結果做最後的修改,例如附加的計算。
2、映射化簡的特點
在MongoDB中,map-reduce操作可以将結果寫入集合或内聯傳回結果。如果将map-reduce輸出寫入集合,則可以在同一輸入集合上執行随後的map-reduce操作,這些操作将替換結果,合并結果或歸約結果與先前結果合并。
如果選擇映射化簡操作的即時傳回結果,這些文檔一定要在
BSON文檔大小
限制以内,目前這個限制是16MB。
MongoDB支援對分片集合進行 map-reduce操作。Map-reduce操作還可以将結果輸出到分片集合。
三、單一目的聚合方法
MongoDB還提供
db.collection.count()
和
db.collection.distinct()
。
所有這些操作都彙總了單個集合中的文檔。盡管這些操作提供了對常見聚合過程的簡單通路,但是它們缺乏聚合管道和映射減少的靈活性和功能。
> db.goods.find()
{ "_id" : 1, "type" : 1 }
{ "_id" : 2, "type" : 2 }
{ "_id" : 3, "type" : 3 }
{ "_id" : 4, "type" : 2 }
{ "_id" : 5, "type" : 2 }
{ "_id" : 6, "type" : 3 }
> db.goods.distinct("type")
[ 1, 2, 3 ]
> db.goods.count()
6