高版本SpringBoot兼容低版本ElasticSearch解决方案

背景

由于公司最近需要接入日志数据,然而日志数据在ElasticSearch(版本为 6.8.23)里面,但是接入数据项目使用的是Spring Boot 2.4.x版本,根据Spring Data官方提供的版本对应,明显对应不上,官方文档地址:Spring Data Elasticsearch - Reference Documentation

Spring Data Release Train Spring Data Elasticsearch Elasticsearch Spring Framework Spring Boot

2021.2 (Raj)

4.4.x

7.17.9

5.3.x

2.7.x

2021.1 (Q)

4.3.x

7.15.2

5.3.x

2.6.x

2021.0 (Pascal)

4.2.x[1]

7.12.0

5.3.x

2.5.x

2020.0 (Ockham)[1]

4.1.x[1]

7.9.3

5.3.2

2.4.x

Neumann[1]

4.0.x[1]

7.6.2

5.2.12

2.3.x

Moore[1]

3.2.x[1]

6.8.12

5.2.12

2.2.x

Lovelace[1]

3.1.x[1]

6.2.2

5.1.19

2.1.x

Kay[1]

3.0.x[1]

5.5.0

5.0.13

2.0.x

Ingalls[1]

2.1.x[1]

2.4.0

4.3.25

1.5.x

如果使用Spring Boot提供的spring-boot-starter-data-elasticsearch模块则存在兼容性问题;

ElasticSearch 5.x:支持多种Type(类似关系型数据的表概念);

ElasticSearch 6.x:仅支持一个Type;

ElasticSearch 7.x:将Type概念移出。

由于以上ElasticSearch 版本之间的差距导致对应Spring Data ElasticSearch包的差距;所以在不降低Spring Boot版本的情况需兼容低版本的ElasticSearch的客户端。

解决方法

方案一

具体使用

由于不兼容,即放弃Spring Data ElasticSearch框架包,使用最直接的Java ElasticSearch Client连接即可,将Client注入到Spring容器中,当前使用Transport方式连接ElasticSearch服务(在ES7.x版本已经不推荐使用TCP 9300端口),或者使用High/Low Level Client API连接也是可以的(HighLevel是在LowLevel Client的基础上封装而成的

使用Maven依赖如下:

        
            elasticsearch
            org.elasticsearch
            6.8.13
        
        
            org.elasticsearch.plugin
            transport-netty4-client
            6.8.13
        
        
            org.elasticsearch.client
            transport
            6.8.13
        

编写ElasticSearch配置类:

@Configuration
public class ElasticSearchConfig  {

    public static final String HOST = "127.0.0.1";   //ES集群服务器IP地址

    public static final Integer PORT = 9300;         //集群结点之间通信端口

    public static final String CONF = "cluster.name"; //配置集群名称(默认配置、无需修改)

    public static final String NAME = "elasticsearch"; //配置节点名称(默认配置、无需修改)


    @Bean
    public TransportClient transportClient() throws UnknownHostException {
        Settings settings = Settings.builder().put(CONF, NAME).build();
        return new PreBuiltTransportClient(settings)
                .addTransportAddress(new TransportAddress(InetAddress.getByName(HOST),PORT));
    }

}

查询示例:

@Component
public class ESTransportInit implements CommandLineRunner {

    @Resource
    private TransportClient transportClient;

    @Override
    public void run(String... args) throws Exception {
        QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();
        SearchResponse resp = transportClient.prepareSearch("blog").setQuery(queryBuilder).get();

        //3、返回结果
        System.out.println(resp);

    }
}

结论

由于使用原生Java连接ElasticSearch服务,所以在代码开发方式上有一定难度,不建议使用。

方案二(推荐)

具体使用

由于SpringBoot 2.3.x以上版本只支持ES7服务,所以对于一些本身为SpringBoot高版本的项目而言单纯的引入spring-boot-starter-data-elasticsearch模块包是存在兼容性问题的,所以需要将Spring Data ElasticSearch单独引入,由于ES6对应的Spring Data ElasticSearch 为3.2.x版本,单纯引入依赖如下配置:


    org.springframework.data
    spring-data-elasticsearch
    3.2.12.RELEASE
    
        
            org.elasticsearch.client
            transport
        
        
            transport-netty4-client
            org.elasticsearch.plugin
        
        
            elasticsearch-rest-high-level-client
            org.elasticsearch.client
        
    


    elasticsearch-rest-high-level-client
    org.elasticsearch.client
    6.8.13


    org.elasticsearch.client
    elasticsearch-rest-client
    6.8.13


    elasticsearch
    org.elasticsearch
    6.8.13


    org.elasticsearch.plugin
    transport-netty4-client
    6.8.13


    org.elasticsearch.client
    transport
    6.8.13
    
        
            elasticsearch
            org.elasticsearch
        
        
            transport-netty4-client
            org.elasticsearch.plugin
        
        
            elasticsearch-rest-client
            org.elasticsearch.client
        
    

引入如上依赖之后,spring-boot-starter-data-elasticsearch包无需再引,由于SpringBoot为自动配置类,所以在主类中需要将ElasticSearch自动配置类去除:

@SpringBootApplication(exclude = {ElasticsearchRepositoriesAutoConfiguration.class, ElasticsearchDataAutoConfiguration.class})
public class EsAppApplication {

    public static void main(String[] args) {
        SpringApplication.run(EsAppApplication.class, args);
    }

}

去除自动配置类之后,需要手动将ElasticSearch配置类提供:

@Configuration
public class ElasticSearchConfig  {
	// 使用ES http客户端
    @Bean
    public RestHighLevelClient restHighLevelClient() {
        // IP以及port可以写入到application.yml配置文件中
        return new RestHighLevelClient(RestClient.builder(new HttpHost("127.0.0.1", 9200)));
    }
	// 引入ElasticsearchRestTemplate
    @Bean
    public ElasticsearchRestTemplate elasticsearchRestTemplate() {
        return new ElasticsearchRestTemplate(restHighLevelClient());
    }

}

编写索引实体类:

@Data
// 低版本依赖包注解有type标记
@Document(indexName = "blog", type = "doc")
public class Blog {
	@Id
    private String id;

    private String name;

    private String phone;

    private Integer age;

    private String ip;

    private String dec;

    private Date birth;

}

简单使用:

@Component
public class ESInit implements CommandLineRunner {
    // 引入ES Rest Template
    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public void run(String... args) throws Exception {
        System.out.println("执行ES初始化.........");
        // 查询Query,查询age小于等于19并且第一页数据页大小为5
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.rangeQuery("age").lte(19))
                .withPageable(PageRequest.of(0,5))
                .build();

        List blogs = elasticsearchRestTemplate.queryForList(searchQuery, Blog.class);

        blogs.stream().forEach(System.out::println);

        System.out.println("执行ES结束.........");
    }
}

结论

使用Spring Data ElasticSearch框架包中的ElasticsearchRestTemplate模板类,在代码开发上比原生开发提升了便携性。

其他

具体ElasticsearchRestTemplate使用官方文档:Spring Data Elasticsearch - Reference Documentation

ElasticsearchRestTemplate API文档:Spring Data Elasticsearch 3.2.12.RELEASE API

你可能感兴趣的:(ElasticSearch,NoSql数据库,elasticsearch,spring,boot,java)