mongodb中group分组场景应用

mongodb中数据集合(ABC123)包含的指标进行统计分析,指标(指标在mongodb中实际以字母、数字组合的编码表示)包括:

A1:用户标识、A2:用户编码、A3:用户名称、A4:地市、A5:区县、A6:手机号码、A7:账期、A8:入网时间、A9:ARPU值

 

需地市、区县分组统计的指标(统计指标的结果标识编码可自定义):

X1:用户数、X2:总ARPU值、X3:平均用户入网时间

即需要统计分析:

用户数:      count(用户编码)

总ARPU值:     sum(ARPU值)

平均入网时间:sum(入网时间)/count(用户编码)

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

mongodb  Java  api   mongo-2.7.3.jar

mongodb group 分组函数使用:

BasicDBList basicDBList = (BasicDBList)db.getCollection("mongodb中集合编码或者编码")

                   .group(DBObject key,   --分组字段,即group by的字段

                DBObject cond,        --查询中where条件

                DBObject initial,     --初始化各字段的值

                String reduce,        --每个分组都需要执行的Function

                String finial         --终结Funciton对结果进行最终的处理

);

------------------------代码------------------------------

将分组字段、统计的结果字段、统计公式中用到的字段分别保存在HashMap中:

分组字段:

HashMap dimMap = new HashMap();

dimMap.put("A4","A4");    //地市

dimMap.put("A5","A5");    //区县

统计的结果字段:

HashMap forIdxMap = new HashMap();

dimMap.put("X1","count(A2)");            //用户数

dimMap.put("X2","sum(A9)");              //总ARPU值

dimMap.put("X3","sum(A8)/count(A2)");    //平均用户入网时间

统计公式中用到的字段:

HashMap indexMap = new HashMap();

dimMap.put("A2","A2");            //用户编码

dimMap.put("A8","A8");            //入网时间

dimMap.put("A9","A9");            //ARPU值

java调用:

BasicDBList basicDBList = (BasicDBList)db.getCollection("ABC123")

                   .group(GroupUtil.generateFormulaKeyObject(dimMap),

                       new BasicDBObject(),

                        GroupUtil.generateFormulaInitObject(indexMap),

                         GroupUtil.generateFormulaReduceObject(indexMap),

                          GroupUtil.generateFormulaFinalizeObject(forIdxMap, indexMap));

 

 

GroupUtil.java:

[java] view plain copy


