mongodb sum 操作

Mongodb 统计某个字段的和,可以使用聚合函数。

数据结构如下:

> db.message.findOne()
{
	"_class" : "com.cyou.appwiki.bean.Message",
	"_id" : ObjectId("53997f80c451bf833288b882"),
	"content" : "power9li的回答2",
	"fromNick" : "power9li",
	"fromUid" : "5176923980",
	"pic1" : null,
	"pic2" : null,
	"pic3" : null,
	"qid" : "53997f4dc451bf833288b880",
	"time" : NumberLong("1402568587464"),
	"toUid" : "F34780D6A3CA543DB020D584A91CC8BB",
	"unreadCount" : 2
}

我要统计的是某个toUid的unreadCount的总数

我发现有两种方法可以实现,第一种是mapReduce的方式,我在《MongodDB权威指南》书里看到的:

 

db.runCommand({"group":{
	"ns":"message",
	"key":"toUid",
	"initial":{"total":0},
	"$reduce" : function(doc,prev){
		prev.total += doc.unreadCount;
	},
	"condition":{"toUid":"F34780D6A3CA543DB020D584A91CC8BB"}
}});

 

 返回的结果格式:

{
	"retval" : [
		{
			"total" : 13
		}
	],
	"count" : 5,
	"keys" : 1,
	"ok" : 1
}

 

第二种方法是在 http://www.w3cschool.cc/mongodb/mongodb-aggregate.html 看到的:

db.message.aggregate([
	{ $match : { "toUid" : "F34780D6A3CA543DB020D584A91CC8BB"}},
	{ $group : { _id : "$toUid", num_tutorial : {$sum : "$unreadCount"} }}
]);

 

返回的结果:

{
	"result" : [
		{
			"_id" : "F34780D6A3CA543DB020D584A91CC8BB",
			"num_tutorial" : 13
		}
	],
	"ok" : 1
}

 在使用spring-mongo进行开发的时候,也对应两种方法

1:(老方法,支持spring-mongo所有版本)

public long findNewMessage(Integer appId, String userId) {
		Long total = 0l;
		String reduce = "function(doc, aggr){" +
                "            aggr.total += doc.unreadCount;" +
                "        }";
        Query query = Query.query(Criteria.where("toUid").is(userId).and("appId").is(appId));
        DBObject result = mongoTemplate.getCollection("message").group(new BasicDBObject("toUid", 1), 
                query.getQueryObject(), 
                new BasicDBObject("total", total),
                reduce);
        
        Map map = result.toMap();
        if(map.size() > 0){
	        BasicDBObject bdbo = map.get("0");
	        if(bdbo != null && bdbo.get("total") != null)
	        	total = bdbo.getLong("total");
        }
		return total;
	}

 

方法2(只有spring-mongo 3.2以上才支持)

public long getNewMessageCount(Integer appId, String userId){
		Long total = 0l;
		Aggregation aggregation = Aggregation.newAggregation(
			match(Criteria.where("toUid").is(userId).and("appId").is(appId)),
			group("toUid").sum("unreadCount").as("total")
		);
		
		AggregationResults ar = mongoTemplate.aggregate(aggregation, "message", StateStats.class);
		List list = ar.getMappedResults();
		if(list.size() > 0){
			total = list.get(0).total;
		}
		return total;
	}

 

 

你可能感兴趣的:(数据库)