mongodb11天之屠龙宝刀(六)mapreduce:mongodb中mapreduce原理与操作案例
原文连接:直通车
MapReduce 是Google公司的核心模型,用于大规模数据集(大于1TB)的并行计算。“映射(Map)”与“化简(Reduce)”的概念是它们的主要思想。MapReduce使用JavaScript作为“查询语言”,能够在多台服务器之间并行执行。MapReduce将负责的运行于大规模集群上的并行计算过程高度地抽象为两个函数(Map和Reduce),利用一个输入<key,value>集合来产生一个输出地<key,value>对集合。MapReduce在执行时先指定一个Map(映射)函数,把输入<key,value>对映射成一组新的<key,value>对,经过一定处理后交给 Reduce,Reduce对相同key下的所有value处理后再输出<key,value>对作为最终的结果。
二 Map/Reduce过程
MongoDB中的Map/Reduce对于批量处理数据进行聚合操作是非常有用的。在思想上它跟Hadoop一样,从一个单一集合中输入数据,然后将结果输出到一个集合中。通常在使用类似SQL中Group By操作时,Map/Reduce会是一个好的工具。
a.在orders集合上进行MapReduce操作,首先使用query进行“过滤”操作,选择出 status为’A’的所有文档。
b.在选择后的每个文档上执行map操作,在map操作的时候将当前文档的this.cust\_id,this.amount分别作为键值发射出去,经过map操作后,相同键的文档的值被放到一起组成一个数组。
c.如果一个键有多个值的话,进行reduce的操作,在进行reduce 操作的时候将所有的值进行累加
如果一个健只有一个值的话就直接输出到结果集合
d.Reduce完后将结果输出到预先定义好的结果集合中,即order\_totals集合。
在mongodb中,mapreduce除了包含mapper和reducer之外,还包含其他的一些选项,不过整体遵循mapreduce的规则:
db.table.mapReduce(
map,
reduce,
{
query: query,
out: out, #指定结果集存储,可选参数包括四个
sort: sort,
limit: limit,
finalize: function
scope: document, //设置参数值,在这里设置的值在map,reduce,finalize函数中可见
jsMode:boolean
verbose:boolean //是否产生详细的服务器日志,默认true
keytemp:boolean
}
)
必备参数:map,reduce, out,
详解:
**map:** function() {emit(this.cat_id,this.goods_number); }, // 函数内部要调用内置的emit函数,cat_id代表根据cat_id来进行分组,goods_number代表把文档中的goods_number字段映射到cat_id分组上的数据,其中this是指向向前的文档的,这里的第二个参数可以是一个对象,如果是一个对象的话,也是作为数组的元素压进数组里面;
**reduce:** function(cat_id,all_goods_number) {return Array.sum(all_goods_number)}, // cat_id代表着cat_id当前的这一组,all_goods_number代表当前这一组的goods_number集合,这部分返回的就是结果中的value值;
**out:** <output>, // 输出到某一个集合中,注意本属性来还支持如果输出的集合如果已经存在了,那是替换,合并还是继续reduce? 另外还支持输出到其他db的分片中,具体用到时查阅文档,筛选出现的键名分别是_id和value;
finalize: function(key, reducedValue) {return modifiedObject; }, // 从reduce函数中接受的参数key与reducedValue,并且可以访问scope中设定的变量
**query:** <document>, // 一个查询表达式,是先查询出来,再进行mapReduce的
**sort:** <document>, // 发往map函数前先给文档排序
**limit:** <number>, // 发往map函数的文档数量上限,该参数貌似不能用在分片模式下的mapreduce
**finalize:** function(key, reducedValue) {return modifiedObject; }
主要用来在存入out之前可以修改数据
scope: <document>, // 指定一个全局变量,能应用于finalize和reduce函数
jsMode: <boolean>,
是否减少执行过程中BSON和JS的转换,默认true]
false时 BSON-->JS-->map-->BSON-->JS-->reduce-->BSON,可处理非常大的mapreduce,true时BSON-->js-->map-->reduce-->BSON
verbose: <boolean>
true或false,表明结果输出到的collection是否是临时的,如果为true,则会在客户端连接中断后自动删除,如果你用的是MongoDB的mongo客户端连接,那必须exit后才会删除。如果是脚本执行,脚本退出或调用close会自动删除结果collection
1、map:javascript方法,此方法中可以使用emit(key,value),一次map调用中允许返回调用多次emit(也可以不调用),它不需要返回值;其中key用来分组,value将来会被传递给reducer用于“聚合计算”。每条document都会调用一次map方法。
mapper中输入的是当前document,可以通过this.来获取字段的值。mapper应该是封闭的,它不能访问外部资源,比如collection、database,不能修改外部的值,但允许访问“scope”中的变量。emit的值不能大于16M,即document最大的尺寸,否则mongodb将会抛出错误。
// 使用传字符串的方法
单次传入:
var map = function() {
emit(this.state, this.loc);
};
多次传入
function() {
this.items.forEach(function(item) {emit(item.sku,1);});//多次emit
}
先放个别人的案例,改日整理