SpringBoot整合 EasyES (八)

news/2024/7/7 5:54:04 标签: elasticsearch

一直在坑自己家人,对,说的就是你,大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: true
  banner: false
  address: localhost:9200
  # 一些其它的额外配置
  keep-alive-millis: 30000 # 心跳策略时间 单位:ms
  connect-timeout: 5000 # 连接超时时间 单位:ms
  socket-timeout: 600000 # 通信超时时间 单位:ms
  request-timeout: 5000 # 请求超时时间 单位:ms
  connection-request-timeout: 5000 # 连接请求超时时间 单位:ms
  max-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 # 是否开启下划线转驼峰 默认为false
      table-prefix:  # 索引前缀,可用于区分环境  默认为空 用法和MP一样
      id-type: customize # id生成策略 customize为自定义,id值由用户生成,比如取MySQL中的数据id,如缺省此项配置,则id默认策略为es自动生成
      field-strategy: not_empty # 字段更新策略 默认为not_null
      refresh-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;
    @Score
    private 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 # 默认为http
  username: elastic #如果无账号密码则可不配置此行
  password: 123456 #如果无账号密码则可不配置此行

二.一.二 扩展的连接池配置项

easy-es:
  keep-alive-millis: 18000 # 心跳策略时间 单位:ms
  connect-timeout: 5000 # 连接超时时间 单位:ms
  socket-timeout: 5000 # 通信超时时间 单位:ms 
  request-timeout: 5000 # 请求超时时间 单位:ms
  connection-request-timeout: 5000 # 连接请求超时时间 单位:ms
  max-conn-total: 100 # 最大连接数 单位:个
  max-conn-per-route: 100 # 最大连接路由数 单位:个

二.一.三 全局配置

类似于 mp 的配置处理

easy-es:
  banner: false # 默认为true 打印banner 若您不期望打印banner,可配置为false
  global-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 # 是否开启下划线转驼峰 默认为false
      table-prefix: daily_ # 索引前缀,可用于区分环境  默认为空 用法和MP一样
      id-type: customize # id生成策略 customize为自定义,id值由用户生成,比如取MySQL中的数据id,如缺省此项配置,则id默认策略为es自动生成
      field-strategy: not_empty # 字段更新策略 默认为not_null
      enable-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);
    }
}

image-20230411142203035

二.二.二 索引名注解 @IndexName

使用位置, 在 实体类上

@Data
@IndexName("es")
public class EsUser implements Serializable {
    
}

image-20230411142311755

二.二.三 ES主键 @IndexId

使用位置:实体类中被作为ES主键的字段, 对应MP的@TableId注解

    // value 默认为 _id
    @IndexId(type = IdType.CUSTOMIZE)
    private Integer id;

image-20230411142421858

一般是用户自定义配置.

二.二.四 一般属性配置 @IndexField

实体类中被作为ES索引字段的字段

 @IndexField(strategy = FieldStrategy.NOT_EMPTY,fieldType = FieldType.TEXT, analyzer = "ik_max_word")
    private String nickName;
    @IndexField(fieldType = FieldType.INTEGER)
    private Integer age;

image-20230411142600105

二.二.五 得分注解 @Score

​ 实体类中被作为ES查询得分返回的字段

​ 比如需要知道本次匹配查询得分有多少时,可以在实体类中添加一个类型为Float/float的字段,并在该字段上添加@Score注解,在后续查询中,若es有返回当次查询的得分,则此得分会自动映射至此字段

    @Score
    private 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 {
    @Resource
    private EsUserMapper esUserMapper;

    /**
    单个插入
     */
    @Test
    public void insertTest() {
        EsUser esUser = new EsUser();
        esUser.setId(1);
        esUser.setName("岳泽霖");
        esUser.setNickName("小泽霖");
        esUser.setAge(28);
        esUser.setSex("男");
        esUserMapper.insert(esUser);
    }
        /**
    批量插入
     */
    @Test
    public void batchInsertTest() {
        EsUser esUser = new EsUser();
        esUser.setId(2);
        esUser.setName("岳建立");
        esUser.setNickName("小建立");
        esUser.setAge(25);
        esUser.setSex("男");
        // 批量插入
        esUserMapper.insertBatch(Collections.singletonList(esUser));
    }
}
    

三.二 查询操作


    @Test
    public void getByIdTest() {
        EsUser esUser = esUserMapper.selectById(1);
        log.info(">> 查询用户: {}",esUser );
    }

    @Test
    public void selectAllTest() {
        List<EsUser> esUserList = esUserMapper.selectList(new LambdaEsQueryWrapper<>());
        esUserList.forEach(
                n->{
                    log.info("用户信息: {}",n);
                }
        );
    }
    /**
    根据id 批量查询
     */
    @Test
    public void getByIdsTest() {
        List<EsUser> esUserList = esUserMapper.selectBatchIds(Arrays.asList(1,2));
        esUserList.forEach(
                n->{
                    log.info("用户信息: {}",n);
                }
        );
    }
    /**
   查询数量
     */
    @Test
    public void countTest() {

        Long count = esUserMapper.selectCount(new LambdaEsQueryWrapper<>());
        log.info(">>> 总数是: {}", count);
    }

