天天看點

mongodb aggregate mapReduce and group

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 個參數:一個是組内本條記錄,一個是累加器資料

按照部門分組,計算每個部門的工資總和,如下所示:

繼續閱讀