SpringBoot整合 EasyES (八)
一直在坑自己家人,对,说的就是你,大A.
上一章简单介绍了SpringBoot整合ES 实现简单项目(七), 如果没有看过,请观看上一章
Mybatis 有增强性的 MybatisPlus, ES 有增强性的吗? 有的, easy-es
Easy-Es(简称EE)是一款基于ElasticSearch(简称Es)官方提供的RestHighLevelClient打造的ORM开发框架,
在 RestHighLevelClient 的基础上,只做增强不做改变,为简化开发、提高效率而生,
您如果有用过Mybatis-Plus(简称MP),那么您基本可以零学习成本直接上手EE,EE是MP的Es平替版,
在有些方面甚至比MP更简单,同时也融入了更多Es独有的功能,助力您快速实现各种场景的开发.
官网地址: https://www.easy-es.cn/pages/v1.x/1cebb8/
EE的主要特性如下:
- 全自动索引托管:开发者无需关心索引的创建、更新及数据迁移等繁琐步骤,框架能自动完成。
- 屏蔽语言差异:开发者只需要会MySQL的语法即可使用ES。
- 代码量极少:与直接使用官方提供的RestHighLevelClient相比,相同的查询平均可以节省3-5倍的代码量。
- 零魔法值:字段名称直接从实体中获取,无需手写。
- 零额外学习成本: 开发者只要会国内最受欢迎的Mybatis-Plus用法,即可无缝迁移至EE。
一. SpringBoot 整合 Easy-Es
一.一 添加依赖
一.一.一 去除 spring-boot-starter-web 携带的 es 版本
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId></exclusion><exclusion><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId></exclusion></exclusions></dependency>
一.一.二 添加 easy-es 和相应的依赖
<!--引入 spring-data-elasticsearch--><dependency><groupId>cn.easy-es</groupId><artifactId>easy-es-boot-starter</artifactId><version>1.1.1</version></dependency><!--添加依赖--><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.14.0</version></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>7.8.0</version></dependency><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.14.0</version></dependency>
一.二 easy-es 配置 application.yml
easy-es:enable: truebanner: falseaddress: localhost:9200# 一些其它的额外配置keep-alive-millis: 30000 # 心跳策略时间 单位:msconnect-timeout: 5000 # 连接超时时间 单位:mssocket-timeout: 600000 # 通信超时时间 单位:msrequest-timeout: 5000 # 请求超时时间 单位:msconnection-request-timeout: 5000 # 连接请求超时时间 单位:msmax-conn-total: 100 # 最大连接数 单位:个max-conn-per-route: 100 # 最大连接路由数 单位:个global-config:process-index-mode: smoothly #索引处理模式,smoothly:平滑模式,默认开启此模式, not_smoothly:非平滑模式, manual:手动模式print-dsl: true # 开启控制台打印通过本框架生成的DSL语句,默认为开启,测试稳定后的生产环境建议关闭,以提升少量性能distributed: false # 当前项目是否分布式项目,默认为true,在非手动托管索引模式下,若为分布式项目则会获取分布式锁,非分布式项目只需synchronized锁.db-config:map-underscore-to-camel-case: false # 是否开启下划线转驼峰 默认为falsetable-prefix: # 索引前缀,可用于区分环境 默认为空 用法和MP一样id-type: customize # id生成策略 customize为自定义,id值由用户生成,比如取MySQL中的数据id,如缺省此项配置,则id默认策略为es自动生成field-strategy: not_empty # 字段更新策略 默认为not_nullrefresh-policy: immediate # 数据刷新策略,默认为不刷新
# 配置日志
logging:level:# # 开启trace级别日志,在开发时可以开启此配置,则控制台可以打印es全部请求信息及DSL语句,# 为了避免重复,开启此项配置后,可以将EE的print-dsl设置为false.tracer: trace
一.三 启动类配置扫描
使用 EsMapperScan 注解,进行配置扫描
@SpringBootApplication
@EsMapperScan("top.yueshushu.learn.esmapper")
public class EasyESApp {public static void main(String[] args) {SpringApplication.run(EasyESApp.class,args);}
}
一.四 配置实体 EsUser
@Data
@IndexName("es")
public class EsUser implements Serializable {// value 默认为 _id@IndexId(type = IdType.CUSTOMIZE)private Integer id;@IndexField(strategy = FieldStrategy.NOT_EMPTY, fieldType = FieldType.TEXT, analyzer = "ik_max_word")/* 需要被高亮的字段*/@HighLight(mappingField = "nameHighlightContent", preTag = "<font color='red'>", postTag = "</font>")private String name;@IndexField(strategy = FieldStrategy.NOT_EMPTY,fieldType = FieldType.TEXT, analyzer = "ik_max_word")private String nickName;@IndexField(fieldType = FieldType.INTEGER)private Integer age;@IndexField(fieldType = FieldType.KEYWORD_TEXT)private String sex;@Scoreprivate Float score;// 不存在@IndexField(exist = false)private String description;// 不存在@IndexField(exist = false)private Integer maxAge;@IndexField(exist = false)private Integer minAge;@IndexField(exist = false)private String nameHighlightContent;
}
使用一些配置注解 @IndexName @IndexId @IndexField
一.五 配置 Mapper
继承 BaseEsMapper 接口
public interface EsUserMapper extends BaseEsMapper<EsUser> {}
这样,基本的配置就算是处理完成了, 后续 使用 EsUserMapper 即可以操作.
二. Easy-ES 配置项和注解
二.一 配置项
二.一.一 基础配置项
easy-es:enable: true # 是否开启EE自动配置address : 127.0.0.1:9200 # es连接地址+端口 格式必须为ip:port,如果是集群则可用逗号隔开schema: http # 默认为httpusername: elastic #如果无账号密码则可不配置此行password: 123456 #如果无账号密码则可不配置此行
二.一.二 扩展的连接池配置项
easy-es:keep-alive-millis: 18000 # 心跳策略时间 单位:msconnect-timeout: 5000 # 连接超时时间 单位:mssocket-timeout: 5000 # 通信超时时间 单位:ms request-timeout: 5000 # 请求超时时间 单位:msconnection-request-timeout: 5000 # 连接请求超时时间 单位:msmax-conn-total: 100 # 最大连接数 单位:个max-conn-per-route: 100 # 最大连接路由数 单位:个
二.一.三 全局配置
类似于 mp 的配置处理
easy-es:banner: false # 默认为true 打印banner 若您不期望打印banner,可配置为falseglobal-config:process-index-mode: smoothly #索引处理模式,smoothly:平滑模式,默认开启此模式, not_smoothly:非平滑模式, manual:手动模式print-dsl: true # 开启控制台打印通过本框架生成的DSL语句,默认为开启,测试稳定后的生产环境建议关闭,以提升少量性能distributed: false # 当前项目是否分布式项目,默认为true,在非手动托管索引模式下,若为分布式项目则会获取分布式锁,非分布式项目只需synchronized锁.async-process-index-blocking: true # 异步处理索引是否阻塞主线程 默认阻塞 数据量过大时调整为非阻塞异步进行 项目启动更快active-release-index-max-retry: 60 # 分布式环境下,平滑模式,当前客户端激活最新索引最大重试次数若数据量过大,重建索引数据迁移时间超过60*(180/60)=180分钟时,可调大此参数值,此参数值决定最大重试次数,超出此次数后仍未成功,则终止重试并记录异常日志active-release-index-fixed-delay: 180 # 分布式环境下,平滑模式,当前客户端激活最新索引最大重试次数 若数据量过大,重建索引数据迁移时间超过60*(180/60)=180分钟时,可调大此参数值 此参数值决定多久重试一次 单位:秒db-config:map-underscore-to-camel-case: false # 是否开启下划线转驼峰 默认为falsetable-prefix: daily_ # 索引前缀,可用于区分环境 默认为空 用法和MP一样id-type: customize # id生成策略 customize为自定义,id值由用户生成,比如取MySQL中的数据id,如缺省此项配置,则id默认策略为es自动生成field-strategy: not_empty # 字段更新策略 默认为not_nullenable-track-total-hits: true # 默认开启,开启后查询所有匹配数据,若不开启,会导致无法获取数据总条数,其它功能不受影响,若查询数量突破1W条时,需要同步调整@IndexName注解中的maxResultWindow也大于1w,并重建索引后方可在后续查询中生效(不推荐,建议分页查询).refresh-policy: immediate # 数据刷新策略,默认为不刷新enable-must2-filter: false # 是否全局开启must查询类型转换为filter查询类型 默认为false不转换batch-update-threshold: 10000 # 批量更新阈值 默认值为1万
其中,主要的属性有 :
global-config.print-dsl: true
global-config.db-config.id-type: customize
global-config.db-config.field-strategy: not_empty
global-config.db-config.refresh-policy: immediate
- id-type支持3种类型:
- auto: 由ES自动生成,是默认的配置,无需您额外配置 推荐
- uuid: 系统生成UUID,然后插入ES (不推荐)
- customize: 用户自定义,在此类型下,用户可以将任意数据类型的id存入es作为es中的数据id,比如将mysql自增的id作为es的id,可以开启此模式,或通过@TableId(type)注解指定.
- field-strategy支持3种类型:
- not_null: 非Null判断,字段值为非Null时,才会被更新
- not_empty: 非空判断,字段值为非空字符串时才会被更新
- ignore: 忽略判断,无论字段值为什么,都会被更新
- 在配置了全局策略后,您仍可以通过注解针对个别类进行个性化配置,全局配置的优先级是小于注解配置的
- refresh-policy支持3种策略
- none: 默认策略,不刷新数据
- immediate : 立即刷新,会损耗较多性能,对数据实时性要求高的场景下适用
- wait_until: 请求提交数据后,等待数据完成刷新(1s),再结束请求 性能损耗适中
二.一.四 日志配置
logging:level:tracer: trace # 开启trace级别日志
二.二 注解
二.二.一 mapper 扫描注解 @EsMapperScan
位置在Springboot启动类 ,功能与MP的@MapperScan一致
@SpringBootApplication
@EsMapperScan("top.yueshushu.learn.esmapper")
public class EasyESApp {public static void main(String[] args) {SpringApplication.run(EasyESApp.class,args);}
}
二.二.二 索引名注解 @IndexName
使用位置, 在 实体类上
@Data
@IndexName("es")
public class EsUser implements Serializable {}
二.二.三 ES主键 @IndexId
使用位置:实体类中被作为ES主键的字段, 对应MP的@TableId注解
// value 默认为 _id@IndexId(type = IdType.CUSTOMIZE)private Integer id;
一般是用户自定义配置.
二.二.四 一般属性配置 @IndexField
实体类中被作为ES索引字段的字段
@IndexField(strategy = FieldStrategy.NOT_EMPTY,fieldType = FieldType.TEXT, analyzer = "ik_max_word")private String nickName;@IndexField(fieldType = FieldType.INTEGER)private Integer age;
二.二.五 得分注解 @Score
实体类中被作为ES查询得分返回的字段
比如需要知道本次匹配查询得分有多少时,可以在实体类中添加一个类型为Float/float的字段,并在该字段上添加@Score注解,在后续查询中,若es有返回当次查询的得分,则此得分会自动映射至此字段
@Scoreprivate Float score;
二.二.六 高亮注解 @HighLight
配置高亮信息
/* 需要被高亮的字段*/@HighLight(mappingField = "nameHighlightContent", preTag = "<font color='red'>", postTag = "</font>")private String name;@IndexField(exist = false)private String nameHighlightContent;
一般会配置一下 mappingField, 这样就不会修改之前的 name 属性了.
三. 基础的操作
跟 MybatisPlus 基本是一样的, 这里就不作过多的讲解了。
三.一 单个插入和批量插入
@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class BaseEsTest {@Resourceprivate EsUserMapper esUserMapper;/单个插入*/@Testpublic void insertTest() {EsUser esUser = new EsUser();esUser.setId(1);esUser.setName("岳泽霖");esUser.setNickName("小泽霖");esUser.setAge(28);esUser.setSex("男");esUserMapper.insert(esUser);}/批量插入*/@Testpublic void batchInsertTest() {EsUser esUser = new EsUser();esUser.setId(2);esUser.setName("岳建立");esUser.setNickName("小建立");esUser.setAge(25);esUser.setSex("男");// 批量插入esUserMapper.insertBatch(Collections.singletonList(esUser));}
}
三.二 查询操作
@Testpublic void getByIdTest() {EsUser esUser = esUserMapper.selectById(1);log.info(">> 查询用户: {}",esUser );}@Testpublic void selectAllTest() {List<EsUser> esUserList = esUserMapper.selectList(new LambdaEsQueryWrapper<>());esUserList.forEach(n->{log.info("用户信息: {}",n);});}/根据id 批量查询*/@Testpublic void getByIdsTest() {List<EsUser> esUserList = esUserMapper.selectBatchIds(Arrays.asList(1,2));esUserList.forEach(n->{log.info("用户信息: {}",n);});}/查询数量*/@Testpublic void countTest() {Long count = esUserMapper.selectCount(new LambdaEsQueryWrapper<>());log.info(">>> 总数是: {}", count);}
三.三 更新操作
/更新操作*/@Testpublic void updateTest() {log.info(">>> 之前的数据是: {}" ,esUserMapper.selectById(1));EsUser esUser = esUserMapper.selectById(1);esUser.setAge(29);esUser.setNickName("两个蝴蝶飞");// 进行更新esUserMapper.updateById(esUser);log.info(">>> 修改后的数据是: {}" ,esUserMapper.selectById(1));}/批量更新*/@Testpublic void batchUpdateTest() {EsUser esUser = esUserMapper.selectById(1);esUser.setAge(30);esUser.setNickName("批量更新两个蝴蝶飞");esUserMapper.updateBatchByIds(Collections.singletonList(esUser));log.info(">>> 修改后的数据是: {}" ,esUserMapper.selectById(1));}/根据条件进行更新*/@Testpublic void updateByWrapperTest() throws Exception{LambdaEsUpdateWrapper<EsUser> esUserLambdaEsUpdateWrapper = new LambdaEsUpdateWrapper<>();esUserLambdaEsUpdateWrapper.le(EsUser::getAge,300);EsUser esUser = new EsUser();esUser.setNickName("根据条件更新2");esUser.setAge(33);esUserMapper.update(esUser,esUserLambdaEsUpdateWrapper);selectAllTest();}
三.四 删除操作
@Testpublic void deleteByIdTest() {// 根据id 进行删除esUserMapper.deleteById(1);}/根据id 批量删除*/@Testpublic void deleteBatchTest() {esUserMapper.deleteBatchIds(Collections.singletonList(2));}/根据条件批量删除*/@Testpublic void deleteByWrapperTest() throws Exception{LambdaEsQueryWrapper<EsUser> esUserLambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();esUserLambdaEsQueryWrapper.le(EsUser::getAge,300);esUserMapper.delete(esUserLambdaEsQueryWrapper);TimeUnit.SECONDS.sleep(2);selectAllTest();}
四. 查询操作
查询使用到 LambdaEsQueryWrapper 对象
方法基本与 mybatiplus 一致
Mysql | Easy-ES | es-DSL/es java api |
---|---|---|
and | and | must |
or | or | should |
= | eq | term |
!= | ne | boolQueryBuilder.mustNot(queryBuilder) |
> | gt | QueryBuilders.rangeQuery(‘es field’).gt() |
>= | ge | .rangeQuery(‘es field’).gte() |
< | lt | .rangeQuery(‘es field’).lt() |
<= | le | .rangeQuery(‘es field’).lte() |
like ‘%field%’ | like | QueryBuilders.wildcardQuery(field,value) |
not like ‘%field%’ | notLike | must not wildcardQuery(field,value) |
like ‘%field’ | likeLeft | QueryBuilders.wildcardQuery(field,*value) |
like ‘field%’ | likeRight | QueryBuilders.wildcardQuery(field,value*) |
between | between | QueryBuilders.rangeQuery(‘es field’).from(xx).to(xx) |
notBetween | notBetween | must not QueryBuilders.rangeQuery(‘es field’).from(xx).to(xx) |
is null | isNull | must not QueryBuilders.existsQuery(field) |
is notNull | isNotNull | QueryBuilders.existsQuery(field) |
in | in | QueryBuilders.termsQuery(" xx es field", xx) |
not in | notIn | must not QueryBuilders.termsQuery(" xx es field", xx) |
group by | groupBy | AggregationBuilders.terms() |
order by | orderBy | fieldSortBuilder.order(ASC/DESC) |
min | min | AggregationBuilders.min |
max | max | AggregationBuilders.max |
avg | avg | AggregationBuilders.avg |
sum | sum | AggregationBuilders.sum |
order by xxx asc | orderByAsc | fieldSortBuilder.order(SortOrder.ASC) |
order by xxx desc | orderByDesc | fieldSortBuilder.order(SortOrder.DESC) |
- | match | matchQuery |
- | matchPhrase | QueryBuilders.matchPhraseQuery |
- | matchPrefix | QueryBuilders.matchPhrasePrefixQuery |
- | queryStringQuery | QueryBuilders.queryStringQuery |
select * | matchAllQuery | QueryBuilders.matchAllQuery() |
- | highLight | HighlightBuilder.Field |
先批量添加, 提前准备好数据
@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class SearchTest {@Resourceprivate EsUserMapper esUserMapper;@Resourceprivate RestHighLevelClient restHighLevelClient;@Testpublic void batchInsertTest() {EsUser esUser1 = new EsUser();esUser1.setId(1);esUser1.setName("岳泽霖");esUser1.setNickName("小泽霖");esUser1.setAge(28);esUser1.setSex("男");EsUser esUser2 = new EsUser();esUser2.setId(2);esUser2.setName("岳建立");esUser2.setNickName("小建立");esUser2.setAge(26);esUser2.setSex("男");EsUser esUser3 = new EsUser();esUser3.setId(3);esUser3.setName("张三");esUser3.setNickName("张三");esUser3.setAge(24);esUser3.setSex("男");EsUser esUser4 = new EsUser();esUser4.setId(4);esUser4.setName("李四");esUser4.setNickName("李四");esUser4.setAge(24);esUser4.setSex("女");EsUser esUser5 = new EsUser();esUser5.setId(5);esUser5.setName("王二");esUser5.setNickName("王二");esUser5.setAge(16);esUser5.setSex("女");List<EsUser> userList = new ArrayList<>();userList.add(esUser1);userList.add(esUser2);userList.add(esUser3);userList.add(esUser4);userList.add(esUser5);esUserMapper.insertBatch(userList);}
}
只列举信息
四.一 equals
@Testpublic void equalsTest() {LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();// String name = "岳泽霖";String name = "霖";lambdaEsQueryWrapper.eq(StringUtils.hasText(name), EsUser::getName,name);List<EsUser> esUserList = esUserMapper.selectList(lambdaEsQueryWrapper);printInfo(esUserList);}public void printInfo( List<EsUser> esUserList) {if (CollectionUtils.isEmpty(esUserList)){log.info(">>>> 未查询出用户信息");return ;}esUserList.forEach(n->{log.info("用户信息: {}" ,n);});}
四.二 and 组合
@Testpublic void andTest() {LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();String name = "霖";String sex = "男";lambdaEsQueryWrapper.eq(StringUtils.hasText(name), EsUser::getName,name);lambdaEsQueryWrapper.eq(StringUtils.hasText(sex), EsUser::getSex,sex);List<EsUser> esUserList = esUserMapper.selectList(lambdaEsQueryWrapper);printInfo(esUserList);}
四.三 or 组合
@Testpublic void orTest() {LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();String name = "霖";String sex = "男";lambdaEsQueryWrapper.eq(StringUtils.hasText(name), EsUser::getName,name);lambdaEsQueryWrapper.or().eq(StringUtils.hasText(sex), EsUser::getSex,sex);List<EsUser> esUserList = esUserMapper.selectList(lambdaEsQueryWrapper);printInfo(esUserList);}
四.四 配置原始 restHighLevelClient 查询
@Resourceprivate RestHighLevelClient restHighLevelClient;/原先查询*/@Testpublic void originTest() throws Exception{SearchRequest searchRequest = new SearchRequest();// 设置索引searchRequest.indices("es");/构建条件*/SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();searchSourceBuilder.query(QueryBuilders.matchAllQuery());searchRequest.source(searchSourceBuilder);// 进行请求SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);SearchHits result = searchResponse.getHits();log.info(">>> 花费的时间:{}", searchResponse.getTook());log.info(">>>是否超时:{}", searchResponse.isTimedOut());log.info(">>>> 总的数量:{}", result.getTotalHits());log.info(">>>>最大的匹配分数值:{}", result.getMaxScore());log.info(">>>>查询结果输出开始");Arrays.stream(result.getHits()).forEach(n -> log.info(">>>获取内容:{}", n.getSourceAsString()));log.info(">>>> 查询结果输出结束");}
四.五 分页查询
/分页查询*/@Testpublic void pageTest() {LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();EsPageInfo<EsUser> esUserPageInfo = esUserMapper.pageQuery(lambdaEsQueryWrapper, 1, 2);log.info(">>> 总数是: {}" ,esUserPageInfo.getTotal());printInfo(esUserPageInfo.getList());}
四.六 排序
/排序查询*/@Testpublic void orderTest() {LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();// 进行排序lambdaEsQueryWrapper.orderByDesc(EsUser::getId);EsPageInfo<EsUser> esUserPageInfo = esUserMapper.pageQuery(lambdaEsQueryWrapper, 1, 5);log.info(">>> 总数是: {}" ,esUserPageInfo.getTotal());printInfo(esUserPageInfo.getList());}
四.七 获取 Dsl 数据
/获取 Dsl 数据*/@Testpublic void getDslTest() {LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();// 进行排序lambdaEsQueryWrapper.orderByDesc(EsUser::getId);// from sizelambdaEsQueryWrapper.limit((1-1) * 5,5);String source = esUserMapper.getSource(lambdaEsQueryWrapper);log.info(">>> 执行语句: {}", source);}
四.八 查询部分字段
四.八.一 只查询部分字段
/只查询字段*/@Testpublic void selectTest() {LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();String name = "霖";String sex = "男";lambdaEsQueryWrapper.eq(StringUtils.hasText(name), EsUser::getName,name);lambdaEsQueryWrapper.eq(StringUtils.hasText(sex), EsUser::getSex,sex);lambdaEsQueryWrapper.select(EsUser::getId,EsUser::getName);List<EsUser> esUserList = esUserMapper.selectList(lambdaEsQueryWrapper);printInfo(esUserList);}
四.八.二 不查询某些字段
/不查询字段*/@Testpublic void notSelectTest() {LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();String name = "霖";String sex = "男";lambdaEsQueryWrapper.eq(StringUtils.hasText(name), EsUser::getName,name);lambdaEsQueryWrapper.eq(StringUtils.hasText(sex), EsUser::getSex,sex);lambdaEsQueryWrapper.notSelect(EsUser::getId,EsUser::getAge);List<EsUser> esUserList = esUserMapper.selectList(lambdaEsQueryWrapper);printInfo(esUserList);}
四.九 单字段去重
/单字段去重*/@Testpublic void dictTest() {LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();lambdaEsQueryWrapper.distinct(EsUser::getAge);List<EsUser> esUserList = esUserMapper.selectList(lambdaEsQueryWrapper);printInfo(esUserList);}
只查询出来四条记录
四.十 分组查询
@Testpublic void groupTest() {LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();lambdaEsQueryWrapper.groupBy(EsUser::getAge);SearchResponse searchResponse = esUserMapper.search(lambdaEsQueryWrapper);log.info(">>> 查询数据: {}" ,searchResponse);}
配置最大,最小
@Testpublic void group2Test() {LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();lambdaEsQueryWrapper.groupBy(EsUser::getAge);lambdaEsQueryWrapper.max(EsUser::getMaxAge);lambdaEsQueryWrapper.min(EsUser::getMinAge);SearchResponse searchResponse = esUserMapper.search(lambdaEsQueryWrapper);log.info(">>> 查询数据: {}" ,searchResponse);}
本章节的代码放置在 github 上:
https://github.com/yuejianli/springboot/tree/develop/SpringBoot_EasyES
谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!