Mongodb聚合框架Aggregate
一 概念
1、簡介
mongo aggregation是mongo的一個輕量級的map-reduce框架,可以實現一些count,sum,group by的聚合。
使用聚合框架可以對集合中的文件進行變換和組合。可以用多個構件建立一個管道,用於對一連串的文件進行處理。構件有:篩選、投射、分組、排序、限制和跳過。
MongoDB的聚合管道將MongoDB文件在一個管道處理完畢後將結果傳遞給下一個管道處理,管道操縱是可以重複的。
2、管道表示式
管道操作符作為“鍵”,所對應的“值”叫做管道表示式。例如{$match:{status:”A”}},$match稱為管道操作符,而{status:”A”}稱為管道表示式,它可以看作是管道操作符的運算元(Operand),每個管道表示式是一個文件結構,它是由欄位名、欄位值、和一些表示式操作符組成的,例如管道表示式$group: { _id: null, count: { $sum: 1 } } 就包含了一個表示式操作符$sum進行累加求和。
每個管道表示式只能作用於處理當前正在處理的文件,而不能進行跨文件的操作。管道表示式對文件的處理都是在記憶體中進行的。除了能夠進行累加計算的管道表示式外,其他的表示式都是無狀態的,也就是不會保留上下文的資訊。累加性質的表示式操作符通常和$group操作符一起使用,來統計該組內最大值、最小值等。
3、aggregate語法
db.collection.aggregate(pipeline, options)
pipeline:管道運算元組,也可以為文件型別,如果該引數不是陣列形式,無法指定options引數
options:aggregate命令的附加選項,文件型別。
1) explain:布林值,指定返回結果是否顯示該操作的執行計劃
2) allowDiskUse:
布林值,指定該聚合操作是否使用磁碟。每個階段管道限制為100MB的記憶體。如果一個節點管道超過這個極限,MongoDB將產生一個錯誤。為了能夠在處理大型資料集,可以設定allowDiskUse為true來在聚合管道節點把資料寫入臨時檔案。這樣就可以解決100MB的記憶體的限制。
3) cursor:
4) maxTimeMS:
5) bypassDocumentValidation:
6) readConcern:
7) collation:
4、分片使用
db.collection.aggregate()可以作用在分片集合,但結果不能輸在分片集合,MapReduce可以 作用在分片集合,結果也可以輸在分片集合。
5、聚合中的遊標
db.collection.aggregate()方法可以返回一個指標(cursor),資料放在記憶體中,直接操作。跟Mongo shell 一樣指標操作。
二 管道操作符
1、$match:用於對文件集合進行篩選,在$match中不能使用$geoNear地理空間操作符及$where表示式操作符。
示例: 獲取分數大於70小於或等於90記錄,然後將符合條件的記錄送到下一階段$group管道操作符進行處理。
db.articles.aggregate( [
{ $match : { score : { $gt : 70, $lte : 90 } } },
{ $group: { _id: null, count: { $sum: 1 } } }
]);
2、$project:
示例: 獲取article集合的title欄位及author欄位,將欄位_id遮蔽
db.article.aggregate({
$project : {
_id : 0 ,
title : 1 ,
author : 1
}});
3、$group:操作可以根據文件特定欄位的不同值進行分組,$group不能用流式工作方式對文件進行處理。 在$group階段,記憶體的大小最大可以為100Mb,如果超過則會出錯。當處理大量資料是,可以將引數allowDiskUse置為true,如此$group操作符可以寫入臨時檔案,格式:
{ $group: { _id: <expression>,<field1>: { <accumulator1> : <expression1> }, … } }
_id欄位是強制性的,可以指定其為空來進行其他累加操作,accumulator操作符可以為:$sum、$avg、$first、$last、$max、$min、$push、$addToSet、$stdDevPop、$stdDevSamp
注:$group的輸出是無序的,且該操作目前是在記憶體中進行的,所以不能用它來對大量個數的文件進行分組。
4、$unwind:分割陣列嵌入到自己頂層檔案,會將陣列中的每一個值拆分為單獨的文件,這樣一個文件會被分為陣列長度個文件。
示例:將部落格評論對映為cts並查詢評論作者為Mark的文件
> db.blog.aggregate([
{"project":{"cts":"$comments"}},
{"$unwind":"$cts"},
{"$match":{"cts.author":"Mark"}
]);
注:{$unwind:”$cts”})不能忘了$符號,且如果$unwind目標欄位不存在的話,那麼該文件將被忽略過濾掉。
5、$limit:$limit會接受一個數字n,返回結果集中的前n個文件。
{ $limit: <positive integer> }
示例:查詢5條文件記錄
db.article.aggregate(
{ $limit : 5 }
);
6、$skip:$skip接受一個數字n,丟棄結果集中的前n個文件
{$skip: <positive integer> }
示例:獲取article集合中第5條資料之後的資料
db.article.aggregate(
{ $skip : 5 }
);
7、$sort:可以根據任何欄位進行排序,”$sort”不能用流式工作方式對文件進行處理,必須要接收到所有文件之後才能進行排序。當排序的欄位BSON型別不一致時,按一下順序進行排序
官方參考文件:
The MongoDB 3.2 Manual:
https://docs.mongodb.com/v3.2/
Spring Data MongoDB - Reference Documentation
https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/