首页 > 代码库 > 第二部分 应用篇 第七章 MongoDB MapReduce

第二部分 应用篇 第七章 MongoDB MapReduce

1、简介

MongoDB的MapReduce相当于MySQL中的group by,所以在MongoDB上使用Map/Reduce进行统计很容易,使用MapReduce要实现两个函数Map函数和Reduce函数,Map函数调用emit(key,value),遍历collection中所有的记录,将key与value传递给Reduce函数进行处理,Map函数和Reduce函数可以使用JavaScript来实现,可以通过db.runCommand或者mapReduce命令来执行一个MapReduce的操作:

db.runCommand(

{mapreduce:<collection>,

map:<mapfunction>,

reduce:<reducefunction>

[,query:<query filter object>]

[,sort:<sorts the input objects using this key,Useful for optimization,like sorting by the emit key for fewer reduces>]

[,limit:<number of objects to return from collection>]

[,out:<see output options below>]

[,keeptemp:<true|false>]

[,finalize:<finalizefunction>]

[,scope:<object where fields go into javascript global scope>]

[,verbose:true]

}

)

参数说明:

  • mapreduce:要操作的目标集合。
  • map:映射函数(生成键值对序列,作为reduce函数参数)。
  • reduce:统计函数。
  • query:目标记录过滤。
  • sort:目录记录排序。
  • limit:限制目标记录数量。
  • out:统计结果存放集合(不指定则使用临时集合,在客户端断开后自动删除)。
  • keeptemp:是否保留临时集合。
  • finalize:最终处理函数(对reduce返回结果进行最终整理后存入结果集合)。
  • scope:向map、reduce、finalze导入外部变量。
  • verbose:显示详细的时间统计信息。

2、Map
下面我们准备一些数据:
> db.students.insert({classid:1,name:‘Tom‘,age:15});
WriteResult({ "nInserted" : 1 })
> db.students.insert({classid:1,name:‘Jack‘,age:12});
WriteResult({ "nInserted" : 1 })
> db.students.insert({classid:2,name:‘Lily‘,age:16});
WriteResult({ "nInserted" : 1 })
> db.students.insert({classid:2,name:‘Tony‘,age:9});
WriteResult({ "nInserted" : 1 })
> db.students.insert({classid:2,name:‘Harry‘,age:19});
WriteResult({ "nInserted" : 1 })
> db.students.insert({classid:2,name:‘Vincent‘,age:13});
WriteResult({ "nInserted" : 1 })
> db.students.insert({classid:1,name:‘Bill‘,age:15});
WriteResult({ "nInserted" : 1 })
> db.students.insert({classid:2,name:‘Bruce‘,age:17});
WriteResult({ "nInserted" : 1 })
接下来我们演示如何统计1班和2班的学生数量
Map函数必须调用emit(key,value)返回键值对,使用this访问当前待处理的Document。
> m=function(){emit(this.classid,1)}
function (){emit(this.classid,1)}
value可以使用JSONObject传递(支持多个属性值),比如:
emit(this.classid,{count:1})

3、Reduce
Reduce函数接收的参数类似与Group效果,将Map返回的键值序列组合成{key,[value1,value2,value3....]}传递给reduce。
> r=function(key,values){var x=0;values.forEach(function(v){x+=v});return x;}
function (key,values){var x=0;values.forEach(function(v){x+=v});return x;}

Reduce函数对这些values进行统计操作,返回结果可以使用JSONObject。

4、Result
> res=db.runCommand({mapreduce:"students",map:m,reduce:r,out:"students_res"});
{
        "result" : "students_res",
        "timeMillis" : 1206,
        "counts" : {
                "input" : 8,
                "emit" : 8,
                "reduce" : 2,
                "output" : 2
        },
        "ok" : 1
}
查看统计结果
> db.students_res.find()
{ "_id" : 1, "value" : 3 }
{ "_id" : 2, "value" : 5 }
mapReduce()将结果存储在students_res表中。

4、finalize
利用finalize()可以对reduce()的结果做进一步的处理。
> f=function(key,value){return{classid:key,count:value};}
function (key,value){return{classid:key,count:value};}
我们再计算一次,看看返回结果:
>  res=db.runCommand({mapreduce:"students",map:m,reduce:r,out:"students_res",finalize:f});
{
        "result" : "students_res",
        "timeMillis" : 243,
        "counts" : {
                "input" : 8,
                "emit" : 8,
                "reduce" : 2,
                "output" : 2
        },
        "ok" : 1
}
> db.students_res.find();
{ "_id" : 1, "value" : { "classid" : 1, "count" : 3 } }
{ "_id" : 2, "value" : { "classid" : 2, "count" : 5 } }
列名变与classid和count了,这样的列表更容易理解。

5、options
我们还可以添加更多的控制细节。
> res=db.runCommand({mapreduce:"students",map:m,reduce:r,out:"students_res",finalize:f,query:{age:{$lt:10}}});
{
        "result" : "students_res",
        "timeMillis" : 16,
        "counts" : {
                "input" : 1,
                "emit" : 1,
                "reduce" : 0,
                "output" : 1
        },
        "ok" : 1
}
> db.students_res.find();
{ "_id" : 2, "value" : { "classid" : 2, "count" : 1 } }
可以看到先进行了过滤,只取age<10的数据,然后再进行统计,所以没有1班的统计数据。
-----------------------------------------MongoDB文章更新----------------------------------------------------------

第一部分 基础篇 第一章 走进MongoDB

第一部分 基础篇 第二章 安装MongoDB

第一部分 基础篇 第三章 MongoDB体系结构

第一部分 基础篇 第四章 MongoDB快速入门

第一部分 基础篇 第四章 MongoDB查询

第二部分 应用篇 第五章 MongoDB高级查询

第二部分 应用篇 第六章 MongoDB GridFS







第二部分 应用篇 第七章 MongoDB MapReduce