mongodb的mapReduce查詢


mapReduce從字面上來理解就是兩個過程:map映射以及reduce化簡。是一種大數據處理方法,其難度不高,從性能上來說屬於比較暴力的(通過N台服務器同時來計算),但相較於group以及aggregate來說,功能更強大,並更加靈活。

  1. 映射過程:先把某一類數據分組歸類,這里的映射過程是支持分布式的,一邊遍歷每一台服務器,一邊進行分類。

  2. 化簡過程:然后再在分組中進行運算,這里的化簡過程也是支持分布式的,在分類的過程中直接運算了。也就是說如果是一個求和的過程,先在a服務器分組求和,然后再在b服務器分組求和····最后再把化簡以后的數據進行最終處理。在映射化簡的過程都是每台服務器自己的CPU在運算,大量的服務器同時來進行運算工作,這就是大數據基本理念。

mapReduce可以用js語法來寫。下面是結構:

db.table.mapReduce(  
        map,  
       reduce,  
        {  
            query: query,  
            out: out,    //指定結果集以什么方式存儲,可選參數包括:  
                        //replace:如果文檔(table)存在,則替換table,  
                        //merge:如果文檔中存在記錄,則覆蓋已存在的文檔記錄  
                        //reduce: 如果文檔中存在相同key的記錄了,則先計算兩條記錄,然后覆蓋舊記錄  
                        // {inline:1}  在內存中存儲記錄,不寫入磁盤(用戶數據量少的計算) 
            sort: sort,  
            limit: limit,  
            finalize: function  //這個function主要用來在存入out之前可以修改數據,function(key,values) {   
                                //return modifiedValues;}  
            scope: document,    //設置參數值,在這里設置的值在map,reduce,finalize函數中可見
            jsMode:boolean      //是否減少執行過程中BSON和JS的轉換,默認true]
                                //false時 BSON-->JS-->map-->BSON-->JS-->reduce-->BSON,可處理非常大的mapreduce,
                                //true時BSON-->js-->map-->reduce-->BSON
                               
            verbose:boolean     //是否產生更加詳細的服務器日志,默認true
            keytemp:boolean    //true或false,表明結果輸出到的collection是否是臨時的,如果為true,則會在客戶端連接中斷后自動刪除,如果你用的是MongoDB的mongo客戶端連接,  
                                //那必須exit后才會刪除。如果是腳本執行,腳本退出或調用close會自動刪除結果collection    

        }  
    )  
必備參數:map,reduce, out,

 詳解:

map: function() {emit(this.cat_id,this.goods_number); }, // 函數內部要調用內置的emit函數,cat_id代表根據cat_id來進行分組,goods_number代表把文檔中的goods_number字段映射到cat_id分組上的數據,其中this是指向向前的文檔的,這里的第二個參數可以是一個對象,如果是一個對象的話,也是作為數組的元素壓進數組里面;

reduce: function(cat_id,all_goods_number) {return Array.sum(all_goods_number)}, // cat_id代表着cat_id當前的這一組,all_goods_number代表當前這一組的goods_number集合,這部分返回的就是結果中的value值;

out: <output>, // 輸出到某一個集合中,注意本屬性來還支持如果輸出的集合如果已經存在了,那是替換,合並還是繼續reduce? 另外還支持輸出到其他db的分片中,具體用到時查閱文檔,篩選出現的鍵名分別是_id和value;

query: <document>, // 一個查詢表達式,是先查詢出來,再進行mapReduce的

sort: <document>, // 發往map函數前先給文檔排序

limit: <number>, // 發往map函數的文檔數量上限,該參數貌似不能用在分片模式下的mapreduce

finalize: function(key, reducedValue) {return modifiedObject; }, // 從reduce函數中接受的參數key與reducedValue,並且可以訪問scope中設定的變量

scope: <document>, // 指定一個全局變量,能應用於finalize和reduce函數

jsMode: <boolean>, // 布爾值,是否減少執行過程中BSON和JS的轉換,默認true,true時BSON-->js-->map-->reduce-->BSON,false時 BSON-->JS-->map-->BSON-->JS-->reduce-->BSON,可處理非常大的mapreduce。

verbose: <boolean> // 是否產生更加詳細的服務器日志,默認true

 

在集合 orders 中查找 status:"A" 的數據,並根據 cust_id 來分組,並計算 amount 的總和。圖解:


 下面是我個人的動手實驗。

    1. 在logsInfo表數據中,根據logcategory進行分組統計數量。

   2.  db.表名. mapReduce實例:

  3. 查看mapReduce的統計結果:

 

 

 

mapReduce中map函數可以理解為分組, emit里的key為分組依據,value建議用count統計次數。

下面這個例子value為數據庫的值耗時慢,達不到效果。

 mapReduce中的query參數,一般用來過濾使用。 當滿足query的條件時,調用mapReduce。相當於SQL的where條件。 query的語句請看我上篇mongodb的文章,聚合查詢中有寫道這些條件操作符。

 

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM