在做聚合運(yùn)算的時(shí)候,Map-reduce是個(gè)不錯(cuò)的選擇;
顧名思義:Map-reduce主要通過(guò)實(shí)現(xiàn)Map函數(shù)與reduce函數(shù)來(lái)完成聚合操作,函數(shù)通過(guò)javascript代碼來(lái)定義仰楚;
- 命令方式
db.collection.mapReduce(
map, //map函數(shù)(生成鍵值對(duì)序列,作為 reduce 函數(shù)參數(shù))
reduce, //reduce函數(shù)
{
<out>, //存放輸出結(jié)果的集合,不寫(xiě)使用臨時(shí)集合
<query>, //篩選條件,符合條件才會(huì)進(jìn)入map
<sort>, //排序
<limit>, //限制條數(shù)
<finalize>,
<scope>,
<jsMode>,
<verbose>
}
)
下面通過(guò)一個(gè)具體的例子月劈,來(lái)分析Map-reduce的運(yùn)行機(jī)制
consume集合中記錄著用戶(hù)每天的消費(fèi)金額,其中字段分別為:
<user_id>用戶(hù)標(biāo)示藤乙,<price>用戶(hù)消費(fèi)金額猜揪,<date>消費(fèi)日期
- 計(jì)算每個(gè)用戶(hù)2016-06-01這天的消費(fèi)金額
db.consume.mapReduce(
function(){ emit( this.user_id,this.price ) },
function(key,values){
var total = 0 ;
for(var i=0;i<values.length;i++){
total += values[i];
}
return total;
},//end reduce function
{
query:{"date":"2016-06-01"}
}
)
上文中的例子主要邏輯是,將集合中的文檔按user_id分組坛梁,得到以u(píng)ser_id為key的數(shù)組而姐,形成key-values的映射關(guān)系,再將key-values的映射關(guān)系做為參數(shù)划咐,放入reduce函數(shù)拴念,reduce函數(shù),迭代values數(shù)組褐缠,將values數(shù)據(jù)內(nèi)的消費(fèi)金額疊加政鼠,返回total總值;
文字描述太繞队魏,請(qǐng)看下圖:
理解原理后缔俄,咱們就可以隨意組合聚合啦~
- 將consume集合內(nèi)的數(shù)據(jù)按照每天每個(gè)客戶(hù)匯總金額
var mapfunction = function(){
emit( {this.date, this.user_id},this.price} )
}
var reducefunction = function(key,values){
var total = 0 ;
for(var i=0;i<values.length;i++){
total += values[i];
}
return total;
}
db.consume.mapReduce(
mapfunction,
reducefunction
)