print?

  1. package com.test;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Iterator;  
  5. import com.mongodb.BasicDBObject;  
  6. import com.mongodb.DBObject;  
  7.   
  8. public class GroupUtil  
  9. {  
  10.     /** 
  11.      * 方法描述:根据用户选择的维度编码和指标编码,生成Group中的key 
  12.      * @param dimMap 维度编码 
  13.      * @return key 对象 
  14.      */  
  15.     public static DBObject generateFormulaKeyObject(HashMap dimMap)  
  16.     {  
  17.         DBObject key = new BasicDBObject();  
  18.         Iterator dimIt = dimMap.keySet().iterator();  
  19.         while (dimIt.hasNext())  
  20.         {  
  21.             String dimId = (String)dimIt.next();  
  22.             key.put(dimId, true);  
  23.         }  
  24.         return key;  
  25.     }  
  26.       
  27.     /** 
  28.      * 方法描述:根据用户选择的维度编码和指标编码,生成Group中的属性初始化值 
  29.      * @param dimMap 维度编码 
  30.      * @return key 对象 
  31.      */  
  32.     public static DBObject generateFormulaInitObject(HashMap indexMap)  
  33.     {  
  34.         DBObject initial = new BasicDBObject();  
  35.         //设置计算指标中使用的指标对应的统计值:sum、count、avg、max、min  
  36.         Iterator indexIt = indexMap.keySet().iterator();  
  37.         while (indexIt.hasNext())  
  38.         {  
  39.             DBObject index = new BasicDBObject();  
  40.             index.put("count"0);  
  41.             index.put("sum"0);  
  42.             index.put("max"0);  
  43.             index.put("min"0);  
  44.             index.put("avg"0);  
  45.             index.put("self"0);  
  46.             String indexId = (String)indexIt.next();  
  47.             initial.put(indexId, index);  
  48.         }  
  49.           
  50.         return initial;  
  51.     }  
  52.       
  53.     /** 
  54.      * 方法描述:根据用户选择的指标编码,生成Group中的reduce函数 
  55.      * @param indexMap 指标编码 
  56.      * @return reduce函数 
  57.      */  
  58.     public static String generateFormulaReduceObject(HashMap indexMap)  
  59.     {  
  60.         StringBuffer reduceBuf = new StringBuffer();  
  61.           
  62.         reduceBuf.append("function(doc, prev) {");  
  63.         reduceBuf.append("var tempVal;");  
  64.         Iterator indexIt = indexMap.keySet().iterator();  
  65.         while (indexIt.hasNext())  
  66.         {  
  67.             String indexId = (String)indexIt.next();  
  68.             //计算指标数量  
  69.             reduceBuf.append("prev.").append(indexId).append(".count ++;");  
  70.             //计算指标总计  
  71.             reduceBuf.append("if(isNaN(").append("prev.").append(indexId).append(".sum").append(")){");  
  72.             reduceBuf.append("prev.").append(indexId).append(".sum = 0;");  
  73.             reduceBuf.append("}");  
  74.             reduceBuf.append("prev.").append(indexId).append(".sum += parseFloat(doc.").append(indexId).append(");");  
  75.             reduceBuf.append("if(isNaN(").append("prev.").append(indexId).append(".self").append(")){");  
  76.             reduceBuf.append("prev.").append(indexId).append(".self = 0;");  
  77.             reduceBuf.append("}");  
  78.             reduceBuf.append("prev.").append(indexId).append(".self = parseFloat(doc.").append(indexId).append(");");  
  79.               
  80.             reduceBuf.append("print(prev.").append(indexId).append(".self);");  
  81.             //计算指标最大值  
  82.             reduceBuf.append("tempVal = parseFloat(doc.").append(indexId).append(");");  
  83.             reduceBuf.append("if(").append("prev.").append(indexId).append(".max == 0").append("){");  
  84.             reduceBuf.append("prev.").append(indexId).append(".max = tempVal;");  
  85.             reduceBuf.append("}else{");  
  86.             reduceBuf.append("prev.").append(indexId).append(".max = ");  
  87.             reduceBuf.append("prev.").append(indexId).append(".max > tempVal ? ");  
  88.             reduceBuf.append("prev.").append(indexId).append(".max : tempVal;");  
  89.             reduceBuf.append("}");  
  90.             //计算指标最小值  
  91.             reduceBuf.append("if(").append("prev.").append(indexId).append(".min == 0").append("){");  
  92.             reduceBuf.append("prev.").append(indexId).append(".min = tempVal;");  
  93.             reduceBuf.append("}else{");  
  94.             reduceBuf.append("prev.").append(indexId).append(".min = ");  
  95.             reduceBuf.append("prev.").append(indexId).append(".min < tempVal ? ");  
  96.             reduceBuf.append("prev.").append(indexId).append(".min : tempVal;");  
  97.             reduceBuf.append("}");  
  98.             //计算指标的平均值  
  99.             reduceBuf.append("prev.").append(indexId).append(".avg = ");  
  100.             reduceBuf.append("prev.").append(indexId).append(".sum");  
  101.             reduceBuf.append(" / ");  
  102.             reduceBuf.append("prev.").append(indexId).append(".count;");  
  103.         }  
  104.         reduceBuf.append("}");  
  105.           
  106.         return reduceBuf.toString();  
  107.     }  
  108.       
  109.     /** 
  110.      * 方法描述:根据用户选择的指标编码,生成MapReduce中的finalize函数 
  111.      * @param indexMap 指标编码 
  112.      * @return reduce函数 
  113.      */  
  114.     public static String generateFormulaFinalizeObject(HashMap forIdxMap, HashMap indexMap)  
  115.     {  
  116.         StringBuffer reduceBuf = new StringBuffer();  
  117.         reduceBuf.append("function(doc){");  
  118.         //得到计算指标的公式运行值  
  119.         Iterator formulaIt = forIdxMap.keySet().iterator();  
  120.         while (formulaIt.hasNext())  
  121.         {  
  122.             String indexId = (String)formulaIt.next();  
  123.             String idxFormula = (String)forIdxMap.get(indexId);  
  124.             reduceBuf.append("var tempIdx, tempFormula;");  
  125.             Iterator indexItB = indexMap.keySet().iterator();  
  126.             int i = 0;  
  127.             while (indexItB.hasNext())  
  128.             {  
  129.                 String indexIdS = (String)indexItB.next();  
  130.                 if(i == 0)  
  131.                 {  
  132.                     reduceBuf.append("tempFormula = \"").append(idxFormula).append("\";");  
  133.                 }  
  134.                 reduceBuf.append("tempIdx = ").append("doc.").append(indexIdS).append(".sum;");  
  135.                 reduceBuf.append("tempFormula = ").append("tempFormula").append(".replace(/sum\\(").append(indexIdS).append("\\)/g,tempIdx);");  
  136.                 reduceBuf.append("tempIdx = ").append("doc.").append(indexIdS).append(".count;");  
  137.                 reduceBuf.append("tempFormula = ").append("tempFormula").append(".replace(/count\\(").append(indexIdS).append("\\)/g,tempIdx);");  
  138.                 reduceBuf.append("tempIdx = ").append("doc.").append(indexIdS).append(".min;");  
  139.                 reduceBuf.append("tempFormula = ").append("tempFormula").append(".replace(/min\\(").append(indexIdS).append("\\)/g,tempIdx);");  
  140.                 reduceBuf.append("tempIdx = ").append("doc.").append(indexIdS).append(".max;");  
  141.                 reduceBuf.append("tempFormula = ").append("tempFormula").append(".replace(/max\\(").append(indexIdS).append("\\)/g,tempIdx);");  
  142.                 reduceBuf.append("tempIdx = ").append("doc.").append(indexIdS).append(".avg;");  
  143.                 reduceBuf.append("tempFormula = ").append("tempFormula").append(".replace(/avg\\(").append(indexIdS).append("\\)/g,tempIdx);");  
  144.                 i++;  
  145.             }  
  146.             reduceBuf.append("var resTemp = ").append("eval(tempFormula);");  
  147.             reduceBuf.append("doc.").append(indexId).append(" = resTemp.toFixed(2);");  
  148.         }  
  149.           
  150.         Iterator indexItC = indexMap.keySet().iterator();  
  151.         while (indexItC.hasNext())  
  152.         {  
  153.             String indexId = (String)indexItC.next();  
  154.             reduceBuf.append("doc.").append(indexId).append(" = doc.").append(indexId).append(".self;");  
  155.         }  
  156.         reduceBuf.append("}");  
  157.           
  158.         return reduceBuf.toString();  
  159.     }  
  160. }  

 

注:group限制:分组后的组数不得超过20000个组!

你可能感兴趣的:(MongoDB)