MongoDB中mapReduce详

今天学习了MongoDB中的mapReduce,发现网上的资料不但不多,而且大多千篇一律,没有把mapReduce的用法说明。决定自己写一篇日志记录一下我的自己的理解。

实验数据:

先介绍一下mapReduce使用的标准格式:

db.runCommand(
  { mapreduce : 字符串,集合名,
    map : 函数,见下文
    reduce : 函数,见下文
    [, query : 文档,发往map函数前先给过渡文档]
    [, sort : 文档,发往map函数前先给文档排序]
    [, limit : 整数,发往map函数的文档数量上限]
    [, out : 字符串,统计结果保存的集合]
    [, keeptemp: 布尔值,链接关闭时临时结果集合是否保存]
    [, finalize : 函数,将reduce的结果送给这个函数,做最后的处理]
    [, scope : 文档,js代码中要用到的变量]
    [, jsMode : 布尔值,是否减少执行过程中BSON和JS的转换,默认 true ] //注:false时 BSON-->JS-->map-->BSON-->JS-->reduce-->BSON,可处理非常大的mapreduce,<br>                                    //true时BSON-->js-->map-->reduce-->BSON
    [, verbose : 布尔值,是否产生更加详细的服务器日志,默认 true ]
  }
);
可选参数我还没有仔细研究,我这里只介绍一下mapReduce的最基本用法,就只介绍这几个必选参数。

其中map和reduce是我们自己写的两个函数,这两个函数就是mapReduce的核心。简单讲mapReduce就是将数据分组,然后用分布式的方法对这几组数据分别进行处理。map函数用于分组,reduce函数用于处理分组后的数据。


map 函数:

这里有一个约定,就是要在map函数里调用emit函数,emit中文发射的意思,这里指的是根据key的值对集合进行分组,value用来定制要处理的数据。

reduce函数:

reduce函数其实是被emit函数调用的,他负责处理分组后的数据,然后返回一个结果。 这里面的value参数相当于一个数组,因为之前map之后的每一组数据都是大于等于1行的。

举个例子:

var map = function(){ emit(this.age,{age:this.age,name:this.name}); }
var reduce = function(key,value) { var result = {name:"",age:0};
 for(var i = 0; i<value.lenth; i++){
 result.name = result.name+value[i].name;
 result.age +=alue[i].age;
 }
 return result;
 }

 db.person.mapReduce(map,reduce,{"out":"collection"})

{
        "result" : "collection",
        "timeMillis" : 51,
        "counts" : {
                "input" : 7,
                "emit" : 7,
                "reduce" : 1,
                "output" : 6
        },
        "ok" : 1,
}

       result: "存放的集合名“;

       input:传入文档的个数。

       emit:此函数被调用的次数。

       reduce:此函数被调用的次数。

       output:最后返回文档的个数。



那么这个mapReduce过程的执行结果就可以在collection集合里查看了, 输入命令db.collection.find()的到如下结果:

{ "_id" : 23, "value" : { "age" : 23, "name" : "pad" } }
{ "_id" : 26, "value" : { "age" : 26, "name" : "joe" } }
{ "_id" : 29, "value" : { "age" : 29, "name" : "pork" } }
{ "_id" : 35, "value" : { "age" : 35, "name" : "padee" } }
{ "_id" : 44, "value" : { "name" : "deeddee", "age" : 88 } }
{ "_id" : 60, "value" : { "age" : 60, "name" : "jack" } }

我来讲解一下mapReduce函数执行的过程。首先是map函数被执行,这里你可以简单理解成,emit函数把person表分组,以age为关键字分组,那么根据上面的数据,数据库一共被分为了6组, 44岁共两个人。其他组都是每组一行。 这里面value是我们定制的想要处理的数据集,所以 经过map处理之后的数据集是如下形式的:

{ "_id" : 23, "value" : { "age" : 23, "name" : "pad" } }
{ "_id" : 26, "value" : { "age" : 26, "name" : "joe" } }
{ "_id" : 29, "value" : { "age" : 29, "name" : "pork" } }
{ "_id" : 35, "value" : { "age" : 35, "name" : "padee" } }
{ "_id" : 44, "value" : [{ "age":44 ,"name":"dee"},{"age":44,"name":"ddee"}] }
{ "_id" : 60, "value" : { "age" : 60, "name" : "jack" } }

这里只有第5组是大于一行的,所以很明显只有第5组调用了reduce函数, 在函数中我们让 第5组的返回结果是各行的name相连,age相加。当然这个例子是没有意义的,在此就是为了让大家理解一下mapReduce的执行过程。


参考文献:

http://docs.mongodb.org/manual/core/map-reduce/

http://docs.mongodb.org/manual/tutorial/map-reduce-examples/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值