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

背景

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

Spring Data Release TrainSpring Data ElasticsearchElasticsearchSpring FrameworkSpring 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依赖如下:

        <dependency>
            <artifactId>elasticsearch</artifactId>
            <groupId>org.elasticsearch</groupId>
            <version>6.8.13</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.plugin</groupId>
            <artifactId>transport-netty4-client</artifactId>
            <version>6.8.13</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>transport</artifactId>
            <version>6.8.13</version>
        </dependency>

编写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版本,单纯引入依赖如下配置:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-elasticsearch</artifactId>
    <version>3.2.12.RELEASE</version>
    <exclusions>
        <exclusion>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>transport</artifactId>
        </exclusion>
        <exclusion>
            <artifactId>transport-netty4-client</artifactId>
            <groupId>org.elasticsearch.plugin</groupId>
        </exclusion>
        <exclusion>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <groupId>org.elasticsearch.client</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <groupId>org.elasticsearch.client</groupId>
    <version>6.8.13</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-client</artifactId>
    <version>6.8.13</version>
</dependency>
<dependency>
    <artifactId>elasticsearch</artifactId>
    <groupId>org.elasticsearch</groupId>
    <version>6.8.13</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch.plugin</groupId>
    <artifactId>transport-netty4-client</artifactId>
    <version>6.8.13</version>
</dependency>
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>transport</artifactId>
    <version>6.8.13</version>
    <exclusions>
        <exclusion>
            <artifactId>elasticsearch</artifactId>
            <groupId>org.elasticsearch</groupId>
        </exclusion>
        <exclusion>
            <artifactId>transport-netty4-client</artifactId>
            <groupId>org.elasticsearch.plugin</groupId>
        </exclusion>
        <exclusion>
            <artifactId>elasticsearch-rest-client</artifactId>
            <groupId>org.elasticsearch.client</groupId>
        </exclusion>
    </exclusions>
</dependency>

引入如上依赖之后,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<Blog> 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

  • 18
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值