目录
摘要
MapReduce 概念,与 group 区别,使用
MapReduce
概述
- MapReduce 是聚合工具,可以实现 count,distinct,group 等功能。
- MapReduce 是并行化到多个服务器的聚合方法。它会拆开问题,发送到各个机器上,再从各个机器上汇聚结果返回。
与 group 的区别
- 由映射函数 (mapper) 用一个主键去调用
emit()
函数。而不是map()
函数返回转换过的值。这样的好处是每个文档可以不止发出一次。 - 效率比 group 慢,不适用于实时环境中,而应该用在后台任务中。
执行步骤
- 映射 (map) 将操作映射到集合中的每个文档。
- 洗牌 (shuffle) 按照键分组,并将产生的键值组成列表放到对应的键中。
- 化简 (reduce) 将列表中的值化简成一个单值。这个值被返回,接着再洗牌,直到每个键的列表只有一个值为止。
使用
测试数据
db.things.insert( { _id : 1, tags : ['dog', 'cat'] } );
db.things.insert( { _id : 2, tags : ['cat'] } );
db.things.insert( { _id : 3, tags : ['mouse', 'cat', 'dog'] } );
db.things.insert( { _id : 4, tags : [] } );
mapper
map = function(){
this.tags.forEach(
function(z){
emit( z , { count : 1 } );
}
);
};
emit
返回一组键值对, key
为第一个参数,values
为第二组参数的集合
在上述例子中,即返回 {'dog' : [{ count : 1, { count:1 }], 'cat' : ...}
。
reducer
reduce = function(key, values) {
var total = 0;
for(var i = 0; i< values.length; i++) {
total += values[i].count;
}
return { count : total };
}
reduce
用于将 map
传递过来的 key-values
转变成 key-value
。其两个参数即为 emit
返回的参数。
运行 mapreduce
results = db.runCommand({
mapReduce : 'phones',
map : map,
reduce : reduce,
out : 'phones.report'
})
db.phones.report.find({ '_id.country' : 8})
以上将结果存储到 phones.report
集合中,之后可以直接使用此表进行查询。
或者
db.things.mapReduce( map, reduce, { out : 'tmp' } )
db.tmp.find()
参数含义
mapReduce
执行的集合名map
映射函数reduce
规约函数out
输出的集合名
- 值为
{ inline : 1}
会直接输出结果而不是放到集合中。但是输出长度根据 MongoDB 的版本是有限制的。
- 值为