mongodb map reduce,mapreduce是hadoop数据处理层
本文主要介绍Mapreduce在MongoDB上的使用,类似于sql的分组和聚合。也是用map分组,然后用Reduce计数,最后可选使用finalize调整最终结果的第一步。好了,我来介绍一下,我用的版本是mongodb2.4.5,然后我也用MongoVUE(一个非常好的图形化mongodb管理工具)帮我配合。
1.原始数据。集合中有三个要使用的文档:
它们的数据格式是:
可能很多人并不关注mongodb中存储的数据格式,但是对于我来说,这是非常敏感的,我也不喜欢在后台使用object来保存这些原本清晰的类型。这里,我再多提一点。如果使用控制台插入数据,插入的数字可能会保存为双精度值。如果要保存为整数,必须使用NumberInt()和NumberLong()。例如:
在控制台上运行后你看不到数据类型,但是用MongoVUE,我可以看到:
数据库直接保存为double。并使用:
可以保存为int32,使用NumberLong()保存为Int64。
2.让MapReduce实现统计找到多少个不同名字的人。首先是map函数,然后调用reduce函数。
1功能图(){
2发射(
3 this.name
4 {计数:1}
5 );
6 }
Emit(key,value)是一个分组函数,就是用指定的键对原始单据进行分组。Value是从单据中取出的数据或者自己录入的数据,会加入到一个集合中(暂称为C集合)。MapReduce会对每个文档进行Map函数调用,但是你可以决定是否使用emit函数对这个文档进行分组,没有分组的文档就相当于被丢弃了。不过我建议不要在Map函数中加入过滤操作,比如if (xxx==yyy) emit(.);相反,您应该在MapReduce之前查询以过滤掉信息(这将在后面讨论)。可以在地图功能中执行的过滤操作通常是分类操作。比如分数高于60的以某种方式排放,分数低于60的以某种方式排放,而不是分数高于60的,否则什么都不做。
1个函数Reduce(键,值){
2 var reduced={count:0,name: };//初始化返回值
3个值. forEach(function(val) {
4 reduced . count=val . count;
5 });
6退货减少;
7 }
接下来是Reduce函数,根据上面的emit分组数据进行统计。函数的参数是key(上面emit中的key)和值(上面提到的C集)。MapReduce将对每个分组的键进行Reduce函数调用。函数的第一行是初始化需要的统计结果数据,然后是自己的统计方法,最后需要返回这个结果。
好了,让我们看看如何在DB控制台下调用这个MapReduce:
1 db . run command({ MapReduce: lekko ,
2映射:函数映射(){
3发射(
4 this.name
5 {计数:1}
6 );
7 },
8 reduce:函数reduce(键,值){
9 var reduced={count:0,name: };//初始化返回值
10个值. forEach(function(val) {
11 reduced . count=val . count;
12 });
13返回减少;
14 },
15外出:{ inline : 1 }
16 });
结果很快就出来了:
,因为我之前在控制台下又添加了两个文档,现在有四个人的名字是lekko。值得注意的是,MapReduce后这里的所有结果都会是double!
3.一些附加操作
纯MapReduce的原理很简单,关键是灵活运用。现在我给你举几个我自己经历的例子:
(1)将查询放入MapReduce。
在前面的runCommand中添加参数。比如我要查询所有男生,我就加.查询:{isman: true},
(2)结果的数据类型转换。
使用Finalize函数(该函数在Reduce函数之后调用,它将对所有键的Reduce结果执行最终操作)。比如我想在后台调用api后得到int数据而不是double数据,那么我可以添加Finalize函数:
一.
2最终确定:功能最终确定(关键,简化){
3 reduced . count=number int(reduced . count);
4退货减少;
5 },
六.
这样,减少的输出将是int32。在后台直接用强制转换就可以了,不用先从object转换成double再转换成int(用ToString再转换Prase不如强制转换)。
(3)时间类型
因为mongodb是日期类型的,但是存储时间的格式和查询时间的格式可能不一致(特别是你的mongodb是远程部署,多人协作开发的时候),会导致根据时间条件找不到数据的问题。我的建议是直接存储时间的长形式(过去的秒),那么这个差异问题就不复存在了。