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

yjk295722366      2022-04-08     425

关键词:

这两天要做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聚合使用表达式运算符(函数)分组按条件计数统计案例一则(代码片段)

在MongoDB聚合统计过程中,经常使用表达式运算符用于构造用于聚合管道阶段的表达式。运算符表达式类似于接受参数的函数。通常,这些表达式采用参数数组,并具有以下形式:<operator>:[<argument1>,<argum... 查看详情

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

在MongoDB聚合统计过程中,经常使用表达式运算符用于构造用于聚合管道阶段的表达式。运算符表达式类似于接受参数的函数。通常,这些表达式采用参数数组,并具有以下形式:<operator>:[<argument1>,<argum... 查看详情

如何在 mongoDB 中使用聚合进行分组?

】如何在mongoDB中使用聚合进行分组?【英文标题】:HowtotakegroupusingaggregrateinmongoDB?【发布时间】:2019-05-1912:54:25【问题描述】:我正在尝试从这个BSON数据中对我的一些元素进行分组"_id":ObjectId("5c18e25926fb081b8b5b0240"),"TotalDetectionsin... 查看详情

MongoDB中计算的分组字段

】MongoDB中计算的分组字段【英文标题】:Calculatedgroup-byfieldsinMongoDB【发布时间】:2014-10-1518:21:45【问题描述】:对于MongoDB文档中的这个示例,如何使用MongoTemplate编写查询?db.sales.aggregate([$group:_id:month:$month:"$date",day:$dayOfMonth:"$da... 查看详情

如何使用 MongoDB 根据数组元素对记录进行分组

】如何使用MongoDB根据数组元素对记录进行分组【英文标题】:HowtogrouprecordsbasedonarrayelementsusingMongoDB【发布时间】:2019-09-2510:23:54【问题描述】:我有一个数据集合,其中包含以下格式的一组记录。"_id":22,"title":"3DUserInterfaceswithJa... 查看详情

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

参考技术Ajava操作mongodb进行查询,常用筛选条件的设置如下:条件列表:BasicDBListcondList=newBasicDBList();临时条件对象:BasicDBObjectcond=null;DBCollectioncoll=db.getCollection("A");1、$where在某种应用场合,若要集合A查询文档且要满足文... 查看详情

求教mongodb怎么实现分组去重

...类似于SQLselectcount(distinct(id))fromtwhere...groupbyx;参考技术A在MongoDB中,文档是对数据的抽象,它被使用在Client端和Server端的交互中。所有的Client端(各种语言的Driver)都会使用这种抽象,它的表现形式就是我们常说的BSON(BinaryJSON)... 查看详情

如何在使用 MongoTemplate 进行分组期间对 mongodb 内部字段求和并推送它

】如何在使用MongoTemplate进行分组期间对mongodb内部字段求和并推送它【英文标题】:HowtosumamongodbinnerfieldandpushitduringgroupingusingMongoTemplate【发布时间】:2021-03-1410:06:46【问题描述】:我可以在MongoDB控制台的推送操作中使用sum。但... 查看详情

Mongodb 聚合 - 今天按小时分组

】Mongodb聚合-今天按小时分组【英文标题】:MongodbAggregate-Groupingbyhourfortoday【发布时间】:2020-05-0422:47:49【问题描述】:我想知道是否有人可以帮助我正确设置聚合函数。我正在尝试计算我的健身访问量。我有访问表,其中保存... 查看详情

mongoDB聚合将相似的文档彼此相邻分组

】mongoDB聚合将相似的文档彼此相邻分组【英文标题】:mongolDBaggregationgroupingsimilardocumentsnexttoeachother【发布时间】:2016-03-2012:55:56【问题描述】:我在mongoDB中有一个集合,每天都会向其中添加一个带有采样数据的文档。我想观察... 查看详情

MongoDB Aggregate - 放松、分组和项目

】MongoDBAggregate-放松、分组和项目【英文标题】:MongoDBAggregate-Unwind,groupandproject【发布时间】:2014-10-3003:39:14【问题描述】:使用集合Users,是否可以检索以下唯一的组织/所有者列表?如果当前的设置不可行,是否可以通过一个... 查看详情

MongoDB聚合和分组嵌套字段

】MongoDB聚合和分组嵌套字段【英文标题】:MongoDBaggregateandgroupnestedfield【发布时间】:2017-02-1502:13:13【问题描述】:我有一个使用mongoose的mongoDB的结果,如下所示:"_id":"$oid":"589f926267d836193b0773fd","id":"3","update_date":"2017-02-11","data":[... 查看详情

我应该如何使用 Spring Data MongoDB 计算由另一个分组的字段的总和

】我应该如何使用SpringDataMongoDB计算由另一个分组的字段的总和【英文标题】:HowshouldIcalculatesumoffieldgroupedbyanotheroneusingSpringDataMongoDB【发布时间】:2021-07-0313:41:57【问题描述】:我有一个用户集合,看起来像这样-"post":"teacher","sa... 查看详情

MongoDB/py-mongo 用于带有日期函数的查询

】MongoDB/py-mongo用于带有日期函数的查询【英文标题】:MongoDB/py-mongoforquerieswithdatefunctions【发布时间】:2011-01-1522:19:12【问题描述】:我希望使用诸如MongoDB之类的文档数据库,但在查看文档时,我在涉及日期函数的查询中找不到... 查看详情

使用 MongoDB .Net 驱动程序对数据进行分组并带回其他文档数据

】使用MongoDB.Net驱动程序对数据进行分组并带回其他文档数据【英文标题】:UsingtheMongoDB.NetDrivertobothGroupDataandbringbackotherDocumentData【发布时间】:2021-11-1305:12:25【问题描述】:从这个集合中,我想返回按年级分组的数据,其中还... 查看详情

Mongodb,按日期差异分组并获取小时

】Mongodb,按日期差异分组并获取小时【英文标题】:Mongodb,groupbydatediffandgettinghour【发布时间】:2015-05-3116:10:24【问题描述】:我实际上正在开发一个应用程序,我需要从我的数据库中获取一些信息:我有一个特征模型,其中有... 查看详情

如何对 MongoDB 中数组内的字段值进行分组?

】如何对MongoDB中数组内的字段值进行分组?【英文标题】:HowtogroupbyonafieldvaluethatisinsideanarrayinMongoDB?【发布时间】:2021-10-0612:56:55【问题描述】:我有使用MongoDB的学生评分系统。我在MongoDB中有以下文档:我如何获取特定subject... 查看详情

使用 pymongo 在 mongodb 中按多个值分组

】使用pymongo在mongodb中按多个值分组【英文标题】:Groupbymultiplevaluesinmongodbwithpymongo【发布时间】:2021-07-0817:16:40【问题描述】:我有这个query,我想要groupby"$dateToString":"format":"%Y-%m-%d","date":"$first 查看详情