三.三 更新操作

    /**
     更新操作
     */
    @Test
    public 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));
    }
    /**
        批量更新
     */
    @Test
    public void batchUpdateTest() {
        EsUser esUser = esUserMapper.selectById(1);
        esUser.setAge(30);
        esUser.setNickName("批量更新两个蝴蝶飞");

        esUserMapper.updateBatchByIds(Collections.singletonList(esUser));

        log.info(">>> 修改后的数据是: {}" ,esUserMapper.selectById(1));

    }
    /**
      根据条件进行更新
     */
    @Test
    public 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();

    }

三.四 删除操作

@Test
    public void deleteByIdTest() {
        // 根据id 进行删除
        esUserMapper.deleteById(1);
    }
    /**
     根据id 批量删除
     */
    @Test
    public void deleteBatchTest() {
        esUserMapper.deleteBatchIds(Collections.singletonList(2));
    }

    /**
    根据条件批量删除
     */
    @Test
    public void deleteByWrapperTest() throws Exception{
        LambdaEsQueryWrapper<EsUser> esUserLambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();
        esUserLambdaEsQueryWrapper.le(EsUser::getAge,300);

        esUserMapper.delete(esUserLambdaEsQueryWrapper);

        TimeUnit.SECONDS.sleep(2);
        selectAllTest();

    }

四. 查询操作

查询使用到 LambdaEsQueryWrapper 对象

方法基本与 mybatiplus 一致

MysqlEasy-ESes-DSL/es java api
andandmust
ororshould
=eqterm
!=neboolQueryBuilder.mustNot(queryBuilder)
>gtQueryBuilders.rangeQuery(‘es field’).gt()
>=ge.rangeQuery(‘es field’).gte()
<lt.rangeQuery(‘es field’).lt()
<=le.rangeQuery(‘es field’).lte()
like ‘%field%’likeQueryBuilders.wildcardQuery(field,value)
not like ‘%field%’notLikemust not wildcardQuery(field,value)
like ‘%field’likeLeftQueryBuilders.wildcardQuery(field,*value)
like ‘field%’likeRightQueryBuilders.wildcardQuery(field,value*)
betweenbetweenQueryBuilders.rangeQuery(‘es field’).from(xx).to(xx)
notBetweennotBetweenmust not QueryBuilders.rangeQuery(‘es field’).from(xx).to(xx)
is nullisNullmust not QueryBuilders.existsQuery(field)
is notNullisNotNullQueryBuilders.existsQuery(field)
ininQueryBuilders.termsQuery(" xx es field", xx)
not innotInmust not QueryBuilders.termsQuery(" xx es field", xx)
group bygroupByAggregationBuilders.terms()
order byorderByfieldSortBuilder.order(ASC/DESC)
minminAggregationBuilders.min
maxmaxAggregationBuilders.max
avgavgAggregationBuilders.avg
sumsumAggregationBuilders.sum
order by xxx ascorderByAscfieldSortBuilder.order(SortOrder.ASC)
order by xxx descorderByDescfieldSortBuilder.order(SortOrder.DESC)
-matchmatchQuery
-matchPhraseQueryBuilders.matchPhraseQuery
-matchPrefixQueryBuilders.matchPhrasePrefixQuery
-queryStringQueryQueryBuilders.queryStringQuery
select *matchAllQueryQueryBuilders.matchAllQuery()
-highLightHighlightBuilder.Field

先批量添加, 提前准备好数据

@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class SearchTest {
    @Resource
    private EsUserMapper esUserMapper;

    @Resource
    private RestHighLevelClient restHighLevelClient;

    @Test
    public 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

@Test
    public 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);
                }
        );
    }

image-20230411144634744

四.二 and 组合

    @Test
    public 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);
    }

image-20230411144711211

四.三 or 组合

    @Test
    public 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);
    }

image-20230411144741250

四.四 配置原始 restHighLevelClient 查询


 @Resource
    private RestHighLevelClient restHighLevelClient;

    /**
        原先查询
     */
    @Test
    public 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(">>>> 查询结果输出结束");
    }


四.五 分页查询

    /**
    分页查询
     */
    @Test
    public void pageTest() {
        LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();
        EsPageInfo<EsUser> esUserPageInfo = esUserMapper.pageQuery(lambdaEsQueryWrapper, 1, 2);
        log.info(">>> 总数是: {}" ,esUserPageInfo.getTotal());
        printInfo(esUserPageInfo.getList());
    }

image-20230411144859974

四.六 排序

    /**
     排序查询
     */
    @Test
    public 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());
    }

image-20230411144941905

