使用mongodb的js来统计数据

来源:互联网 发布:vscode编译c语言 编辑:程序博客网 时间:2024/05/18 04:01

有这样一个需求:我需要从一张表中统计出前一天每篇文章的评论数量,程序使用contrab每天晚上定时执行,因此需要写一个mongodb脚本,而不能用程序来完成。由于mapreduce不能直接排序,我的做法是先用mapreduce生成一个临时文档,然后再从这个文章中排序插入数据到目标文档中。程序如下:

var map = function() {
    var date = new Date();
        date.setDate(date.getDate() - 1);
        var d = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
              emit({rootId:this.rootId,date:d,type:parseInt(this.type)},
                    { 
sum:1,
status:this.status,boardId:this.boardId,
                                currBoardId:this.currBoardId});
                    };
var reduce = function(key, values){
var reblogNum = 0;
var likeNum=0; 
var replyNum=0;
var sum = 0;
var type = key.type;
        var date = new Date();
        date.setDate(date.getDate() - 1);
        var d = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
for(var i=0;i < values.length;i++) 
 {
 var val = values[i];
 var status=parseInt(val.status);
 var boardId= val.boardId;
 var currBoardId =  val.currBoardId;
 if(status==11 && currBoardId > 0) {
    reblogNum = reblogNum + 1;
  } else if(status==12 && currBoardId > 0) {
       likeNum = likeNum + 1;
  } else if(status ==0 && boardId > 0) {
    replyNum= replyNum + 1;
 }
 }
 sum =reblogNum + replyNum + likeNum;
 return {sum:NumberInt(sum)};
};


var prevous = function() {
   var date = new Date();
   date.setDate(date.getDate() - 2);
   return (date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' 23:59:59');
};
var after = function() {
    var date = new Date();
   date.setDate(date.getDate());
   return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + (date.getDate() + 1);
};
db.comment.mapReduce(
    map,
    reduce,    
   {
    query : {
        createTime:{$gt:prevous(),$lt:after()}
    },
    out:{replace:'comm_tempnum'}
   }
);

//这个操作完全类似于jquery的each方法,方法的参数x是每一行组成的对象,这个x在方法中就可以随意修改然后存储到别的地方
db.comm_tempnum.find().sort({"value.sum":-1}).forEach(function(x){db.comm_dailly_num.insert({'_id':{rootId:x._id.rootId,date:x._id.date},type:x._id.type,sum:x.value.sum,rootId:x._id.rootId,date:x._id.date})})





java代码实现:

package com.test;


import java.io.IOException;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;


import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.MapReduceCommand;
import com.mongodb.MapReduceOutput;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
import com.mongodb.MongoOptions;
import com.mongodb.ServerAddress;


