MongoDB中的Map/reduce 進行一些複合查詢 , 因為mongodb不支援GROUP BY 查詢, MapReduce 又類似於SQL的 GROUP BY ,所以可以認為 MapReduce 就是 mongodb 版的GROUP BY
命令如下:
db.runCommand( { mapreduce : , map : , reduce : [, query : ] [, sort : ] [, limit : ] [, out : ] [, keeptemp: ] [, finalize : ] [, scope : ] [, verbose : true] } ); mapreduce:指定要進行mapreduce處理的collection map:map函數 reduce:reduce函數 query:一個篩選條件,只有滿足條件的行才會加入mapreduce集合,而這個篩選過程是先於整個mapreduce流程而執行的 sort:和query結合的sort排序參數,這是唯一可以最佳化分組機制的地方 limit:同上 out:結果輸出的collection的名字,不指定會預設建立一個隨機名字的collection keytemp:true或false,表明結果輸出到的collection是否是臨時的,如果為true,則會在用戶端串連中斷後自動刪除,如果你用的是MongoDB的mongo用戶端串連, 那必須exit後才會刪除。如果是指令碼執行,指令碼退出或調用close會自動刪除結果collection finalize:和map,reduce一樣是一個函數,它可以在reduce得出一個結果後再對key和value進行一次計算並返回一個最終結果 scope:設定參數值,在這裡設定的值在map,reduce,finalize函數中可見 verbose:在執行過程中列印調試資訊。 返回結果結構如下: { result : , counts : { input : , emit : , output : } , timeMillis : , ok : <1_if_ok>, [, err : ] } result:儲存結果的collection的名字 input:滿足條件的資料行數 emit:emit調用次數,也就是所有集合中的資料總量 ouput:返回結果條數 timeMillis:執行時間,毫秒為單位 ok:是否成功,成功為1 err:如果失敗,這裡可以有失敗原因,不過從經驗上來看,原因比較模糊,作用不大 map函數
m= function (){ emit(this.hs, { "customid_data":[{customid:this.customid}], "salescountry_data":[{salescountry:this.salescountry}], "usd_data":this.usd, "num_data":this.num, "compid_data":[{compid:this.compid}] } ) }
reduce函數:
r=function (key,values) { var ret = { "customid_data":[], "salescountry_data":[], "usd_data":0, "num_data":0, "compid_data":[] }; var customid= {}; var salescountry={}; var compid={}; for(var i=0;i<values.length;i++){ var ia = values[i]; for(var j in ia.customid_data){ if(!customid[ia.customid_data[j].customid]){ customid[ia.customid_data[j].customid]=true; ret.customid_data.push(ia.customid_data[j]); } } for(var j in ia.salescountry_data){ if(!salescountry[ia.salescountry_data[j].salescountry]){ salescountry[ia.salescountry_data[j].salescountry]=true; ret.salescountry_data.push(ia.salescountry_data[j]); } } for(var j in ia.compid_data){ if(!compid[ia.compid_data[j].compid]){ compid[ia.compid_data[j].compid]=true; ret.compid_data.push(ia.compid_data[j]); } } ret.usd_data+=values[i].usd_data; ret.num_data+=values[i].num_data; } return ret; }finalize函數:
f=function (key, values){ return { custom:values.customid_data.length, salescountry:values.salescountry_data.length, usd_sum:values.usd_data, num_sum:values.num_data, comp:values.compid_data.length }; } 執行mapReduce函數
db.collect.mapReduce(m,r,{out:'groupbyhs',query:{isimp:'1'},keytemp:false,finalize:f})
如果想使用sort和limit等功能,可以使用 res.find().sort({"value.totalNum":-1}).limit(2)來達到目的
需要注意的是:Reduce函數的傳回值也需要和Reduce函數的第二個參數結構一致。
參考文章:
關於mongodb中使用MapReduce的幾點實踐經驗
http://www.l99.com/EditText_view.action?textId=461413
如果想使用sort和limit等功能,可以使用 res.find().sort({"value.totalNum":-1}).limit(2)來達到目的(說的好)
用MongoDB實現MapReduce
http://www.open-open.com/lib/view/open1329107420952.html
Mongodb MapReduce編程模型
http://chenzhou123520.iteye.com/blog/1637672
MongoDB MapReduce(轉)
http://javabeezer.iteye.com/blog/1275124
所以Reduce函數的傳回值也需要和Reduce函數的第二個參數結構一致(這句話說的非常好啊。)
[轉]MongoDB MapReduce 用法及介紹
http://blog.163.com/sjy_814/blog/static/77801164201282531137196/
MongoDB 分組, 去重*******************************
http://my.oschina.net/huzorro/blog/73879