网站用户行为数据统计与分析之二:数据写入mongodb

    接着上一篇博文,我再补充一下:

    在js中收集到用户行为数据之后呢,我们要在后台对数据进行处理,怎么处理?在实际项目中我分两条路走:

    一、直接写入mongodb,随着电商网站规模越来越大,访问量越来越高,这种非关系型数据库可以有效地化解高并发的问题

    二、做日志处理(后台数据-----redis-----logstash-----elasticsearch------kibana)

    在这篇文章中,我们先来探讨写DB。

    两种方式,一、利用java mongodb api;二、利用log4j

    方式一mongodb提供了很友好的java api

    我们先来看看:

   package com.founder.ec.util;

   import java.net.SocketException;
   import java.net.UnknownHostException;

   import com.founder.ec.entity.BehaviorUser;
   import com.mongodb.BasicDBObject;
   import com.mongodb.DB;
   import com.mongodb.DBCollection;
   import com.mongodb.DBObject;
   import com.mongodb.Mongo;

   /**
    * 实现MongoDB的CRUD操作
    * 
    * @author 五味子
    * @version 2014/04/04
    */
    public class MongOpera {

	private static DB db;
	private static DBCollection users;
	private static Mongo mg;

	@SuppressWarnings("deprecation")
	public static DBCollection init() {
		try {
			try {
				mg = DBManager.inits("192.168.2.87", 27017, 300);
			} catch (SocketException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 获取temp DB;如果默认没有创建,mongodb会自动创建
		db = mg.getDB("test");
		// 获取users DBCollection;如果默认没有创建,mongodb会自动创建
		users = db.getCollection("testdb");
		return users;
	}
	/**//**
	 * 销毁mongo对象
	 * @param
	 * @return
	 *//*
	public static void destory() {
		if (mg != null)
			mg.close();
		mg = null;
		db = null;
		users = null;
		System.gc();//内存垃圾回收
	}
	*//**
	 * 打印查询结果
	 * @param o
	 * @return
	 *//*
	public static void print(Object o) {
		System.out.println(o);
	}
	*//**
	 * 查询所有数据
	 * @param
	 * @return
	 *//*
	private static void queryAll() {
		print("查询users的所有数据:");
		// db游标
		DBCursor cur = users.find();
		while (cur.hasNext()) {
			print(cur.next());
		}
	}*/
	/**
	 * 添加数据
	 * @param Synchronized 
	 * @param
	 * @return
	 */
	public static void add(BehaviorUser behaviorUser) {
		// 先查询所有数据
		//queryAll();
		//print("count: " + users.count());

		DBObject user = new BasicDBObject();
		user.put("sessionId", behaviorUser.getSessionId());
		user.put("uuid", 24);
		user.put("memberId", behaviorUser.getMemberId());
		user.put("refPage", behaviorUser.getRefPage());
		user.put("firstPage", behaviorUser.getFirstPage());
		user.put("initTime", behaviorUser.getInitTime());
		user.put("orderId", behaviorUser.getOrderId());
		user.put("currentTime", behaviorUser.getCurrentTime());
		user.put("currentURL", behaviorUser.getCurrentPage());
		
		users = init();
		
		users.save(user);//保存,getN()获取影响行数
		
		/*List list1 = new ArrayList();
		
		List<DBObject> list2 = null;
		
		list1.add(user);
		
		if (list1.size()>=30) {
			
			list2 = new ArrayList();
			
			Synchronized{
				
				list2.addAll(list1);
				list1.clear();
				
			}
			
			new Thread().start();
		
			new Thread(
				
				try{
					
					users.insert(list2);
				}catch(ApplicationException e){
					
				}
			).start();
			
		  }*/
	
		
		
		//print(users.save(user).getN());

		/*// 扩展字段,随意添加字段,不影响现有数据
		user.put("sex", "男");
		print(users.save(user).getN());

		// 添加多条数据,传递Array对象
		print(users.insert(user, new BasicDBObject("name", "tom")).getN());

		// 添加List集合
		List<DBObject> list = new ArrayList<DBObject>();
		list.add(user);
		DBObject user2 = new BasicDBObject("name", "lucy");
		user.put("age", 22);
		list.add(user2);
		// 添加List集合
		print(users.insert(list).getN());

		// 查询下数据,看看是否添加成功
		print("count: " + users.count());
		queryAll();*/
	}
	
      /*	*//**
	 * 移除数据
	 * @param
	 * @return
	 *//*
	public static void remove() {
		queryAll();
		print("删除id = 4de73f7acd812d61b4626a77:"
				+ users.remove(
						new BasicDBObject("_id", new ObjectId(
								"4de73f7acd812d61b4626a77"))).getN());
		print("remove age >= 24: "
				+ users.remove(
						new BasicDBObject("age", new BasicDBObject("$gte", 24)))
						.getN());
	}
	*//**
	 * 修改数据
	 * @param
	 * @return
	 *//*
	public static void modify() {
		print("修改:"
				+ users.update(
						new BasicDBObject("_id", new ObjectId(
								"4dde25d06be7c53ffbd70906")),
						new BasicDBObject("age", 99)).getN());
		print("修改:"
				+ users.update(
						new BasicDBObject("_id", new ObjectId(
								"4dde2b06feb038463ff09042")),
						new BasicDBObject("age", 121), true,// 如果数据库不存在,是否添加
						false// 多条修改
				).getN());
		print("修改:"
				+ users.update(new BasicDBObject("name", "haha"),
						new BasicDBObject("name", "dingding"), true,// 如果数据库不存在,是否添加
						true// false只修改第一天,true如果有多条就不修改
				).getN());

		// 当数据库不存在就不修改、不添加数据,当多条数据就不修改
		// print("修改多条:" + coll.updateMulti(new BasicDBObject("_id", new
		// ObjectId("4dde23616be7c19df07db42c")), new BasicDBObject("name",
		// "199")));
	}
	*//**
	 * 条件查询
	 * @param
	 * @return
	 *//*
	public static void query() {
		// 查询所有
		// queryAll();

		// 查询id = 4de73f7acd812d61b4626a77
		print("find id = 4de73f7acd812d61b4626a77: "
				+ users.find(
						new BasicDBObject("_id", new ObjectId(
								"4de73f7acd812d61b4626a77"))).toArray());

		// 查询age = 24
		print("find age = 24: "
				+ users.find(new BasicDBObject("age", 24)).toArray());

		// 查询age >= 24
		print("find age >= 24: "
				+ users.find(
						new BasicDBObject("age", new BasicDBObject("$gte", 24)))
						.toArray());
		print("find age <= 24: "
				+ users.find(
						new BasicDBObject("age", new BasicDBObject("$lte", 24)))
						.toArray());

		print("查询age!=25:"
				+ users.find(
						new BasicDBObject("age", new BasicDBObject("$ne", 25)))
						.toArray());
		print("查询age in 25/26/27:"
				+ users.find(
						new BasicDBObject("age", new BasicDBObject(
								QueryOperators.IN, new int[] { 25, 26, 27 })))
						.toArray());
		print("查询age not in 25/26/27:"
				+ users.find(
						new BasicDBObject("age", new BasicDBObject(
								QueryOperators.NIN, new int[] { 25, 26, 27 })))
						.toArray());
		print("查询age exists 排序:"
				+ users.find(
						new BasicDBObject("age", new BasicDBObject(
								QueryOperators.EXISTS, true))).toArray());

		print("只查询age属性:"
				+ users.find(null, new BasicDBObject("age", true)).toArray());
		// 只查询一条数据,多条去第一条
		print("findOne: " + users.findOne());
		print("findOne: " + users.findOne(new BasicDBObject("age", 26)));
		print("findOne: "
				+ users.findOne(new BasicDBObject("age", 26),
						new BasicDBObject("name", true)));

		// 查询修改、删除
		print("findAndRemove 查询age=25的数据,并且删除: "
				+ users.findAndRemove(new BasicDBObject("age", 25)));

		// 查询age=26的数据,并且修改name的值为Abc
		print("findAndModify: "
				+ users.findAndModify(new BasicDBObject("age", 26),
						new BasicDBObject("name", "Abc")));
		print("findAndModify: "
				+ users.findAndModify(new BasicDBObject("age", 28), // 查询age=28的数据
						new BasicDBObject("name", true), // 查询name属性
						new BasicDBObject("age", true), // 按照age排序
						false, // 是否删除,true表示删除
						new BasicDBObject("name", "Abc"), // 修改的值,将name修改成Abc
						true, true));
		queryAll();
	}

	*//**
	 * mongoDB不支持联合查询、子查询,这需要我们自己在程序中完成。将查询的结果集在Java查询中进行需要的过滤即可。
	 * @param
	 * @return
	 *//*
	public static void testOthers() {
		DBObject user = new BasicDBObject();
		user.put("name", "hoojo");
		user.put("age", 24);

		// JSON 对象转换
		print("serialize: " + JSON.serialize(user));
		// 反序列化
		print("parse: " + JSON.parse("{ \"name\" : \"hoojo\" , \"age\" : 24}"));

		print("判断temp Collection是否存在: " + db.collectionExists("temp"));

		// 如果不存在就创建
		if (!db.collectionExists("temp")) {
			DBObject options = new BasicDBObject();
			options.put("size", 20);
			options.put("capped", 20);
			options.put("max", 20);
			print(db.createCollection("account", options));
		}

		// 设置db为只读
		db.setReadOnly(true);

		// 只读不能写入数据
		db.getCollection("test").save(user);
	}*/
}
    以上代码,CRUD好像都有了!但是有个问题需要指出,mongodb有默认的连接池,只不过默认连接数为10,我们如果有特别需要,可以自建连接池
   package com.founder.ec.util;
   import com.mongodb.Mongo;
   import com.mongodb.MongoOptions;
   /**
   * mongodb连接池
   * @author 五味子
   * @version 2014/04/04
   */
   public class DBManager{
	
	    private static Mongo mongo;  //mongodb数据库操作对象
	    
	    /**
	     * 
	     * @param ip ip地址
	     * @param port 端口号
	     * @param poolSize 连接数
	     * @return Mongo操作对象
	     * @throws java.net.UnknownHostException 找不到主机异常
	     */
	    public static Mongo inits(final String ip, int port, int poolSize) throws java.net.UnknownHostException,java.net.SocketException {  
	    	try{
		        System.setProperty("MONGO.POOLSIZE", String.valueOf(poolSize));  
		        if (mongo == null) {  
		            mongo = new Mongo(ip, port);  
		            MongoOptions options = mongo.getMongoOptions(); 
		            //每个主机的连接数
		            options.connectionsPerHost = poolSize;  
		            //这个控制是否在一个连接时,系统会自动重试
		            options.autoConnectRetry = true;
		            //最大等待连接的线程阻塞时间 
		            options.maxWaitTime = 5000; 
		           //socket超时。0是默认和无限
		            options.socketTimeout = 2000; 
		            //连接超时的毫秒。0是默认和无限
		            options.connectTimeout = 15000;
		           //线程队列数,它以上面connectionsPerHost值相乘的结果就是线程队列最大值。如果连接线程排满了队列就会抛出“Out of semaphores to get db”错误。
		            options.threadsAllowedToBlockForConnectionMultiplier = 4; 
		        }  
	    	}catch(Exception e){
	    		
	    		e.getMessage();
	    	}
	    	 return mongo;
	    }  
	}  


    

      方式二:log4j

      这种方式比较简单,只不过只能作为添加数据用

      在log4j.propertites文件中:

    log4j.rootLogger=debug, stdout, R, MongoDB

    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%-d{MM-dd HH:mm:ss.SSS} %-5p - [%c{1}.%t] %m%n

    log4j.appender.R=org.apache.log4j.RollingFileAppender
    log4j.appender.R.File=D:/data/Sample.log
    log4j.appender.R.MaxFileSize=1000KB
    log4j.appender.R.MaxBackupIndex=1
    log4j.appender.R.layout=org.apache.log4j.PatternLayout
    log4j.appender.R.layout.ConversionPattern=%-d{MM-dd HH:mm:ss.SSS} %-5p - [%c{1}.%t] %m%n

    #log4j.appender.MongoDB=org.log4mongo.MongoDbAppender
    #log4j.appender.MongoDB.databaseName=test
    #log4j.appender.MongoDB.collectionName=testdb
    #log4j.appender.MongoDB.hostname=192.168.2.86
    #log4j.appender.MongoDB.port=27017
     

     注意打上#的几段代码,应该不要解释吧!

     什么?你看不懂属性文件,那你还是先补补属性文件再来看吧!
     想进一步了解Mongodb,请阅读超详细的中文指南:
     http://download.csdn.net/detail/u013339851/7120473

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值