MongoDB分组汇总操作,及Spring data mongo的实现

转载请在页首注明作者与出处

一:分组汇总

1.1:SQL样例

分组汇总的应用场景非常多,比如查询每个班级的总分是多少,如果用关系形数据库,那么sql是这样子的

SELECT count(1),class from score group by class

得到的结果就是每个班分别的总分是多少,那么在mongodb这种非关系数据库要怎么做呢?

 

 

1.2:数据样例

假如我们有如下数据若干

{ 
    "_id" : "4fe31003-0ee3-47b8-8a1d-0e9f8561c37e", 
    "systemId" : "test", 
    "bizId" : "test", 
    "channel" : "通道一", 
    "msg" : "你好!", 
    "createTime" : ISODate("2016-10-25T09:17:12.228+0000"), 
    "useTime" : NumberLong(274), 
    "success" : NumberInt(1)
}
{ 
    "_id" : "4fe31003-0ee3-47b8-8a1d-0e9f8561c37e", 
    "systemId" : "test", 
    "bizId" : "test", 
    "channel" : "通道二", 
    "msg" : "你好!", 
    "createTime" : ISODate("2016-10-25T09:17:12.228+0000"), 
    "useTime" : NumberLong(274), 
    "success" : NumberInt(1)
}
 

 

 

1.3:需求

如上短信的发送记录,我们可能统计不同短信通道channnel的发送数量。

 

 

1.4:mongodb查询语法

db.shortMessageLog.aggregate([{$group : {_id : "$channel" , num : {$sum : 1}}}]);

这意味着对channel进行分组,并且查询出来的分组名称以id的形式显示出来

查询结果如下:

{ 
    "_id" : "通道一", 
    "num" : NumberInt(12504)
}
{ 
    "_id" : "通道二", 
    "num" : NumberInt(594)
}

 

 

 

1.5:汇总时加入查询条件

这又是一个新的需求,我们可能只想统计一定时间的内的数量,所以我们需要加入查询条件。

新的语句如下

db.shortMessageLog.aggregate([{$match:{createTime:{$gte:new Date(2016,9,28)}}},{$group : {_id : "$channel" , num : {$sum : 1}}}]);

这里使用$match来匹配指定时间的数量。

小提示:mongodb的月份是从0开始的,也就是上面参数中的9,其实代码的是10月份。

我这里匹配时间大于2016-10-28号以后的数据,然后再交给后面的条件去分组。

 

 

 

1.6:使用java代码的实现

我们这里使用spring data mongo,相比原生的mongo驱动,这个确实要好用很多。

实现的需求就是根据时间来分组统计数量

 

        Aggregation agg = null;
        Criteria createTime = Criteria.where("createTime");
        boolean timeTag = false;
        if(startTime != null){
            createTime.gte(startTime);
            timeTag = true;
        }
        if(endTime != null){
            createTime.lte(endTime);
            timeTag = true;
        }
        GroupOperation groupOperation = Aggregation.group("channel").count().as("count");
        if(timeTag){
            agg = Aggregation.newAggregation(ShortMessageLog.class,Aggregation.match(createTime),groupOperation);
        }else{
            agg = Aggregation.newAggregation(ShortMessageLog.class, groupOperation);
        }
        AggregationResults<Map> results = mongoTemplate.aggregate(agg,ShortMessageLog.class,Map.class);

 

posted @ 2016-10-28 16:23  朱小杰  阅读(15417)  评论(0编辑  收藏  举报