MongoDB的MapReduce的用法

MongoDB的MapReduce的用法

MongoDB MapReduce 相当于 Mysql 中的"group by", 所以在 MongoDB 上使用 Map/Reduce 进行并行"统计"很容易。

使用 MapReduce 要实现两个函数 Map 函数和 Reduce 函数,Map 函数调用 emit(key, value), 遍历 collection 中所有记录, key value 传递给 Reduce 函数进行处理。 函数和 Reduce Map 函数可以使用 JavaScript 来实现,可以通db.runCommand mapReduce 命令来执行一个 MapReduce 的操作。

MapReduce函数的参数列表如下

db.runCommand(
 { mapreduce : <collection>,
   map : <mapfunction>,
   reduce : <reducefunction>
   [, query : <query filter object>]
   [, sort : <sort the query.  useful for optimization>]
   [, limit : <number of objects to return from collection>]
   [, out : <output-collection name>]
   [, keeptemp: <true|false>]
   [, finalize : <finalizefunction>]
   [, scope : <object where fields go into javascript global scope >]
   [, verbose : true]
 }
);

或者这么写:

db.collection.mapReduce(
                         <map>,
                         <reduce>,
                         {
                           <out>,
                           <query>,
                           <sort>,
                           <limit>,
                           <keytemp>,
                           <finalize>,
                           <scope>,
                           <jsMode>,
                           <verbose>
                         }
                       )
  • mapreduce:指定要进行mapreduce处理的collection
  • map:map函数
  • reduce:reduce函数
  • out:输出结果的collection的名字,不指定会默认创建一个随机名字的collection(如果使用了out选项,就不必指定keeptemp:true了,因为已经隐含在其中了)
  • query:一个筛选条件,只有满足条件的文档才会调用map函数。(query。limit,sort可以随意组合)
  • sort:和limit结合的sort排序参数(也是在发往map函数前给文档排序),可以优化分组机制
  • limit:发往map函数的文档数量的上限(要是没有limit,单独使用sort的用处不大)
  • keytemp:true或false,表明结果输出到的collection是否是临时的,如果想在连接关闭后仍然保留这个集合,就要指定keeptemp为true,如果你用的是MongoDB的mongo客户端连接,那必须exit后才会删除。如果是脚本执行,脚本退出或调用close会自动删除结果collection
  • finalize:是函数,它会在执行完map、reduce后再对key和value进行一次计算并返回一个最终结果,这是处理过程的最后一步,所以finalize就是一个计算平均数,剪裁数组,清除多余信息的恰当时机
  • scope:javascript代码中要用到的变量,在这里定义的变量在map,reduce,finalize函数中可见
  • verbose:用于调试的详细输出选项,如果想看MpaReduce的运行过程,可以设置其为true。也可以print把map,reduce,finalize过程中的信息输出到服务器日志上。

其中重点的几个参数说明:

1、Map

Map 函数必须调用 emit(key, value) 返回键值对,使用 this 访问当前待处理的 Document

m = function() { emit(this.classid, 1) }

value 可以使用 JSON Object 传递 (支持多个属性值)。例如:

emit(this.classid, {count:1})

2 Reduce

Reduce 函数接收的参数类似 Group 效果,Map 返回的键值序列组合成 { key, [value1, value2, value3, value...] } 传递给 reduce

r = function(key, values) {

var x = 0;

values.forEach(function(v) { x += v });

return x;

}

3 Result

res = db.runCommand({

mapreduce:"students",

map:m,

reduce:r,

out:"students_res"

});

mapReduce() 将结果存储在 "students_res" 表中。

4 Finalize

利用 finalize() 我们可以对 reduce() 的结果做进一步处理。

f = function(key, value) { return {classid:key, count:value}; }

列名变与 “classid”和”count”,这样的列表更容易理解。

5 Options

可以添加更多的控制细节 。添加querysort等。

实例:

  • 
    public void MapReduce() {
            Mongo mongo = new Mongo("localhost",27017);
            DB db = mongo.getDB("qimiguangdb");
            DBCollection coll = db.getCollection("collection1");
           
            String map = "function() { emit(this.name, {count:1});}";
    
            String reduce = "function(key, values) {";  
            reduce=reduce+"var total = 0;";  
            reduce=reduce+"for(var i=0;i<values.length;i++){total += values[i].count;}";  
            reduce=reduce+"return {count:total};}";  
              
            String result = "resultCollection";  
              
            MapReduceOutput mapReduceOutput = coll.mapReduce(map,  
                    reduce.toString(), result, null);  
            DBCollection resultColl = mapReduceOutput.getOutputCollection();  
            DBCursor cursor= resultColl.find();  
            while (cursor.hasNext()) {  
                System.out.println(cursor.next());  
            }  
        }  
    
    
    
    
    		
  • 标签: