MongoDB–聚合工具MapReduce
一:简介
mapreduce可以进行复杂的逻辑运算,但是处理速度很慢不适用于实时的数据分析中。
mmapreduce分为以下几个阶段:
- Map:把一个操作Map到集合中的每一个文档
- Shuffle: 根据Key分组对文档,并且为每个不同的Key生成一系列(>=1个)的值表(List of values)。
- Reduce: 处理值表中的元素,直到值表中只有一个元素。然后将值表返回到Shuffle过程,循环处理,直到每个Key只对应一个值表,并且此值表中只有一个元素,这就是MR的结果。
- Finalize:此步骤不是必须的。在得到MR最终结果后,再进行一些数据“修剪”性质的处理。
基本语法如下:
>db.collection.mapReduce(
function() {emit(key,value);}, //map 函数
function(key,values) {return reduceFunction}, //reduce 函数
{
out: collection,
query: document,
sort: document,
limit: number
}
)
二:找出集合中的所有键并计数
使用 MapReduce 要实现两个函数 Map 函数和 Reduce 函数,Map 函数调用 emit(key, value), 遍历 collection 中所有的记录, 将 key 与 value 传递给 Reduce 函数进行处理。
Map 函数必须调用 emit(key, value) 返回键值对
//map 函数使用特别的emit函数返回要处理的值。emit会给mapreduce一个键值对。这个key就当前文档的引用值,count用来计数
map=function(){
for(var key in this){
emit(key,{count:1});
}
}
//reduce函数用来接收map函数传递地过来的值,reduce函数在map阶段的结果上反复执行或者在上一和reduce的结果上反复执行
reduce = function(key,emits){
total=0;
for(var i in emits){
total+=emits[i].count;
}
return {"count":total};
}
//使用mapreduce聚合找出集合的所有键及其计数
cqsm>db.reac.mapReduce(
function(){
for(var key in this){
emit(key,{count:1}); //按照key分组,这里的key就是一个个的键
} //shuffle阶段将相同的key归到一起,为每个不同的Key生成一系列(>=1个)的值表
},
function(key,values){ //这里将key以及key对于的值表emits给reduce作为参数,reduce的第二个参数形参,shuffle会识别
total=0;
for(var i in values){
total+=emits[i].count; //将相同key的count累加
}
return {"count":total};
},
{
out:"reac1"
}
)
cqsm>db.reac.find()
{ "_id" : "_id", "value" : { "count" : 27 } }
{ "_id" : "author", "value" : { "count" : 22 } }
{ "_id" : "count", "value" : { "count" : 22 } }
{ "_id" : "count1", "value" : { "count" : 4 } }
{ "_id" : "date", "value" : { "count" : 22 } }
{ "_id" : "title", "value" : { "count" : 22 } }
{ "_id" : "totalPay", "value" : { "count" : 4 } }
{ "_id" : "value", "value" : { "count" : 5 } }
三:MongDB中MapReduce参数
- map :映射函数 (生成键值对序列,作为 reduce 函数参数)。
- reduce 统计函数,reduce函数的任务就是将key-values变成key-value,也就是把values数组变成一个单一的值value。。
- out 统计结果存放集合 (不指定则使用临时集合,在客户端断开后自动删除)。设置临时集合:out: { inline: 1 } 设置之后会在内存运行,不会持久化到磁盘。
- query 一个筛选条件,只有满足条件的文档才会调用map函数。(query。limit,sort可以随意组合)
- sort 和limit结合的sort排序参数(也是在发往map函数前给文档排序),可以优化分组机制
- limit 发往map函数的文档数量的上限(要是没有limit,单独使用sort的用处不大)
- finalize函数,fianlize可以当做mr的参数,它会在最后一个reduce输出结果后执行,然后将结果存在临时集合中