java: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:


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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值