Mongodb sum 求和


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

数据结构如下:

Js代码   收藏代码
  1. > db.message.findOne()  
  2. {  
  3.     "_class" : "com.cyou.appwiki.bean.Message",  
  4.     "_id" : ObjectId("53997f80c451bf833288b882"),  
  5.     "content" : "power9li的回答2",  
  6.     "fromNick" : "power9li",  
  7.     "fromUid" : "5176923980",  
  8.     "pic1" : null,  
  9.     "pic2" : null,  
  10.     "pic3" : null,  
  11.     "qid" : "53997f4dc451bf833288b880",  
  12.     "time" : NumberLong("1402568587464"),  
  13.     "toUid" : "F34780D6A3CA543DB020D584A91CC8BB",  
  14.     "unreadCount" : 2  
  15. }  

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

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

 

Js代码   收藏代码
  1. db.runCommand({"group":{  
  2.     "ns":"message",  
  3.     "key":"toUid",  
  4.     "initial":{"total":0},  
  5.     "$reduce" : function(doc,prev){  
  6.         prev.total += doc.unreadCount;  
  7.     },  
  8.     "condition":{"toUid":"F34780D6A3CA543DB020D584A91CC8BB"}  
  9. }});  

 

 返回的结果格式:

Js代码   收藏代码
  1. {  
  2.     "retval" : [  
  3.         {  
  4.             "total" : 13  
  5.         }  
  6.     ],  
  7.     "count" : 5,  
  8.     "keys" : 1,  
  9.     "ok" : 1  
  10. }  

 

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

Js代码   收藏代码
  1. db.message.aggregate([  
  2.     { $match : { "toUid" : "F34780D6A3CA543DB020D584A91CC8BB"}},  
  3.     { $group : { _id : "$toUid", num_tutorial : {$sum : "$unreadCount"} }}  
  4. ]);  

 

返回的结果:

Js代码   收藏代码
  1. {  
  2.     "result" : [  
  3.         {  
  4.             "_id" : "F34780D6A3CA543DB020D584A91CC8BB",  
  5.             "num_tutorial" : 13  
  6.         }  
  7.     ],  
  8.     "ok" : 1  
  9. }  

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

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

Java代码   收藏代码
  1. public long findNewMessage(Integer appId, String userId) {  
  2.         Long total = 0l;  
  3.         String reduce = "function(doc, aggr){" +  
  4.                 "            aggr.total += doc.unreadCount;" +  
  5.                 "        }";  
  6.         Query query = Query.query(Criteria.where("toUid").is(userId).and("appId").is(appId));  
  7.         DBObject result = mongoTemplate.getCollection("message").group(new BasicDBObject("toUid"1),   
  8.                 query.getQueryObject(),   
  9.                 new BasicDBObject("total", total),  
  10.                 reduce);  
  11.           
  12.         Map map = result.toMap();  
  13.         if(map.size() > 0){  
  14.             BasicDBObject bdbo = map.get("0");  
  15.             if(bdbo != null && bdbo.get("total") != null)  
  16.                 total = bdbo.getLong("total");  
  17.         }  
  18.         return total;  
  19.     }  

 

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

Java代码   收藏代码
  1. public long getNewMessageCount(Integer appId, String userId){  
  2.         Long total = 0l;  
  3.         Aggregation aggregation = Aggregation.newAggregation(  
  4.             match(Criteria.where("toUid").is(userId).and("appId").is(appId)),  
  5.             group("toUid").sum("unreadCount").as("total")  
  6.         );  
  7.           
  8.         AggregationResults ar = mongoTemplate.aggregate(aggregation, "message", StateStats.class);  
  9.         List list = ar.getMappedResults();  
  10.         if(list.size() > 0){  
  11.             total = list.get(0).total;  
  12.         }  
  13.         return total;  
  14.     } 



原文:http://garyli.iteye.com/blog/2079158

你可能感兴趣的:(Mongodb)