Mongodb(mapreduce)

在不是分布式的环境,为什么要使用mapreduce

因为mongodb的聚合查询结果不能超过16m

因为mongodb的group有20000的限制

所以只有使用mapreduce才能避免这些

 

 

-----------------------------------------------------------------------

【参考如下】

http://cn.docs.mongodb.org/manual/core/map-reduce/
http://my.oschina.net/huzorro/blog/73879?p=1#rpl_273686466

 

 

【详细解析】

文档结构如下:
Spcode
Spname
Consignid
Consname
Region
Regionname
Serviceid
Servicename
Srctermid

要实现任意字段的组合, 分组,  对Srctermid做去重操作。
Mysql:
SELECT Spcode, Spname, Consignid, Consname, COUNT(DISTINCT(Srctermid))  FROM mt_log_201208 GROUP BY Spcode, Spname, Consignid, Consname
Where Logtime<20120821 and Logtime>20120801;


mongodb的mapreduce操作
res = db.runCommand({
 mapreduce:'mo_log_201208',        【查询的集合】
 query:{Logtime:{$gte:'20120801', $lte:'20120821'}},  【查询条件】
 map:function() {                   【处理的数据源】
  emit({Spcode:this.Spcode, Spname:this.Spname,
  Consignid:this.Consignid, Consname:this.Consname},  [参数一:要分组的字段]
  {"data":[{"Srctermid":this.Srctermid}]});           [参数二:分组后,自定义要处理的每个组的数据数组[单个组的所有Srctermid的值[1,23,455,66...]],传给reduce的value处理的数据]
 },
 reduce:function(key, value) {      【处理函数:value就是map传过来的,返回的就是返回集合的值】
  var ret = {data:[]};
  var srctermid = {};
  for(var i in value) {
   var ia = value[i];   
   for(var j in ia.data) {
    if(!srctermid[ia.data[j].Srctermid]) {
     srctermid[ia.data[j].Srctermid] = true;
     ret.data.push(ia.data[j]);
    }
   }
  }
        return ret;
 },
 finalize:function(key, values){   【对返回值封装后,传给结果】
  return {count:values.data.length};
 },
 out:'tmp_mo_spcode_consignid_1',
 verbose:true
})

 

 

 

【java】
      
  String mapfun = "function() {" +"emit(this.platCode,{count:1})}";
  String reducefun = "function(key, value) {" +
     "var ret = {count:0};" +
     "for(var i in value) {" +
     "ret.count += value[i].count;" +
     "}" +
     "return ret;" +
     "}";
      System.out.println(MongodbUtil.getHourLogPhoneCollection().mapReduce(mapfun, reducefun, "relt2", new BasicDBObject()));
     
     
【java】
  String mapfun = "function() {" +"emit({chCode:this.chCode,platCode:this.platCode,optCode:this.optCode,provCode:this.provCode,retCode:this.retCode,MSISDN:this.MSISDN},{count:this.count,suc_count:this.suc_count})}";
  String reducefun = "function(key, value) {" +
     "var ret = {count:0,suc_count:0};" +
     "for(var i in value) {" +
     "ret.count += value[i].count;" +
     "ret.suc_count+= value[i].suc_count;" +
     "}" +
     "return ret;" +
     "}";
    
     讲解:
    【map】
   {chCode:this.chCode,platCode:this.platCode,optCode:this.optCode,provCode:this.provCode,retCode:this.retCode,MSISDN:this.MSISDN} | 分组里面的所有字段  like: group by chCode,platCode,optCode......

   {count:this.count,suc_count:this.suc_count,name:this.name} | group by后 单个组的所有组员组成的数组 name:this.name=》{'gt','zwj','xx','aa','77'}
   【reduce】
   value | 就是上面说的数组
   function | 对数组做处理
   return ret | 单个组最终要返回的内容
  
    

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值