Spring Boot 整合——MongoDB整合3(MongoDB聚合操作)
文章前面
关于版本
依赖 | 版本 |
---|---|
springboot | 2.0.8.RELEASE |
mongodb | 4.0.14 |
本内容只是为了介绍mongodb最基础的使用以及配置,作为一个知名的数据库,其存在相当多的高级用法,展开来介绍内容会相当多,当然本人并非相关领域的大神,下面内容只不过整理了自己日常使用的一些积累。是对自己经验的积累,也希望能帮助后来的同学
关于项目
本内容也是我尝试整理工作中接触过各种工具在springboot中使用的方法。下面介绍的所有方法都已经提供了测试用例。因为每个例子涉及代码较多,所以文章中只贴出了部分代码。全部的代码在这里:https://gitee.com/daifyutils/springboot-samples。
聚合管道操作
MongoTemplate提供了aggregate方法来实现对数据的聚合操作。其核心逻辑在于接受一个TypedAggregation
参数,此参数定义了聚合操作的具体限制语句。
@Overridepublic <O> AggregationResults<O> aggregate(TypedAggregation<?> aggregation, Class<O> outputType) {return aggregate(aggregation, operations.determineCollectionName(aggregation.getInputType()), outputType);}/* (non-Javadoc)* @see org.springframework.data.mongodb.core.MongoOperations#aggregate(org.springframework.data.mongodb.core.aggregation.TypedAggregation, java.lang.String, java.lang.Class)*/@Overridepublic <O> AggregationResults<O> aggregate(TypedAggregation<?> aggregation, String inputCollectionName,Class<O> outputType) {Assert.notNull(aggregation, "Aggregation pipeline must not be null!");AggregationOperationContext context = new TypeBasedAggregationOperationContext(aggregation.getInputType(),mappingContext, queryMapper);return aggregate(aggregation, inputCollectionName, outputType, context);}
聚合管道支持操作
MongoTemplate提供的aggregate方法,实际上是mongodb的aggregate()的JAVA版。而实际上MongoTemplate提供的aggregate方法也是生成mongodb的aggregate()的表达式来进行最终的查询。
aggregate你可以认为是一个管道,当MongoDB的文档经过一个管道处理之后处理后的数据会传递给下一个管道来进行处理。这就对管道的使用产生两个影响:1.管道处理是顺序的,相同的管道内容不同的执行顺序会产生不同的结果。2.管道只能处理被之前管道处理过后的数据。
mongodb提供的aggregate()
聚合管道操作
下面是基于聚合管道mongodb提供的可操作的内容
支持的操作 | java接口 | 说明 |
---|---|---|
$project | Aggregation.project | 修改输入文档的结构。 |
$match | Aggregation.match | 用于过滤数据 |
$limit | Aggregation.limit | 用来限制MongoDB聚合管道返回的文档数 |
$skip | Aggregation.skip | 在聚合管道中跳过指定数量的文档 |
$unwind | Aggregation.unwind | 将文档中的某一个数组类型字段拆分成多条 |
$group | Aggregation.group | 将集合中的文档分组,可用于统计结果 |
$sort | Aggregation.sort | 将输入文档排序后输出 |
$geoNear | Aggregation.geoNear | 输出接近某一地理位置的有序文档 |
聚合内容操作
下面是基于聚合操作(Aggregation.group),mongodb提供可选的表达式
聚合表达式 | java接口 | 说明 |
---|---|---|
$sum | Aggregation.group().sum(“field”).as(“sum”) | 求和 |
$avg | Aggregation.group().avg(“field”).as(“avg”) | 求平均 |
$min | Aggregation.group().min(“field”).as(“min”) | 获取集合中所有文档对应值得最小值 |
$max | Aggregation.group().max(“field”).as(“max”) | 获取集合中所有文档对应值得最大值 |
$push | Aggregation.group().push(“field”).as(“push”) | 在结果文档中插入值到一个数组中 |
$addToSet | Aggregation.group().addToSet(“field”).as(“addToSet”) | 在结果文档中插入值到一个数组中,但不创建副本 |
$first | Aggregation.group().first(“field”).as(“first”) | 根据资源文档的排序获取第一个文档数据 |
$last | Aggregation.group().last(“field”).as(“last”) | 根据资源文档的排序获取最后一个文档数据 |
聚合管道的实际使用
Group聚合操作
@Overridepublic List<GroupVo> getAggGroup() {GroupOperation noRepeatGroup = Aggregation.group( "userId","type").count().as("num").sum("totalProduct").as("count");TypedAggregation<Order> noRepeatAggregation =Aggregation.newAggregation(Order.class,noRepeatGroup);AggregationResults<GroupVo> noRepeatDataInfoVos = mongoTemplate.aggregate(noRepeatAggregation, GroupVo.class);List<GroupVo> noRepeatDataList = noRepeatDataInfoVos.getMappedResults();System.out.println(JSON.toJSONString(noRepeatDataList));return noRepeatDataList;}
上面例子中对order
集合中的userId
和type
进行分组,使用count
获取总数并映射到num
字段中,对totalProduct
字段进行求和并映射到count
字段中。在所有的Group聚合操作中,除了count
之外,其他操作使用格式基本上都是相同的。其在JAVA中的调用都是使用下面格式
GroupOperation noRepeatGroup = Aggregation.group( {分组字段1},{分组字段2}).count().as({count结果映射的字段}).sum({需要进行sum的字段}).as({sum结果映射的字段})
project操作
@Overridepublic List<GroupVo> getAggProject() {// 重排的GroupOperation noRepeatGroup = Aggregation.group( "userId","type").count().as("num").sum("totalProduct").as("count");Field field = Fields.field("num2", "num");ProjectionOperation project = Aggregation.project("userId","type").andInclude(Fields.from(field));TypedAggregation<Order> noRepeatAggregation =Aggregation.newAggregation(Order.class,noRepeatGroup,project);AggregationResults<GroupVo> noRepeatDataInfoVos = mongoTemplate.aggregate(noRepeatAggregation, GroupVo.class);List<GroupVo> noRepeatDataList = noRepeatDataInfoVos.getMappedResults();System.out.println(JSON.toJSONString(noRepeatDataList));return noRepeatDataList;}
project主要作用就是调整文档的字段内容。比如上面内容中获取数据条目数最开始映射到num字段中,但是在下面Field field = Fields.field("num2", "num")
这里将num的映射转为了num2的映射。这个方法在后续使用lookup进行联表查询的时候会非常有用。因为正常进行联表查询的时候被连接表会作为结果集中的子集出现,而使用project可以将子集数据作为文档的同一层级数据展示出来。
关于match
,unwind
,sort
我会在后面的联表查询、分组去重内容里面来介绍
Bucket操作
在使用聚合管道的时候,可以使用Aggregation.bucket
将数据根据某些范围分为多个桶,或者使用Aggregation.bucketAuto
将数据分为指定数量的桶。
- Aggregation.bucket
Aggregation.bucket方法允许使用者设置一个字段,以及一个多段的查询区间。mongodb将根据这个字段的内容以及设置的分组区间生成多个数据桶。我们可以获取每个桶的聚合结果。下面的例子中就是将Order集合中的数据根据type字段的值分为[0,1),[1,2),[2,3),[3,other)四组。
@Overridepublic List<BucketVo> getAggBucket() {BucketOperation bucketOperation =// 分组的字段Aggregation.bucket("type")// 根据范围进行分组.withBoundaries(0,1,2,3)// 默认分组.withDefaultBucket("other")// 求总.andOutput("_id").count().as("count")// 求和.andOutput("totalProduct").sum().as("sum")// 求平均.andOutput("totalMoney").avg().as("avg");TypedAggregation<Order> newAggregation =Aggregation.newAggregation(Order.class, bucketOperation);AggregationResults<BucketVo> noRepeatDataInfoVos2 =mongoTemplate.aggregate(newAggregation, BucketVo.class);return noRepeatDataInfoVos2.getMappedResults();}
字段介绍
- bucket:需要进行分桶依据的字段
- withBoundaries:分桶区间的范围内容,需要注意的是这个范围是包含前一个条件的值不包含后一个条件的值
- withDefaultBucket:所有没被设定范围统计到的数据会被放入到other这个桶中,其中other是这个桶的id
- andOutput:需要输出的内容,一般是针对某个字段的聚合结果
- Aggregation.bucketAuto
bucketAuto是指定的参数和字段,根据对应字段的内容,将数据平均分配为指定数量的桶。比如下面例子中数据根据type字段中的值分成2组
@Overridepublic List<BucketVo> getAggBucketAuto() {// 分组的字段BucketAutoOperation autoOperation = Aggregation.bucketAuto("type", 2)// 求总.andOutput("_id").count().as("count")// 求和.andOutput("totalProduct").sum().as("sum")// 求平均.andOutput("totalMoney").avg().as("avg");TypedAggregation<Order> newAggregation =Aggregation.newAggregation(Order.class, autoOperation);AggregationResults<BucketVo> noRepeatDataInfoVos2 =mongoTemplate.aggregate(newAggregation, BucketVo.class);return noRepeatDataInfoVos2.getMappedResults();}
字段介绍
bucketAuto: 需要设置进行分桶依据的字段,以及需要分的桶数量
andOutput:需要输出的内容,一般是针对某个字段的聚合结果
个人水平有限,上面的内容可能存在没有描述清楚或者错误的地方,假如开发同学发现了,请及时告知,我会第一时间修改相关内容,也希望大家看在这个新春佳节只能宅到家中埋头苦逼的码代码的情况下,能给我点一个赞。你的点赞就是我前进的动力。在这里也祝大家新春快乐。
Spring Boot 整合——MongoDB整合3(MongoDB聚合操作)相关推荐
- Spring Boot 2.x整合Quartz
宣传官网 xb.exrick.cn 在线Demo xboot.exrick.cn 开源版Github地址 github.com/Exrick/x-bo- 开发文档 www.kancloud.cn/ex ...
- spring boot使用Jedis整合Redis
文章目录 spring boot使用jedis整合redis 总结 Spring Boot整合Redis有两种方式,分别是Jedis和RedisTemplate,那么它们二者有什么区别呢? 1.Jed ...
- [Spring Boot]Druid datasource整合及配置
[Spring Boot]Druid datasource整合及配置 创建Spring Boot项目 这里使用默认配置创建一个空项目 demo-druid 用作演示,可跳过这一段: 只勾选基本的Spr ...
- 重拾后端之Spring Boot(二):MongoDB的无缝集成
重拾后端之Spring Boot(一):REST API的搭建可以这样简单 重拾后端之Spring Boot(二):MongoDb的无缝集成 重拾后端之Spring Boot(三):找回熟悉的Cont ...
- 轻轻松松学习SpringBoot2:第二十六篇: Spring Boot和Redis整合(完整版)
前面我们讲了Spring Boot和Mongodb数据库整合,今天说一下和另一个nosql的整合:redis redis安装就不说了,例子用的是win10版的redis(去git上下载,然后解压,然后 ...
- Spring Boot 2.X整合Spring-cache,让你的网站速度飞起来
计算机领域有人说过一句名言:"计算机科学领域的任何问题都可以通过增加一个中间层来解决",今天我们就用Spring-cache给网站添加一层缓存,让你的网站速度飞起来. 本文目录 一 ...
- Spring Boot与MyBatis整合
2019独角兽企业重金招聘Python工程师标准>>> 数据库以MySQL为例 IDE:spring tool suite 1. 新建项目 file -> new -> ...
- Spring Boot 2.x整合Apollo代码示例
不与spring boot进行整合时,需要给定的VM opitions是如下这些: 与spring boot进行整合时,需要给定的VM opitions是如下这些:
- Spring Boot定时任务-SpringBoot整合Quartz
如何通过SpringBoot整合Quartz框架,我们首先去创建一个项目,接下来我们需要在pom文件里添加坐标,我们在使用SpringBoot整合Quartz的时候,需要添加哪些坐标呢,我们来看一下, ...
- Spring Boot + Mybatis 快速整合
引言 最近在工作结束后抽时间学习了一下mybatis的知识,因为之前有学习过,但是经久不用,也未曾踏实地整理,因此有所淡忘. super meeting会议管理系统是我厂最近开发的一套会议预约平台.持 ...
最新文章
- linux 内网共享文件夹_在Linux下访问Windows共享文件夹
- 【CSS古话今说】-- 01.神奇的CSS-BFC在实战中的应用
- 最新综述:对话式检索数据集汇总
- 【Java】基于注解开发初探
- ubuntu下docker环境、php环境以及laravel的安装
- 草稿 图片盒子定时器模式窗口
- 立即更新!SonicWall 公司再次发布SMA 100 0day 固件更新
- text-overflow:ellipsis
- webrtc 共享屏幕延时测试
- GhostXP_SP3 PCOS技术快速装机版 5.7(优化细节 力争完美)
- Eyoucms易优小程序插件2.0版本上线
- python stub_pycharm的python_stubs问题
- 微信公众平台开发--表情符号
- 朋友们求助一个相关实际操作中的设计的问题
- 目标检测, 实例分割, 图像分类, panoptic segmentation文献
- js当前页面打开小窗口 window.open
- 中文分词基础中trie树的实现方式研究
- 放大器的传递函数_谁惧怕电容负载变化?斩波放大器吗?
- 基于jsp(java)超市管理系统的设计和开发(含源文件)
- 【PS2019CC】工具栏找不到某工具怎么办/自定义工具栏的步骤