开发者

Springboot3整合Elasticsearch8(elasticsearch-java)最佳实践

目录
  • 1、Elasticsearch的Java客户端选择
  • 2、Spring Data Elasticsearch 官方文档
  • 3、Springboot3整合Spring Data Elasticsearch
    • 3.1 maven引入
    • 3.2 配置
  • 4、【简单使用】Spring Data Elasticsearch
    • 4.1 创建ES实体类
      • @Document(indexName = "news")
      • @Id
      • @Field
      • @jsonProperty("publish_date")
    • 4.2 继承ElasticsearchRepository接口
      • 4.3 CRUD接口使用
        • 4.3.1 新增
        • 4.3.3 修改
        • 4.3.3 查询
        • 4.3.4 删除
    • 5、【高阶用法】Elasticsearch Java API Client
      • 6、【最佳实践】Elasticsearch+消息队列(RabbitMQ)+数据库(mysql)

        1、Elasticsearch的JAVA客户端选择

        Elasticsearch官方支持的客户端

        客户端名称简介使用建议
        Elasticsearch Java API Client(新客户端)官方推荐的新客户端,基于 JSON Mapping(如 ElasticsearchClient 类),从 Elasticsearch 7.15 开始推出。✅推荐用于 Spring Boot 3+,Elasticsearch 8+
        RestHighLevelClient(已废弃)基于 REST 的高级客户端,是 ES 6 ~ 7 的主力客户端,ES 8 中已标记为 deprecated。❌不推荐新项目使用
        Low Level REST Client底层客户端,只提供 HTTP 封装,不解析 JSON。

        适合自定义协议或处理特殊 JSON 请求场景

        Spring官方对Elasticsearch的封装

        客户端名称简介特点
        Spring Data ElasticsearchSpring 官方对 Elasticsearch 的数据访问封装,支持 Repository 风格的接口编程。开发效率高、和 JPA 风格一致,但功能不如原生客户端全

        easy-es(dromara团队),国人之光!

        客户端名称简介特点
        easy-es风格类似 MyBATis-Plus,一致的 API 和分页查询方式,Java 开发者易于理解。开发效率高、但是是对RestHighLevelClient的深层封装,容易受版本影响,小团队维护

        总结:

        RestHighLevelClient 是ES7中使用最多的客户端,但是在ES8中已经废弃。

        easy-es  是基于RestHighLevelClient封装的,会比较重,代码风格类似 MyBatis-Plus,熟悉MP的同学容易上手,但是容易受RestHighLevelClient和Elasticsearch版本的限制,并且目前社区虽然活跃,但项目主要靠小团队维护,不如官方客户端那样稳定长期。

        Elasticsearch Java API Client 是 Elasticsearch 7.15 开始推出最新的客户端,能使用Elasticsearch中所有功能,首选首选!!!!!!

        Spring Data Elasticsearch 是Spring 官方对 Elasticsearch的封装,Springboot3中已经弃用了RestHighLevelClient,选择引用了Elasticsearch Java API Client,直接解决了依赖版本冲突的问题,Spring社区强大,所以...不用我说了吧....选我!!!!!

        2、Spring Data Elasticsearch 官方文档

        Elasticsearch Clients :: Spring Data Elasticsearch

        3、Springboot3整合Spring Data Elasticsearch

        tips:我使用的是Springboot3.3.4版本

        3.1 maven引入

                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
                </dependency>

        引入成功之后可以看到:

        Springboot3整合Elasticsearch8(elasticsearch-java)最佳实践

        elasticsearch的新客户端elasticsearch-java也被引入了进来。

        3.2 配置

        yml配置文件

        spring:
          application:
            name: cloud-elasticsearch
          elasticsearch:
            uris: http://127.0.0.1:9200 #  这里还要注意是https还是http协议
        #    username: elastic #如果有账号密码就要配置账号密码,否则可以不配置
        #    password: 123456
        server:
          port: 20000

        4、【简单使用】Spring Data Elasticsearch

        4.1 创建ES实体类

        创建完实体类后,启动项目Spring会自动根据注解,来创建ES的索引(index)和映射(mapping)

        @Data
        @Document(indexName = "news")
        public class EsNews {
            @Id
            private String id;
            @Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer = "ik_smart")
            private String title;//标题
            @Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer = "ik_smart")
            private String content;//内容
            @Field(type = FieldType.Keyword)
            private String author;//作者
            @Field(type = FieldType.Keyword)
            private List<String> tags;//标签
            @Field(type = FieldType.Date,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd")
            @JsonProperty("publish_date")
            private Date publishDate;//发布时间
            @Field(type = FieldType.Date,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd")
            @JsonProperty("create_time")
            private Date createTime;//创建时间
            @Field(type = FieldType.Long)
            @JsonProperty("view_count")
            private Long viewCount;//阅读量
        }

        注解解析:

        @Document(indexName = "news")

        该实体对应的索引名称为:news

        @Id

        ES的唯一标识

        @Field

        @Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer = "ik_smart")

        Field(字段名) , type = FieldType.Text(字段类型为TEXT) ,analyzer = "ik_max_word"(存入时的分词器为ik_max_word),searchAnalyzer = "ik_smart"(搜索时的分词器为ik_smart)

        @JsonProperty("publish_date")

        ES中JSON字段,迎来进行序列化映射

        tips:实际开发中业务实体类和ES实体类最好是分开的,业务实体类主要用来做数据库操作,ES实体类只用来做ES检索

        Springboot3整合Elasticsearch8(elasticsearch-java)最佳实践

        4.2 继承ElasticsearchRepository接口

        public interface EsNewsRepository extends ElasticsearchRepository<EsNews,String> {
        }

        查看ElasticsearchRepository源码可以看到

        ElasticsearchRepository也继承了PagingAndSortingRepository(分页和排序接口)、CrudRepository(常用基础crud接口)

        Springboot3整合Elasticsearch8(elasticsearch-java)最佳实践

        当你的类接口继承了ElasticsearchRepository后,你输入find,你会看到Spring帮你生成的所有常用简单的查询语句。

        Springboot3整合Elasticsearch8(elasticsearch-java)最佳实践

        大部分关键词用法:

        关键词说明等价 Elasticsearch 查询类型
        findBy查询开始(必须)-
        And / Or条件连接符bool 查询
        Is / Equals等于term
        Between在两个值之间range
        LessThan小于range
        LessThanEqual小于等于range
        GreaterThan大于range
        GreaterThanEqual大于等于range
        After大于(时间)range
        Before小于(时间)acauGPrange
        IsNull字段为 nullmust_not exists
        IsNotNull / NotNull字段非 nullexists
        Like类似(不建议用,Elasticsearch 中更推荐 Containingmatch (部分分词匹配)
        NotLike不类似bool + must_not
        StartingWith以…开头(需要 keyword 类编程客栈型字段,match 不支持)prefix / wildcard
        EndingWith以…结尾(需 keyword 类型字段)wildcard
        Containing / Contains包含(常用于全文检索)match
        NotContaining不包含bool + must_not
        Inphp包含在列表中terms
        NotIn不包含在列表中bool + must_not terms
        True / False布尔值判断term
        OrderBy排序sort

        4.3 CRUD接口使用

        使用SpringBoot单元测试

        4.3.1 新增

        文档单个新增(save): 

            @Test
            @DisplayName("新增单个文档")
          编程客栈  void saveDoc(){
                EsNews news = new EsNews();
                news.setId("1");//如果不设置ID,Spring则会帮你生成一个ES风格的随机ID
                news.setTitle("电影《不能说的秘密》热映");
                news.setContent("内容:不能说的秘密............牛X..");
                news.setAuthor("周杰伦");
                news.setTags(Arrays.asList("电影", "国产"));
                news.setPublishDate(new Date());
                news.setCreateTime(new Date());
                news.setViewCount(100L);
                esNewsRepository.save(news);
            }

        文档批量新增(saveAll):

            @Test
            @DisplayName("批量新增文档")
            void saveBatchDoc(){
                List<EsNews> newsList = new ArrayList<>();
                for (int i = 1; i <= 11; i++) {
                    EsNews news = new EsNews();
                    news.setId(String.valueOf(i));
                    news.setTitle("电影《CPW的奇幻世界 " + i + "》");
                    news.setContent("内容 " + i);
                    news.setAuthor("作者" + i);
                    news.setTags(Arrays.asList("电影", "奇幻"));
                    news.setPublishDate(new Date());
                    news.setCreateTime(new Date());
                    news.setViewCount(100L + i);
                    newsList.add(news);
                }
                esNewsRepository.saveAll(newsList);
            }

        4.3.3 修改

        !!!ElasticsearchRepository!!!的修改跟新增是同一个接口,如果你的对象携带ID,那么ES会先查询文档库里是有存在这么一个ID,如果存在的话则进行 先删除 然后 覆盖!!

            javascript@Test
            @DisplayName("新增单个文档")
            void saveDoc(){
                EsNews news = new EsNews();
                news.setId("1");//ES会先找文档库里是否存在改ID,先删除再覆盖
                news.setTitle("电影《不能说的秘密》热映");
                news.setContent("内容:不能说的秘密........牛X..更新覆盖操作");
                news.setAuthor("周杰伦");
                news.setTags(Arrays.asList("电影", "国产"));
                news.setPublishDate(new Date());
                news.setCreateTime(new Date());
                news.setViewCount(100L);
                esNewsRepository.save(news);
            }

        如果你想做到只修改文档中其中一条数据,比如只把作者周杰伦修改成CPW,那就需要用到第五节【高阶用法】Elasticsearch Java API Client

        4.3.3 查询

        需求:我要查询文档编号为999的文档

        tips:简单的查询,比如根据ID查询文档,ElasticsearchRepository已经自己封装好了,不用另外写。(findById)

            @Test
            @DisplayName("根据ID查询文档")
            void searchByID(){
                Optional<EsNews> news = esNewsRepository.findById("999");
                System.out.println(news);
            }

        Springboot3整合Elasticsearch8(elasticsearch-java)最佳实践

        需求:我要分页查询,标题包含【奇幻世界】,作者精准是【作者1】的文档

        tips:这种复杂多条件的就需要我们自己写,如果是模糊查询的则用Containing

        1、EsNewsRepository新增接口findByTitleContainingOrAuthor:

        public interface EsNewsRepository extends ElasticsearchRepository<EsNews,String> {
            Page<EsNews> findByTitleContainingOrAuthor(String Title, String Author,Pageable pageable);
        }

        2、使用

            @Test
            @DisplayName("分页查询条件")
            void searchAll(){
                Pageable pageable = PageRequest.of(0, 10);
                Page<EsNews> pageList = esNewsRepository.findByTitleContainingOrAuthor("奇幻世界","作者1",pageable);
                for (EsNews news : pageList) {
                    System.out.println(news);
                }
            }

        Springboot3整合Elasticsearch8(elasticsearch-java)最佳实践

        根据4.2中的关键词,还有更多的用法例如过滤、排序

        4.3.4 删除

        删除就没什么好说的了,直接上代码!

            @Test
            @DisplayName("根据ID删除文档")
            void deleteDocById(){
                esNewsRepository.deleteById("1");
                System.out.println("ID为1的文档删除成功");
            }
            @Test
            @DisplayName("批量删除文档")
            void deleteBatchDoc(){
                esNewsRepository.deleteAll();
                System.out.println("文档批量删除成功");
            }
            @Test
            @DisplayName("根据ID批量删除文档")
            void deleteBatchDocByIds(){
                List<String> idList = Arrays.asList("1", "2");
                esNewsRepository.deleteAllById(idList);
                System.out.println("根据ID批量删除文档删除成功");
            }

        5、【高阶用法】Elasticsearch Java API Client

        1、修改文档中的某一条数据

        2、高级聚合查询

        6、【最佳实践】Elasticsearch+消息队列(RabbitMQ)+数据库(MYSQL)

        实际应用

        到此这篇关于Springboot3整合Elasticsearch8(elasticsearch-java)最佳实践的文章就介绍到这了,更多相关Springboot3整合Elasticsearch内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新开发

        开发排行榜