四.七 获取 Dsl 数据

    /**
      获取 Dsl 数据
     */
    @Test
    public void getDslTest() {
        LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();
        // 进行排序
        lambdaEsQueryWrapper.orderByDesc(EsUser::getId);
        // from size
        lambdaEsQueryWrapper.limit((1-1) * 5,5);

        String source = esUserMapper.getSource(lambdaEsQueryWrapper);

        log.info(">>> 执行语句: {}", source);
    }

image-20230411145020903

四.八 查询部分字段

四.八.一 只查询部分字段

    /**
    只查询字段
     */
    @Test
    public 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);
    }

image-20230411145104756

四.八.二 不查询某些字段

    /**
   不查询字段
     */
    @Test
    public 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);
    }

image-20230411145144029

四.九 单字段去重

    /**
     单字段去重
     */
    @Test
    public void dictTest() {
        LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();
        lambdaEsQueryWrapper.distinct(EsUser::getAge);
        List<EsUser> esUserList = esUserMapper.selectList(lambdaEsQueryWrapper);
        printInfo(esUserList);
    }

image-20230411145241213

只查询出来四条记录

四.十 分组查询

    @Test
    public void groupTest() {
        LambdaEsQueryWrapper<EsUser> lambdaEsQueryWrapper = new LambdaEsQueryWrapper<>();
        lambdaEsQueryWrapper.groupBy(EsUser::getAge);
        SearchResponse searchResponse = esUserMapper.search(lambdaEsQueryWrapper);
        log.info(">>> 查询数据: {}" ,searchResponse);
    }

image-20230411145342074

配置最大,最小

  @Test
    public 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);
    }

image-20230411145438843


本章节的代码放置在 github 上:

https://github.com/yuejianli/springboot/tree/develop/SpringBoot_EasyES

谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!


http://www.niftyadmin.cn/n/209350.html

相关文章

Linux基础知识——Linux压缩解压

压缩和解压&#xff08;针对tar、gzip、zip三种压缩格式&#xff09; tar命令 主要针对.tar和.gz格式压缩文件。 前者称之为tarball&#xff0c;归档文件&#xff0c;将文件组装到.tar文件&#xff0c;并没有体积的减少&#xff0c;只是简单的封装。后者为gzip压缩文件&…

计算专题(小计算题)

考点&#xff1a; 1.沟通渠道的总量为 n*(n-1)/2&#xff0c;其中 n 代表干系人的数量。 2.决策树计算/自制和外购决策-----EMV。 3.盈亏平衡计算。&#xff08;刚好不亏也不赚&#xff09; 【案例】假设某IT服务企业&#xff0c;其固定成本为30万元&#xff0c;每项服务的变…

企业为什么要做网站?这篇文章告诉你

在如今数字化的时代&#xff0c;企业为什么要做网站&#xff1f;这个问题一直都是企业主和市场营销人员必须要考虑的问题。本文将以一个真实的案例为例&#xff0c;解析为什么企业要做网站以及如何通过网站提升业务和品牌的影响力。 案例背景 以一家小型私人医疗诊所为例&…

Spring AOP及事务说明

目录 1.事务管理 1.1 事务说明 1.2 Spring事务管理 1.3 事务进阶 (1)Transactional属性说明 (2)rollbackFor属性 (3)propagation属性 1.4 总结 2.AOP 2.1 AOP概述 2.2 AOP核心概念 2.3 AOP进阶 (1) 通知类型 (2)切点表达式 (3) 通知顺序 (4)连接点 1.事务管理 …

【C++基础】函数重载(函数重载的概念及意义;C++支持函数重载的原理;C++程序调用C静态库;C程序调用C++静态库)

五、函数重载 5.1 函数重载的概念及意义 函数重载&#xff1a;是函数的一种特殊情况&#xff0c;C允许在同一作用域中声明几个功能类似的同名函数&#xff0c;这些同名函数的形参列表(参数个数、类型、类型顺序)不同&#xff0c;常用来处理实现功能类似数据类型不同的问题。 …

dc-4靶机渗透

1.信息搜集&#xff0c;扫描存活主机&#xff0c;扫描端口&#xff0c;服务,发现开放80&#xff0c;22端口&#xff0c;cms没有看到 nmap 192.168.85.0/24 nmap -p1-66535 192.168.85.175 nmap -sv 192.168.85.1752.访问网站&#xff0c;发现登录框&#xff0c;根据提示&#…

数据结构第三次作业(树结构--递归算法)

设计算法&#xff0c;递归的计算二叉树的高度 1&#xff09;算法思想 2&#xff09;伪代码 int TreeDepth(TreeNode root) { if(rootnull) return 0; int left TreeDepth(root.left); int right TreeDepth(root.right); return Math.max(…

mall商城之基础服务部署-1

文章目录 一、服务器规划二、镜像打包及推送1)下载源码2)部署docker3)docker-compose说明1、部署docker-compose2、docker-compose.yml常用命令3、Docker Compose常用命令4、编写docker-compose.yml文件4)部署基础服务1、部署镜像详情2、下载需要镜像3、elasticsearch4、ng…