您的位置:首页 > 数据库 > Mongodb

mongodb的mapreduce的分组统计

2013-08-23 11:14 471 查看
MongoDB中的Map/reduce 进行一些复合查询 , 因为mongodb不支持GROUP BY 查询, MapReduce 又类似于SQL的 GROUP BY ,所以可以认为 MapReduce 就是 mongodb 版的GROUP BY

命令如下:

db.runCommand(
{ mapreduce :
,
map :
,
reduce :
[, query : ]
[, sort : ]
[, limit : ]
[, out : ]
[, keeptemp:
]
[, finalize : ]
[, scope : ]
[, verbose : true]
}
);

mapreduce:指定要进行mapreduce处理的collection

map:map函数

reduce:reduce函数

query:一个筛选条件,只有满足条件的行才会加入mapreduce集合,而这个筛选过程是先于整个mapreduce流程而执行的

sort:和query结合的sort排序参数,这是唯一可以优化分组机制的地方

limit:同上

out:结果输出的collection的名字,不指定会默认创建一个随机名字的collection

keytemp:true或false,表明结果输出到的collection是否是临时的,如果为true,则会在客户端连接中断后自动删除,如果你用的是MongoDB的mongo客户端连接,
那必须exit后才会删除。如果是脚本执行,脚本退出或调用close会自动删除结果collection

finalize:和map,reduce一样是一个函数,它可以在reduce得出一个结果后再对key和value进行一次计算并返回一个最终结果

scope:设置参数值,在这里设置的值在map,reduce,finalize函数中可见

verbose:在执行过程中打印调试信息。

返回结果结构如下:

{ result :
,
counts : {
input :  ,
emit  : ,
output :
} ,
timeMillis : ,
ok : <1_if_ok>,
[, err : ]
}

result:储存结果的collection的名字

input:满足条件的数据行数

emit:emit调用次数,也就是所有集合中的数据总量

ouput:返回结果条数

timeMillis:执行时间,毫秒为单位

ok:是否成功,成功为1

err:如果失败,这里可以有失败原因,不过从经验上来看,原因比较模糊,作用不大
map函数   
m= function (){

emit(this.hs,
{
"customid_data":[{customid:this.customid}],
"salescountry_data":[{salescountry:this.salescountry}],
"usd_data":this.usd,
"num_data":this.num,
"compid_data":[{compid:this.compid}]
}
)

}

reduce函数:

r=function (key,values) {
var ret = {
"customid_data":[],
"salescountry_data":[],
"usd_data":0,
"num_data":0,
"compid_data":[]
};
var customid= {};
var salescountry={};
var compid={};

for(var i=0;i<values.length;i++){
var ia = values[i];
for(var j in ia.customid_data){
if(!customid[ia.customid_data[j].customid]){
customid[ia.customid_data[j].customid]=true;
ret.customid_data.push(ia.customid_data[j]);
}
}
for(var j in ia.salescountry_data){
if(!salescountry[ia.salescountry_data[j].salescountry]){
salescountry[ia.salescountry_data[j].salescountry]=true;
ret.salescountry_data.push(ia.salescountry_data[j]);
}
}
for(var j in ia.compid_data){
if(!compid[ia.compid_data[j].compid]){
compid[ia.compid_data[j].compid]=true;
ret.compid_data.push(ia.compid_data[j]);
}
}
ret.usd_data+=values[i].usd_data;
ret.num_data+=values[i].num_data;
}

return ret;

}
finalize函数:  
f=function (key, values){
return

{

custom:values.customid_data.length,

salescountry:values.salescountry_data.length,

usd_sum:values.usd_data,

num_sum:values.num_data,

comp:values.compid_data.length

};
}
   执行mapReduce函数         
db.collect.mapReduce(m,r,{out:'groupbyhs',query:{isimp:'1'},keytemp:false,finalize:f})

如果想使用sort和limit等功能,可以使用 res.find().sort({"value.totalNum":-1}).limit(2)来达到目的

需要注意的是:Reduce函数的返回值也需要和Reduce函数的第二个参数结构一致。

参考文章:

关于mongodb中使用MapReduce的几点实践经验
http://www.l99.com/EditText_view.action?textId=461413
如果想使用sort和limit等功能,可以使用 res.find().sort({"value.totalNum":-1}).limit(2)来达到目的(说的好)

用MongoDB实现MapReduce
http://www.open-open.com/lib/view/open1329107420952.html
Mongodb MapReduce编程模型
http://chenzhou123520.iteye.com/blog/1637672
MongoDB MapReduce(转)
http://javabeezer.iteye.com/blog/1275124
所以Reduce函数的返回值也需要和Reduce函数的第二个参数结构一致(这句话说的非常好啊!)

[转]MongoDB MapReduce 用法及介绍  
http://blog.163.com/sjy_814/blog/static/77801164201282531137196/
MongoDB 分组, 去重*******************************
http://my.oschina.net/huzorro/blog/73879
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息