mongodb分组函数的使用(spring-data-mongodb)

Posted yjk295722366

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mongodb分组函数的使用(spring-data-mongodb)相关的知识,希望对你有一定的参考价值。

这两天要做mongodb日志的模块,下面记录一下。

一、

首先要导入一批数据,使用springboot来完成。

配置mongodb的复制集:在application.yml文件中配置uri来完成

技术分享图片

格式:mongodb://用户名:密码@ip:端口[,ip:端口] [,ip:端口]/数据库名

下面注入mongoTemplate:

 技术分享图片

 

二、

Mongodb在java中分组使用应该有两三种方式:可以百度一下

下面我贴上我们项目组使用的代码:

@Service("logMongoService")

public class LogMongoServiceImpl implements LogMongoService {

         /**

          * 按月统计登录次数使用的初始化的js对象

          */

         private static final String initMonthGroupByJs = "{total:0," +

                          "JanCount:0," +

                          "FebCount:0," +

                          "MarCount:0," +

                          "AprCount:0," +

                          "MayCount:0," +

                          "JuneCount:0," +

                          "JulyCount:0," +

                          "AugCount:0," +

                          "SepCount:0," +

                          "OctCount:0," +

                          "NovCount:0," +

                          "DecCount:0}";

         /**

          * 按月统计登录次数使用的js,mongodb在执行时会自动的执行此脚本

          */

         private static final String monthGroupByJs =

                          "function(doc, prev){" +

                                            "prev.total += 1;" +

                                            "if (doc.startTime.getFullYear() == searchYear && doc.startTime.getMonth() == 0) {" +

                                                     "prev.JanCount += 1;" +

                                            "}" +

                                            "if (doc.startTime.getFullYear() == searchYear && doc.startTime.getMonth() == 1) {" +

                                                     "prev.FebCount += 1;" +

                                            "}" +

                                            "if (doc.startTime.getFullYear() == searchYear && doc.startTime.getMonth() == 2) {" +

                                                     "prev.MarCount += 1;" +

                                            "}" +

                                            "if (doc.startTime.getFullYear() == searchYear && doc.startTime.getMonth() == 3) {" +

                                                     "prev.AprCount += 1;" +

                                            "}" +

                                            "if (doc.startTime.getFullYear() == searchYear && doc.startTime.getMonth() == 4) {" +

                                                     "prev.MayCount += 1;" +

                                            "}" +

                                            "if (doc.startTime.getFullYear() == searchYear && doc.startTime.getMonth() == 5) {" +

                                                     "prev.JuneCount += 1;" +

                                            "}" +

                                            "if (doc.startTime.getFullYear() == searchYear && doc.startTime.getMonth() == 6) {" +

                                                     "prev.JulyCount += 1;" +

                                            "}" +

                                            "if (doc.startTime.getFullYear() == searchYear && doc.startTime.getMonth() == 7) {" +

                                                     "prev.AugCount += 1;" +

                                            "}" +

                                            "if (doc.startTime.getFullYear() == searchYear && doc.startTime.getMonth() == 8) {" +

                                                     "prev.SepCount += 1;" +

                                            "}" +

                                            "if (doc.startTime.getFullYear() == searchYear && doc.startTime.getMonth() == 9) {" +

                                                     "prev.OctCount += 1;" +

                                            "}" +

                                            "if (doc.startTime.getFullYear() == searchYear && doc.startTime.getMonth() == 10) {" +

                                                     "prev.NovCount += 1;" +

                                            "}" +

                                            "if (doc.startTime.getFullYear() == searchYear && doc.startTime.getMonth() == 11) {" +

                                                     "prev.DecCount += 1;" +

                                            "}" +

                          "}";

 

 

  @Override

    public void findMonthLogin(MongoPage page, SystemLogQuery systemLogQuery) throws Exception{

                  //添加年份的限制  也就是查询条件

                  Criteria[] logType ={Criteria.where("logType").is("2")};

                  Calendar startCalendar = Calendar.getInstance();

                  startCalendar.set(year, 0, 1, 0,0, 0);

                  Calendar endCalendar = Calendar.getInstance();

                  endCalendar.set(year + 1, 0, 1, 0,0, 0);

                  Criteria[] yearCriteria ={Criteria.where("startTime").gte(startCalendar.getTime()).lt(endCalendar.getTime())};

                  logType = (Criteria[]) ArrayUtils.addAll(logType, yearCriteria);

 

                  //组织分组时使用的js

                  String initGroupByJs = initMonthGroupByJs;

                  String groupByJs = monthGroupByJs.replace("searchYear", year + "");

 

                  //此处开始分组查询

             //以name字段进行分组

             GroupBy groupBy = new GroupBy("username","name","departmentName").

                                                     initialDocument(initGroupByJs).

                                                     reduceFunction(groupByJs);

             //执行分组查询

             GroupByResults groupByResults = logMongoDao.group(new Criteria().andOperator(logType), groupBy);

//取出分组后的数据 这里必须是retval

             BasicDBList list = (BasicDBList) groupByResults.getRawResults().get("retval");

                  page.setTotal(list.size());

 

                  //用来存放查询到的list集合

             List<SystemLogVO> logVOList = new ArrayList<SystemLogVO>();

        for (int i = (page.getPageNumber()-1) * page.getPageSize();

                               i < page.getPageNumber() * page.getPageSize() && i < list.size(); i++) {

                 SystemLogVO systemlog = new SystemLogVO();

                          //在这个obj中就包含了所有的分组后,我们自定义的哪些属性的值

                 BasicDBObject obj = (BasicDBObject)list.get(i);

                 systemlog.setName(obj.get("name") == null? "" : obj.get("name").toString());

                 systemlog.setDepartmentName(obj.get("departmentName") == null?"":obj.get("departmentName").toString());

                 systemlog.setUsername(obj.get("username") == null?"":obj.get("username").toString());

                          //获取其中的月份的值

                          obj.get("total");//总的值

                          obj.get("JanCount");//根据条件过滤后,统计的1月份的值

                          obj.get("DecCount");

        }

         }               

}


需要说明的一点是,groupByJs这个是一个回调函数, 

当mongodb在过滤数据时,会调用这个js方法,doc变量是将正在处理的一条数据传输进来,prev相当于上面定义的initMonthGroupByJs中的js对象,

最后在initMonthGroupByJs中定义的对象会返回给我们,我们可以从prev中取到我们所有需要的数据。

Additiong:

https://blog.csdn.net/liming_0820/article/details/78657146

http://www.cnblogs.com/anhaogoon/p/9354248.html

 


以上是关于mongodb分组函数的使用(spring-data-mongodb)的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB聚合使用表达式运算符(函数)分组按条件计数统计案例一则

MongoDB聚合使用表达式运算符(函数)分组按条件计数统计案例一则

求教mongoDB怎么实现分组去重

由3个表分组,并计入空函数,与空表mongoDb相同

java怎么做到使用mongodb来进行分组查询统

Mongodb 聚合 - 今天按小时分组