日期:2014-05-16 浏览次数:20575 次
参考文章
?
?
http://www.mongodb.org/display/DOCS/MapReduce
http://www.rainsts.net/article.asp?id=1044
https://github.com/mongodb/mongo-java-driver/commit/fa003adc5db8a6c4efe0279c74973af15d99e6ed#diff-2
?
?
MapReduce是一个编程模型,封装了并行计算、容错、数据分布、负载均衡等细节问题。
输入是一个key-value对的集合,中间输出也是key-value对的集合,用户使用两个函数:Map和Reduce。
?
在使用MongoDb的mapreduce功能时,我找Java代码找半天,结果练了半天的Javascript代码。
MongoDb是通过解析“Javascript”代码来计算的。所有我们先用Javascript代码调通,再使用Java代码拼接使用这个MapReduce功能。
?
?
db.runCommand( { mapreduce : <collection>, map : <mapfunction>, reduce : <reducefunction> [, query : <query filter object>] [, sort : <sort the query. useful optimization>] for [, limit : <number of objects to from collection>] return [, out : <output-collection name>] [, keeptemp: < | >] true false [, finalize : <finalizefunction>] [, scope : <object where fields go into javascript global scope >] [, verbose : ] true });
?
?
?
参数说明:
?
?
?
?
先看看我们的文档结果
?
?
?
我使用上一篇文章插入数据?http://xiaofancn.iteye.com/blog/1163200
?
讲讲我们要实现的功能,就是按照名字name统计记录个数。
?
?
?
D:\Program Files\mongodb>bin\mongo MongoDB shell version: 2.0.0 connecting to: test > use test; switched to db test > map = function() { ... emit(this.name, {count:1}); ... }; function () { emit(this.name, {count:1}); } > reduce = function(key, values) { ... var total = 0; ... var index =0; ... for(var i=0;i<values.length;i++){ ... total += values[i].count; ... index = i; ... } ... return {count:total}; ... }; function (key, values) { var total = 0; var index = 0; for (var i = 0; i < values.length; i++) { total += values[i].count; index = i; } return {count:total}; } > db.person.mapReduce(map, reduce, {out : "resultCollection"}); { "result" : "resultCollection", "timeMillis" : 112, "counts" : { "input" : 10, "emit" : 10, "reduce" : 2, "output" : 2 }, "ok" : 1, } > db.resultCollection.find(); { "_id" : "xiaofancn", "value" : { "count" : 3 } } { "_id" : "小樊", "value" : { "count" : 7 } }?
?
map = function() { emit(this.name, {count:1}); };
?? ? 此函数是形成下面的key-values结构的,emit就是指定key和value的,也是结果的数据结构。
?
xiaofancn [{count:1},{count:1},{count:1}]
?
? ? ?由于name字段为xiaofancn的person有三个,所以形成三个{count:1}数组。
?
?
?
reduce = function(key, values) { var total = 0; for(var i=0;i<values.length;i++){ total += values[i].count; } return {count:total}; };
reduce函数中参数key和map函数的emit指定的key(this.name)是同一个key(name),values就是map函数形成的values(?[{count:1},{count:1},{count:1}])
?
经过reduce函数处理就形成了key和一个最终的?{count:3}数据结构。定义好的函数,需要MongoDB执行
?
?
db.person.mapReduce(map, reduce, {out : "resultCollection"}); db.resultCollection.find();?
? db代表当前的数据库,person当前的文档,mapReduce调用函数,out:是指定输出的文档名称。
?