Aggregate
MongoDB中聚合(aggregate)主要用于處理資料(諸如統計平均值,求和等),并傳回計算後的資料結果,類似sql語句中的 count(*)
文法如下:
db.collection.aggregate()
db.collection.aggregate(pipeline,options)
db.runCommand({
aggregate: "<collection>",
pipeline: [ <stage>, <...> ],
explain: <boolean>,
allowDiskUse: <boolean>,
cursor: <document>
})
在使用aggregate實作聚合操作之前,我們首先來認識下幾個常用的聚合操作符。
$project::可以對結果集中的鍵 重命名,控制鍵是否顯示,對列進行計算。
$match: 過濾結果集,隻輸出符合條件的文檔。
$skip: 在顯示結果的時候跳過前幾行,并傳回餘下的文檔。
$sort: 對即将顯示的結果集排序
$limit: 控制結果集的大小
$unwind:将文檔中的某一個數組類型字段拆分成多條,每條包含數組中的一個值。
$geoNear:輸出接近某一地理位置的有序文檔。
$group: 分組,聚合,求和,平均數,最大值,最小值,第一個,最後一個,等
表達式 描述 執行個體
$sum 計算總和 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avg 計算平均值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$min 擷取集合中所有文檔對應值得最小值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$max 擷取集合中所有文檔對應值得最大值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$push 在結果文檔中插入值到一個數組中 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet在結果文檔中插入值到一個數組中,但不建立副本 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first 根據資源文檔的排序擷取第一個文檔資料 db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last 根據資源文檔的排序擷取最後一個文檔資料 db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])
執行個體:
db.createCollection("emp")
db.emp.insert({_id:1,"ename":"tom","age":25,"department":"Sales","salary":6000})
db.emp.insert({_id:2,"ename":"eric","age":24,"department":"HR","salary":4500})
db.emp.insert({_id:3,"ename":"robin","age":30,"department":"Sales","salary":8000})
db.emp.insert({_id:4,"ename":"jack","age":28,"department":"Development","salary":8000})
db.emp.insert({_id:5,"ename":"Mark","age":22,"department":"Development","salary":6500})
db.emp.insert({_id:6,"ename":"marry","age":23,"department":"Planning","salary":5000})
db.emp.insert({_id:7,"ename":"hellen","age":32,"department":"HR","salary":6000})
db.emp.insert({_id:8,"ename":"sarah","age":24,"department":"Development","salary":7000})
Map Reduce
Map-Reduce是一種計算模型,簡單的說就是将大批量的工作(資料)分解(MAP)執行,然後再将結果合并成最終結果(REDUCE)
MongoDB提供的Map-Reduce非常靈活,對于大規模資料分析也相當實用。
以下是MapReduce的基本文法:
>db.collection.mapReduce(
function() {emit(key,value);}, //map 函數
function(key,values) {return reduceFunction}, //reduce 函數
{
out: collection,
query: document,
sort: document,
limit: number
}
)
使用 MapReduce 要實作兩個函數 Map 函數和 Reduce 函數,Map 函數調用 emit(key, value), 周遊 collection 中所有的記錄, 将key 與 value 傳遞給 Reduce 函數進行處理。
Map 函數必須調用 emit(key, value) 傳回鍵值對。
參數說明:
map :映射函數 (生成鍵值對序列,作為 reduce 函數參數)。
reduce 統計函數,reduce函數的任務就是将key-values變成key-value,也就是把values數組變成一個單一的值value。。
out 統計結果存放集合 (不指定則使用臨時集合,在用戶端斷開後自動删除)。
query 一個篩選條件,隻有滿足條件的文檔才會調用map函數。(query。limit,sort可以随意組合)
sort 和limit結合的sort排序參數(也是在發往map函數前給文檔排序),可以優化分組機制
limit 發往map函數的文檔數量的上限(要是沒有limit,單獨使用sort的用處不大)
Group
基本文法如下:
db.runCommand({group:{
ns:集合名稱,
key:分組的鍵對象,
initial:初始化累加器,
$reduce:組分解器,
condition:條件,
finalize:組完成器}})
分組首先會按照key進行分組,每組的每個文檔全要執行$reduce方法,該方法接收2 個參數:一個是組内本條記錄,一個是累加器資料
按照部門分組,計算每個部門的工資總和,如下所示: