在做聚合运算的时候,Map-reduce是个不错的选择;
顾名思义:Map-reduce主要通过实现Map函数与reduce函数来完成聚合操作,函数通过javascript代码来定义;
- 命令方式
db.collection.mapReduce(
map, //map函数(生成键值对序列,作为 reduce 函数参数)
reduce, //reduce函数
{
<out>, //存放输出结果的集合,不写使用临时集合
<query>, //筛选条件,符合条件才会进入map
<sort>, //排序
<limit>, //限制条数
<finalize>,
<scope>,
<jsMode>,
<verbose>
}
)
下面通过一个具体的例子,来分析Map-reduce的运行机制
consume集合中记录着用户每天的消费金额,其中字段分别为:
<user_id>用户标示,<price>用户消费金额,<date>消费日期
- 计算每个用户2016-06-01这天的消费金额
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分组,得到以user_id为key的数组,形成key-values的映射关系,再将key-values的映射关系做为参数,放入reduce函数,reduce函数,迭代values数组,将values数据内的消费金额叠加,返回total总值;
文字描述太绕,请看下图:
理解原理后,咱们就可以随意组合聚合啦~
- 将consume集合内的数据按照每天每个客户汇总金额
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
)