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?
- package com.test;
-
- import java.util.HashMap;
- import java.util.Iterator;
- import com.mongodb.BasicDBObject;
- import com.mongodb.DBObject;
-
- public class GroupUtil
- {
- /**
- * 方法描述:根据用户选择的维度编码和指标编码,生成Group中的key
- * @param dimMap 维度编码
- * @return key 对象
- */
- public static DBObject generateFormulaKeyObject(HashMap dimMap)
- {
- DBObject key = new BasicDBObject();
- Iterator dimIt = dimMap.keySet().iterator();
- while (dimIt.hasNext())
- {
- String dimId = (String)dimIt.next();
- key.put(dimId, true);
- }
- return key;
- }
-
- /**
- * 方法描述:根据用户选择的维度编码和指标编码,生成Group中的属性初始化值
- * @param dimMap 维度编码
- * @return key 对象
- */
- public static DBObject generateFormulaInitObject(HashMap indexMap)
- {
- DBObject initial = new BasicDBObject();
- //设置计算指标中使用的指标对应的统计值:sum、count、avg、max、min
- Iterator indexIt = indexMap.keySet().iterator();
- while (indexIt.hasNext())
- {
- DBObject index = new BasicDBObject();
- index.put("count", 0);
- index.put("sum", 0);
- index.put("max", 0);
- index.put("min", 0);
- index.put("avg", 0);
- index.put("self", 0);
- String indexId = (String)indexIt.next();
- initial.put(indexId, index);
- }
-
- return initial;
- }
-
- /**
- * 方法描述:根据用户选择的指标编码,生成Group中的reduce函数
- * @param indexMap 指标编码
- * @return reduce函数
- */
- public static String generateFormulaReduceObject(HashMap indexMap)
- {
- StringBuffer reduceBuf = new StringBuffer();
-
- reduceBuf.append("function(doc, prev) {");
- reduceBuf.append("var tempVal;");
- Iterator indexIt = indexMap.keySet().iterator();
- while (indexIt.hasNext())
- {
- String indexId = (String)indexIt.next();
- //计算指标数量
- reduceBuf.append("prev.").append(indexId).append(".count ++;");
- //计算指标总计
- reduceBuf.append("if(isNaN(").append("prev.").append(indexId).append(".sum").append(")){");
- reduceBuf.append("prev.").append(indexId).append(".sum = 0;");
- reduceBuf.append("}");
- reduceBuf.append("prev.").append(indexId).append(".sum += parseFloat(doc.").append(indexId).append(");");
- reduceBuf.append("if(isNaN(").append("prev.").append(indexId).append(".self").append(")){");
- reduceBuf.append("prev.").append(indexId).append(".self = 0;");
- reduceBuf.append("}");
- reduceBuf.append("prev.").append(indexId).append(".self = parseFloat(doc.").append(indexId).append(");");
-
- reduceBuf.append("print(prev.").append(indexId).append(".self);");
- //计算指标最大值
- reduceBuf.append("tempVal = parseFloat(doc.").append(indexId).append(");");
- reduceBuf.append("if(").append("prev.").append(indexId).append(".max == 0").append("){");
- reduceBuf.append("prev.").append(indexId).append(".max = tempVal;");
- reduceBuf.append("}else{");
- reduceBuf.append("prev.").append(indexId).append(".max = ");
- reduceBuf.append("prev.").append(indexId).append(".max > tempVal ? ");
- reduceBuf.append("prev.").append(indexId).append(".max : tempVal;");
- reduceBuf.append("}");
- //计算指标最小值
- reduceBuf.append("if(").append("prev.").append(indexId).append(".min == 0").append("){");
- reduceBuf.append("prev.").append(indexId).append(".min = tempVal;");
- reduceBuf.append("}else{");
- reduceBuf.append("prev.").append(indexId).append(".min = ");
- reduceBuf.append("prev.").append(indexId).append(".min < tempVal ? ");
- reduceBuf.append("prev.").append(indexId).append(".min : tempVal;");
- reduceBuf.append("}");
- //计算指标的平均值
- reduceBuf.append("prev.").append(indexId).append(".avg = ");
- reduceBuf.append("prev.").append(indexId).append(".sum");
- reduceBuf.append(" / ");
- reduceBuf.append("prev.").append(indexId).append(".count;");
- }
- reduceBuf.append("}");
-
- return reduceBuf.toString();
- }
-
- /**
- * 方法描述:根据用户选择的指标编码,生成MapReduce中的finalize函数
- * @param indexMap 指标编码
- * @return reduce函数
- */
- public static String generateFormulaFinalizeObject(HashMap forIdxMap, HashMap indexMap)
- {
- StringBuffer reduceBuf = new StringBuffer();
- reduceBuf.append("function(doc){");
- //得到计算指标的公式运行值
- Iterator formulaIt = forIdxMap.keySet().iterator();
- while (formulaIt.hasNext())
- {
- String indexId = (String)formulaIt.next();
- String idxFormula = (String)forIdxMap.get(indexId);
- reduceBuf.append("var tempIdx, tempFormula;");
- Iterator indexItB = indexMap.keySet().iterator();
- int i = 0;
- while (indexItB.hasNext())
- {
- String indexIdS = (String)indexItB.next();
- if(i == 0)
- {
- reduceBuf.append("tempFormula = \"").append(idxFormula).append("\";");
- }
- reduceBuf.append("tempIdx = ").append("doc.").append(indexIdS).append(".sum;");
- reduceBuf.append("tempFormula = ").append("tempFormula").append(".replace(/sum\\(").append(indexIdS).append("\\)/g,tempIdx);");
- reduceBuf.append("tempIdx = ").append("doc.").append(indexIdS).append(".count;");
- reduceBuf.append("tempFormula = ").append("tempFormula").append(".replace(/count\\(").append(indexIdS).append("\\)/g,tempIdx);");
- reduceBuf.append("tempIdx = ").append("doc.").append(indexIdS).append(".min;");
- reduceBuf.append("tempFormula = ").append("tempFormula").append(".replace(/min\\(").append(indexIdS).append("\\)/g,tempIdx);");
- reduceBuf.append("tempIdx = ").append("doc.").append(indexIdS).append(".max;");
- reduceBuf.append("tempFormula = ").append("tempFormula").append(".replace(/max\\(").append(indexIdS).append("\\)/g,tempIdx);");
- reduceBuf.append("tempIdx = ").append("doc.").append(indexIdS).append(".avg;");
- reduceBuf.append("tempFormula = ").append("tempFormula").append(".replace(/avg\\(").append(indexIdS).append("\\)/g,tempIdx);");
- i++;
- }
- reduceBuf.append("var resTemp = ").append("eval(tempFormula);");
- reduceBuf.append("doc.").append(indexId).append(" = resTemp.toFixed(2);");
- }
-
- Iterator indexItC = indexMap.keySet().iterator();
- while (indexItC.hasNext())
- {
- String indexId = (String)indexItC.next();
- reduceBuf.append("doc.").append(indexId).append(" = doc.").append(indexId).append(".self;");
- }
- reduceBuf.append("}");
-
- return reduceBuf.toString();
- }
- }
注:group限制:分组后的组数不得超过20000个组!