前面已经简单介绍了MongoDB在OECP社区的一个应用:动态消息的设计实现。在上次的应用中,我们只介绍了MongoDB最基本的查询的功能,今天我再介绍一下MongoDB更加高级的应用:用MongoDB做统计分析。
OECP社区中,我们为了更加准确的分析网站的访问情况,以便能够为用户更准确的推荐他们感兴趣的内容,我们需要将页面的访问记录存储下来。对于这些数据,主要由以下几个特点:
- 与业务无关,尽量将数据存储和业务数据分离,减少业务数据库的压力。而且对数据的一致性要求不高。
- 每当访问一个页面就要存储一条记录,实时插入操作的要求很高,当然可以使用缓存作为临时缓冲来解决数据频繁更新的问题。
- 数据随着访问量的增长膨胀的很快,如果一个页面1天有100个PageViews,将会新增100条数据,数据量远远高于业务数据,而且要比我们上次说的消息动态的数据的数量级要大得多。网站要尽量存储至少两个月的数据,当网站访问量很大的时候,要解决的是海量数据的存储。
所以从存储上考虑,我们依然选择了MongoDB作为持久存储。由于NoSQL数据库在数据查询的多样性能力太低,特别是标准的Key-Value数据库,一般的做法就是用NoSQL负责日志的存储,分析需要将数据抽取到关系数据库中再进行统计查询。但是MongoDB却提供给我们非常丰富的查询统计功能,group 和MapReduce都能实现SQL中group by,sum,count之类的统计查询分析。Group的功能已经可以实现简单的统计功能,但是当数据量非常大的时候,group处理能力就不太好了,所以我们一开始就使用MapReduce进行统计分析。
先看一下官方对MapReduce的介绍:
db.runCommand(
{ mapreduce : <collection>,
map : <mapfunction>,
reduce : <reducefunction>
[, query : <query filter object>]
[, sort : <sort the query. useful foroptimization>]
[, limit : <number of objects to returnfrom collection>]
[, out : <output-collection name>]
[, keeptemp: <true|false>]
[, finalize : <finalizefunction>]
[, scope : <object where fields go into javascript global scope >]
[, verbose : true]
}
);
而java驱动下提供的方法主要有两个:
DBCollection.mapReduce(String map, String reduce,String outputCollection,
DBObject query);
DBCollection.mapReduce(DBObject command);//该接口按照上面的介绍,总是报错,不知道此该如何应用
PV数据存储结构:(这些属性主要是为了支持我们以后根据各种维度去分析)
entityId:实体ID,
entityName:实体名称,
userid:(登录)访问者ID,
sessionId:会话ID,
referer:来源URL,
url:当前页面url,
title:显示的标题,
date:访问时间,
ip:访问者IP
第一个应用场景:当访问某用户的空间时,得到某用户最新的访问记录,同一个页面重复访问的话,返回最新的一次访问。
- 首先是map方法,主要是定义outputCollection的结构。OutputCollection的输出结构为:{_id:key,value:value}
java 代码
- String mapfun = "function(){emit({url:this.url,title:this.title},this.date)}";
java 代码
- String reducefun = "function(key,vals){var date=0; for(var i in vals){ if(date==0){date=vals[i];}else if(vals[i]>date){date=vals[i];}} return date;}";
java 代码
- DBObject query = newBasicDBObject();
-
query.put("userid", userid);
-
query.put("date", newBasicDBObject("$gte", fromDate));
-
*.getCollection().mapReduce(mapfun, reducefun,"pageview_results", query);
- 遍历pageview_results集合的结果:[{_id:{url:”/blog/yongtree/258”,title:’博客1’},value:’2010-10-11 20:30:56’},{_id:{url:”/blog/slx/288”,title:’博客2’}, value:’2010-10-01 02:23:33’}]
注意:mapfun和reducefun字符串里面是写的javascript的方法,MongoDB可以在服务器端进行js的解析。如果这个方法写的不对,程序将不能正常执行。
第二个应用场景:当访问某个具体的内容时,返回某段时间曾经浏览过这篇文章的其他人关注的其他内容,以便对当前用户有一个内容的引导。
- 首先先找出某段时间内曾经访问该内容的人作为统计的条件,我们使用sessionId而不是userid,是为了将没有登录的用户的访问算进来一起统计
java 代码
- DBObject query = newBasicDBObject();
-
query.put("entityId", entityId);
-
query.put("entityName", entityName);
-
query.put("date", newBasicDBObject("$gte", fromDate));
-
query.put("date", newBasicDBObject("$lt", toDate));
-
List sessionIds = this.mongoService.getCollection().distinct("sessionId", query);
- 定义map方法,主要是定义outputCollection的结构。OutputCollection的输出结构为:{_id:key,value:次数浏览的次数}
java 代码
- String mapfun = " function(){emit({url:this.url,title:this.title},1)}";
java 代码
- String reducefun = " function(key,vals){var count=0; for(var i in vals){count+=vals[i];} return count;}";
java 代码
- *.getCollection().mapReduce(mapfun, reducefun,"pageview_results", new BasicDBObject("sessionId",new BasicDBObject("$in",sessionIds.toArray())));
- 遍历pageview_results集合的结果:[{_id:{url:”/blog/yongtree/258”,title:’博客1’},value:’45.0’},{_id:{url:”/blog/slx/288”,title:’博客2’}, value:’30.0’}]
前台展现的效果:
继续关注OECP社区,我们将会实践和发布更多基于MongoDB的应用。本着共享的精神,该文档可以被转载和应用,但是要注明出处。
作者主页:http://www.po-soft.com/hi/yongtree
分享到:
相关推荐
Cube 是一个开源的基于 MongoDB 的数据分析工具 Cube 的收集器接收事件并将这些事件保持在 MongoDB 中。你可通过 UDP、HTTP POST 或者 WebSockets 来发送事件。同时 Cube 内置支持接受来自 collectd 的事件。
mongodb mapreduce 实例,该例子主要用来做订单统计的。具体问题请到博客提问。
本系统是本人初学MongoDb时所写,代码不是很完美,基本实现图书管理系统的增删改查等基本功能,目前尚有一处缺陷未解决——在查询后只能在控制台看到结果,没有反馈到界面上,有兴趣的朋友可以加以修改,相信这是一...
计算机后端-PHP视频教程. mongodb10 MapReduce 统计栏目下的商品.wmv
NULL 博文链接:https://superhuo.iteye.com/blog/1193485
MongoDB MapReduce MapReduce是一种计算模型,简单的说就是将大批量的工作(数据)分解(MAP)执行,然后再将结果合并成最终结果(REDUCE)。这样做的好处是可以在任务被分解后,可以通过大量机器进行并行计算,减少...
基于mongodb存储的军事领域知识图谱问答项目,8大类,100余小类,共计5800项的知识库,该项目不使用图数据库进行存储,通过jieba进行问句解析,问句实体项识别,基于查询模板完成多类问题的查询,主要是提供一种工业...
1、该资源内项目代码经过严格调试,下载即用确保可以运行! 2、该资源适合计算机相关专业(如计科、人工智能、大数据、数学、电子信息等)正在做课程设计、期末大作业和毕设项目的...基于MongoDB+Spark+ElasticSearch的电
MapReduce应该算是MongoDB操作中比较复杂的了,下面这篇文章主要给大家介绍了关于MongoDB中MapReduce使用的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起看看吧。
Mongodb是针对大数据量环境下诞生的用于保存大数据量的非关系型数据库,针对大量的数据。接下来通过本文给大家介绍Mongodb中MapReduce实现数据聚合方法详解,感兴趣的朋友一起学习吧
MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化MongoDB疑难杂症分析及优化...
基于MongoDB实现商品管理系统视频
基于MongoDB的数据中台技术实现.pptx
基于MongoDB的分布式地质灾害数据存储策略.docx
基于MongoDB分布式集群架构的日志系统及分片方法.docx
mongodb-log 是一个基于MongoDB的Python日志系统。 MongoDB 的 Capped Collection是一个天生的日志系统,MongoDB自己的oplog就是用它来存储的,Capped Collection的特点是可以指定Collection的大小,当记录总大小...
[Packt Publishing] 基于 MongoDB 的 PHP 网络应用开发 初学者指南 (英文版) [Packt Publishing] PHP and MongoDB Web Development Beginner's Guide (E-Book) ☆ 出版信息:☆ [作者信息] Rubayeet Islam [出版...
MongoDB的MapReduce.pdf 学习资料 复习资料 教学资源
数据库为 mongodb 后端为node 前端为vue,一款简洁的小型库存系统,进出库,历史查询,经销商管理等!
这篇文章就是展示如何使用Java基于MongoDB和Spring Data创建一个CRUD应用。 Spring Data for MongoDB提供了一个类似于基于Sping编程模型的NoSQL数据存储。Spring Data for MongoDB提供了很多特性,它使很多MongoDB的...