MongoDB MapReduce分组后的每一组数据如果大于100,那么他每次会取100条,归并完变成1条又返回给emit里面作为输入,继续判断余数是否大于100,大于100,取100条,周而复始,直到最后一次取数不大于100,运算完成后就结束。
需要特别说明的是,如果最后一次虽然不大于100,但是如果是1的话,那么不好意思,他直接就给到finalize了,跳过reduce函数。
原理剖析:
下面给出两个相同业务的运算逻辑。
第一种:注意costTime += (val.endTime - val.beginTime)+val.costTime;
var m = function(){ emit(this.url,{count:1,beginTime:this.rt,endTime:this.rpt,costTime:0}) } var r =function(key,values){ var cnt=0; var costTime = 0; var obj; values.forEach(function(val){ if(val.endTime != null && val.beginTime != null){ cnt += val.count; costTime += (val.endTime - val.beginTime)+val.costTime; } }) return {"count":cnt,beginTime:0,endTime:0,"costTime":costTime}; } var f =function (key,reduceResult){ //reduceResult.price =(reduceResult.beginTime).toFixed(2); if(reduceResult.count != 0 ){ reduceResult.avgCost =(reduceResult.costTime/reduceResult.count).toFixed(2); } return reduceResult; } //"url":{"$in":["/agent-fx-web/area/findManageAreas.do","/agent-fx-web/api/distributor/expectCommission.do"]}, var q = {"rt":{"$gt":ISODate("2017-10-10 07:00:25"),"$lt":ISODate("2017-10-10 07:30:25")}} db.runCommand({ mapreduce:"traceIndex", map:m, reduce:r, query:q, finalize:f, out:{merge:"test_map_reduce_4"} } )
第二种:注意totalCount += val.totalCount;
var m = function(){ emit(this.url,{"costTime":(this.rpt&&this.rt)?(this.rpt - this.rt):0,"totalCount":1}) } var r =function(key,values){ var totalCostTime = 0; var totalCount = 0; values.forEach(function(val){ //if(val.costTime > 0){ totalCount += val.totalCount; totalCostTime += val.costTime; //} //console.log(val); }) var result = {"costTime":totalCostTime,"totalCount":totalCount}; print(result); return result; } var f =function (key,reduceResult){ //reduceResult.price =(reduceResult.beginTime).toFixed(2); if(reduceResult.count != 0 ){ reduceResult.avgCost =(reduceResult.costTime/reduceResult.totalCount).toFixed(2); } // db.getCollection("test_map_reduce_5").update({ca:key},result,{upsert:true}); return reduceResult; } //"url":{"$in":["/agent-fx-web/area/findManageAreas.do","/agent-fx-web/api/distributor/expectCommission.do"]}, var q = {"rt":{"$gt":ISODate("2017-10-10 07:00:25"),"$lt":ISODate("2017-10-10 07:30:25")}} db.runCommand({ mapreduce:"traceIndex", map:m, reduce:r, query:q, finalize:f, out:{merge:"test_map_reduce_4"} } )