由于公司最近需要接入日志数据,然而日志数据在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