public class StaticDaillyCommentNum {

/**@description:
* @return:void
* @param args
* @throws MongoException 
* @throws SQLException 
* @throws ParseException 
* @throws IOException 
*/
public static void main(String[] args) throws MongoException, SQLException, ParseException, IOException {
StaticDaillyCommentNum t = new StaticDaillyCommentNum();
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");

        t.insertData();
}

private void insertData() throws SQLException, MongoException, ParseException, IOException {
MongoOptions options = new MongoOptions();
options.autoConnectRetry = true;  
        options.connectionsPerHost = 300;  
        options.maxWaitTime= 3000;
Mongo mg = new Mongo(new ServerAddress("192.168.1.48",27017), options);
DB db = mg.getDB("l_comment");
Calendar cal = Calendar.getInstance();
Calendar end = Calendar.getInstance();
SimpleDateFormat sdf  = new SimpleDateFormat("yyyy-MM-dd");
cal.setTime(sdf.parse("2013-08-30"));
long sd = cal.getTimeInMillis();
long ed = System.currentTimeMillis();
long td = ed - sd;
int day = (int)(td/(1000*60*60*24));
System.out.println("day="+day);
end.setTime(sdf.parse("2013-08-30"));
int count = 0;
long start = System.currentTimeMillis();
while(count < day) {
count++;
cal.add(Calendar.DAY_OF_MONTH, -1);
end.add(Calendar.DAY_OF_MONTH,1);
selectData(db, cal.getTime(), end.getTime());
cal.setTime(end.getTime());
}
long end1 = System.currentTimeMillis();
System.out.println((end1 - start) + "ms");
}

public void selectData(DB db, Date startD, Date endD) throws SQLException {

DBCollection coll = db.getCollection("comment");
String map = "function() {emit({type:this.type,boardId:this.boardId},{ " +
"reb:0,like:0,reply:0,recommentReply:0,length:0,checkin:0," +
"status:this.status,boardId:this.boardId,currBoardId:this.currBoardId,type:this.type});}";
String reduce = "function(key, values){var reblogNum = 0;var likeNum=0; " +
"var replyNum=0;var length =values.length;var recommentReply = 0;" +
"var checkinNum = 0;" +
"for(var i=0;i < values.length;i++) " +
 "{" +
 "var val = values[i];" +
 "var status=parseInt(val.status);" +
 "var boardId= val.boardId;" +
 "var currBoardId =  val.currBoardId;" +
 "reblogNum += val.reb;" +
 "likeNum += val.like; " +
 "replyNum += val.reply; recommentReply += val.recommentReply; length += val.length;" +
 "checkinNum += val.checkinNum;" +
 "if(status==11 && currBoardId > 0) {reblogNum = reblogNum + 1;} " +
 "else if(status==12 && currBoardId > 0) {likeNum = likeNum + 1;} " +
 " else if(status ==0 && boardId > 0) {" +
 " replyNum= replyNum + 1;}" +
 "else if(status == 1 && boardId > 0) {" +
 "recommentReply += 1;}" +
 "} " +
 "return {k:key,reb:NumberInt(reblogNum),like:NumberInt(likeNum)," +
 "reply:NumberInt(replyNum),recommentReply:NumberInt(recommentReply)," +
 "length:NumberInt(length)}; " +
 "}";

DBObject query = new BasicDBObject();
//query.put("accountId", 833640);    //测试单个用户的数量
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
cal.setTime(startD);
String startDate = sdf.format(startD);
query.put("createTime", new BasicDBObject("$gt",startDate).append("$lt", sdf2.format(endD)));
query.put("boardId", new BasicDBObject("$gt",0));
System.out.println(query);
MapReduceCommand cmd = new MapReduceCommand(coll,map, reduce,"reblogNum",MapReduceCommand.OutputType.REPLACE,query);
MapReduceOutput out = coll.mapReduce(cmd);
int length = 0;
cal.add(Calendar.DAY_OF_MONTH, 1);
Map<String, DBObject> datas = new HashMap<String, DBObject>(100);
for (DBObject result : out.results()) {

Object obj = result.get("value");
DBObject key = (BasicDBObject) result.get("_id");
Long boardIdd = Long.parseLong(key.get("boardId").toString());
String stype = key.get("type").toString();
int type = -1;
if(stype.indexOf(".") > 0) {
type = Integer.parseInt(stype.substring(0, stype.indexOf(".")));
} else {
type = Integer.parseInt(stype);
}
if(obj instanceof BasicDBObject) {
DBObject objt = (BasicDBObject) obj;
int reblogNum = 0;
int likeNum = 0;
int replyNum = 0;
int recommentReply = 0;
if(objt.get("status") != null) {
length += 1;
String sta = objt.get("status").toString();
int status = Integer.parseInt(sta.substring(0, sta.length() - 2));
Long boardId = Long.parseLong(objt.get("boardId").toString());
Long currBoardId = Long.parseLong(objt.get("currBoardId").toString());
if(status == 12 && currBoardId.longValue() > 0) {
likeNum = 1;
} else if(status == 11 && currBoardId.longValue() > 0){
reblogNum = 1;
} else if(status == 0&& boardId.longValue() > 0) {
replyNum = 1;
} else if(status == 1.0 && boardId.longValue() > 0) {
recommentReply = 1;
}
} else {
length += Integer.parseInt(objt.get("length").toString());
reblogNum = Integer.parseInt((objt.get("reb") == null)?"0":objt.get("reb").toString());
likeNum = Integer.parseInt((objt.get("like") == null)?"0":objt.get("like").toString());
replyNum = Integer.parseInt((objt.get("reply") == null)?"0":objt.get("reply").toString());
recommentReply = Integer.parseInt((objt.get("recommentReply") == null)?"0":objt.get("recommentReply").toString());
}
DBObject set = new BasicDBObject();
set.put("boardId", boardIdd);
set.put("likeNum", likeNum);
set.put("reblogNum", reblogNum);
set.put("replyNum", replyNum);
set.put("recommentReply", recommentReply);
set.put("sum", likeNum + reblogNum + replyNum);
set.put("type", type);
set.put("date", sdf2.format(cal.getTime()));
System.out.println("set=" + set + ", length=" + length);
datas.put(likeNum + reblogNum + replyNum + "_" + boardIdd, set);



}  
List<Map.Entry<String, DBObject>> list = new ArrayList<Map.Entry<String, DBObject>>(datas.entrySet());
Collections.sort(list, new Comparator<Map.Entry<String, DBObject>>() {   
   public int compare(Map.Entry<String, DBObject> o1, Map.Entry<String, DBObject> o2) {     
    String key1 = o1.getKey();
    String key2 = o2.getKey();
    String num1 = key1.split("_")[0];
    String num2 = key2.split("_")[0];
    Integer sum1 = Integer.parseInt(num1);
    Integer sum2 = Integer.parseInt(num2);
       return sum2.compareTo(sum1);
   }
}); 
DBCollection numColl = db.getCollection("comm_dailly_num");

for(Entry<String, DBObject> entry : list) {
numColl.save(entry.getValue());
}

}
}



原创粉丝点击