Mongodb 的中資料統計神器Map_Reduce的使用

Loving....發表於2016-08-10

Map -reduce 就是先把資料拆分然後合併的的一種思想,在map 方法中至少要呼叫一次內建函式emit,該函式需要兩個引數,第一個是引數key,可以理解為關聯式資料庫中的group by 的欄位,第二個引數是value,也就是要進行聚合操作的欄位。emit 的作用是根據key ,把value組合為一個陣列,為reduce提供輸入引數值。執行reduce 處理,需要用兩個引數,第一個引數是key 第二個引數是value陣列,也就是上一步中產生的結果。在這個函式裡進行聚合處理,並返回處理後的物件,對上一步的結果進行finalize處理。把結果輸出到out指定的目標(v1.7 以上版本可以指定out{inline :1}直接返回結果集)例如:
db.users.mapReduce(m, r, {out : {inline : 1}})
MongoDB中使用emit函式向MapReduce提供Key/Value對。Reduce函式接受兩個引數:Key,emits. Key即為emit函式中的Key。 emits是一個陣列,它的元素就是emit函式提供的Value。Reduce函式的返回結果必須要能被Map或者Reduce重複使用,所以返回結果必須與emits中元素結構一致。Map或者Reduce函式中的this關鍵字,代表當前被Mapping文件。

map = %Q{
        function(){
          emit({userinfo_id:this.userinfo_id,customer_id:this.customer_id},{paycost:this.paycost})
        }
      }
      reduce = %Q{
        function(key,values){
          var res={order_count:0,order_amount:0.0}
          values.forEach(function(val){
              res.order_count += 1;
              if(!isNaN(val.paycost) && val.paycost!=""){
                  res.order_amount = res.order_amount +parseFloat(val.paycost);
              }
          });
          return res;
        }
      }
      results = OrderStateChange.where({'customer_id'=>analyse_infos[:customer_id],'userinfo_id'=>analyse_infos[:userinfo_id],'state'=>{'$in' => ['receive','completed']}}).map_reduce(map, reduce).out(inline: true)

這種操作最終將會按照我們設定的方式返回的資訊{_id:{userinfo_id:“121212”,customer_id:“23322”},value:{paycost:30}}
map中的引數的其實就是為reduce 提供(key ,value),key 和value都是可以封裝多個引數的如emit({userinfo_id:this.userinfo_id,customer_id:this.customer_id},{paycost:this.paycost})這個emit中的key 就是{userinfo_id:this.userinfo_id,customer_id:this.customer_id},value就是{paycost:this.paycost}。mongodb 中MR的使用可以非常大的提升資料的查詢和統計速度。真是屢試不爽

相關文章