如果你已经搜索到了这个页面,那我很不幸的告诉你,java mongodb的查询不仅慢,而且很繁琐,你的噩梦才刚刚开始。
先简单地介绍下,我要实现的功能。
本人一直在做网站运维这块,在统计网站数据的过程中,需要计算PV、UV,时间单位是一天,很自然就需要用到条件查询,查询一天的情况。
先看PV,查询某日总的页面访问量,面向页面计算。
/**
* 查询某日PV量(总的页面访问量,面向页面)
* @param date
* @return PV量
*/
public static int getPV(String strDate){
BasicDBObject query = new BasicDBObject();
int PV = 0;
String condition = Condition.getTimeCond(strDate);
query.put("$where",condition);
dbCol = init();
DBCursor cursor = dbCol.find(query);
while (cursor.hasNext()) {
System.out.println(cursor.next());;
}
PV = cursor.count();
return PV;
}
再看UV,我以cookie中的UUID为标准,作为独立访客,00:00-24:00内相同的客户端只会被计算一次。
/**
* UV(独立访客数)00:00-24:00内相同的客户端只会被计算一次
* @param strDate
* @return UV量
*/
public static int getUV(String strDate){
BasicDBObject query = new BasicDBObject();
int UV = 0;
dbCol = init();
String condition = Condition.getTimeCond(strDate);
query.put("$where",condition);
//根据uuid去重,查询
UV = dbCol.distinct("uuid",query).size();
return UV;
}
如果你想偷懒,直接cope过去使用,肯定会报错的,呵呵呵!
我来稍带讲一下:
两个函数中的参数strDate,是你查询的日期,比如“2014-04-11”;
dbCol,是获取的集合对象,也就是DBCollection,这里不废话了,不知道的可以留言;
query,大家注意这个对象,它是用来临时条件查询中的条件,如果多个条件,也可以这样:
条件列表:
BasicDBList condList = new BasicDBList();
//年龄大于1小于100
BasicDBObject cond1= new BasicDBObject();
cond1.append("age",new BasicDBObject("$gt",1));
cond1.append("age",new BasicDBObject("$lte",100));
//性别为女
BasicDBObject cond2= new BasicDBObject();
cond2.append("sex","女");
//将两个条件加入到条件集合中(多条件)
condList.add(cond1);
condList.add(cond2);
BasicDBObject cond= new BasicDBObject();
cond.put("$and", condList);
然后查询数据:
DBCursor cursor= coll.find(cond);
condition,大家可能注意到了,这个对象是关键,标准的where条件从句,现在我将方法展示如下:
/**
* 条件查询时间条件
* @param strDate
* @return
*/
public static String getTimeCond(String strDate){
long mintime = DataFormat.stringToMills(strDate);
long maxtime = mintime+86400000;
return "function(){"
+"var init = this.initTime.replace(new RegExp('-','gm'),'/'); "
+"var initMills = (new Date(init)).getTime();"
+"return initMills>"+mintime+"&&initMills<"+maxtime+";}" ;
}
}
我将where条件用一个javascript函数返回,为什么可以这样呢,因为JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包,而mongodb存的就是类json数据(bson)。
还有在这里,我是把时间转换为了毫秒进行大小比较的!
最后一点,distinct函数,对就是sqlserver中的去重,很好用。
另外,讲讲分组。
先上代码:
//返回条件查询的游标
DBCursor cursor = dbCol.find(query);
List
不知道大家有没有用过guava,谷歌自创的map,很好用的。
官网:https://code.google.com/p/guava-libraries/
开源社区也有部分中文资料可供参考:http://www.oschina.net/question/tag/guava
uuid是本人在mongodb中一个字段名。
简单讲一下思路:先将条件查询获取的游标(只是指针)的结果遍历出来,然后放入一个List中,最后把list放入谷歌的Multimap中,就会返回分组后的结果(DEMO中from.get("uuid")是以“uuid”来分组的),当然也可以多次分组,一层一层分,事实上,本人就用了三次分组,原理一样。
欢迎大家留言!