MongoDB文档翻译-执行增量Map Reduce

英文原文地址:https://docs.mongodb.com/v3.2/tutorial/perform-incremental-map-reduce/
本文章属个人翻译,作个人学习之用,如有雷同,纯属巧合。如有错误之处,欢迎指正。

执行增量Map-Reduce

Map-reduce操作可以处理复杂的聚集任务。MongoDB对聚集操作提供了mapReduce命令,在mongoshell中提供了db.collection.mapReduce()方法。

如果map-reduce要处理的数据经常增加,你有可能需要执行增量map-reduce,而不是每次在整个数据集上执行map-reduce操作。

要执行增量map-reduce:

  1. 对当前集合运行map-reduce作业,然后把结果输出到另一个集合。
  2. 当有更多的数据需要处理时,用以下方法运行后面的map-reduce:
    • query参数来指定条件,只匹配新文档。
    • out参数来指定reduce操作,把新结果合并至已存在的输出集合中。

考虑以下例子,在每天结束时定时在sessions集合上执行map-reduce操作。

数据集

sessions集合包含了记录每日用户会话的文档,如下:

db.sessions.save( { userid: "a", ts: ISODate('2011-11-03 14:17:00'), length: 95 } );
db.sessions.save( { userid: "b", ts: ISODate('2011-11-03 14:23:00'), length: 110 } );
db.sessions.save( { userid: "c", ts: ISODate('2011-11-03 15:02:00'), length: 120 } );
db.sessions.save( { userid: "d", ts: ISODate('2011-11-03 16:45:00'), length: 45 } );

db.sessions.save( { userid: "a", ts: ISODate('2011-11-04 11:05:00'), length: 105 } );
db.sessions.save( { userid: "b", ts: ISODate('2011-11-04 13:14:00'), length: 120 } );
db.sessions.save( { userid: "c", ts: ISODate('2011-11-04 17:00:00'), length: 130 } );
db.sessions.save( { userid: "d", ts: ISODate('2011-11-04 15:37:00'), length: 65 } );

当前集合的首次Map-Reduce

按如下运行第一次map-reduce操作:

  1. 定义一个map函数,把userid映射到包含userid,total_time,count和avg_time字段的对象:

    var mapFunction = function() {
          var key = this.userid;
          var value = {
            userid: this.userid,
            total_time: this.length,
            count: 1,
            avg_time: 0
          };
    
          emit( key, value );
    };
  2. 定义相应的reduce函数,它有两个参数:key和values,以计算总时间和总数。key对应的是userid,values是一个数组,其元素对应的是mapFunction中映射到userid的各个对象。

    var reduceFunction = function(key, values) {
    
         var reducedObject = {
              userid: key,
              total_time: 0,
              count:0,
              avg_time:0
            };
    
            values.forEach( function(value) {
              reducedObject.total_time += value.total_time;
              reducedObject.count += value.count;
            });
            return reducedObject;
    };
  3. 定义一个有两个参数:key和reducedValue 的终止函数。该函数修改reducedValue文档,添加了一个average字段,并返回修改后的文档。

    var finalizeFunction = function (key, reducedValue) {
    
           if (reducedValue.count > 0)
                reducedValue.avg_time = reducedValue.total_time / reducedValue.count;
               return reducedValue;
    };
  4. mapFunctionreduceFunctionfinalizeFunctionsessions集合执行map-reduce操作。把结果输出至session_stat集合。如果该集合已经存在,该操作将会把它的内容替换掉:

    db.sessions.mapReduce( mapFunction,
                           reduceFunction,
                           {
                             out: "session_stat",
                             finalize: finalizeFunction
                           }
                         )

    后续的增量Map-Reduce

    之后,随着sessions集合的增长,你可以运行附加的map-reduce操作。例如,添加一些新文档到sessions集合中:

    db.sessions.save( { userid: "a", ts: ISODate('2011-11-05 14:17:00'), length: 100 } );
    db.sessions.save( { userid: "b", ts: ISODate('2011-11-05 14:23:00'), length: 115 } );
    db.sessions.save( { userid: "c", ts: ISODate('2011-11-05 15:02:00'), length: 125 } );
    db.sessions.save( { userid: "d", ts: ISODate('2011-11-05 16:45:00'), length: 55 } );

    在每天结束时,在sessions集合上执行增量map-reduce,要用query字段来只选出新文档。把结果输出至session_stat集合,把该集合的内容与增量map-reduce的结果再reduce:

    db.sessions.mapReduce( mapFunction,
                           reduceFunction,
                           {
                             query: { ts: { $gt: ISODate('2011-11-05 00:00:00') } },
                             out: { reduce: "session_stat" },
                             finalize: finalizeFunction
                           }
                         );

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值