Spring Boot 整合Elasticsearch
# 版本选择
官方文档中提到:
The Elasticsearch Java client is forward compatible; meaning that the client supports communicating with greater or equal minor versions of Elasticsearch. Elasticsearch language clients are only backwards compatible with default distributions and without guarantees made. Elasticsearch Java 客户端向前兼容;这意味着客户端支持与更高或同等次要版本的 Elasticsearch 进行通信。 Elasticsearch 语言客户端仅向后兼容默认发行版,并且不做任何保证。
也就是说 java 的 Elasticsearch 客户端版本不能高于 Elasticsearch 服务端的版本,由于我使用的服务端版本为 7.14.2
,因此可使用的客户端版本最高也只能是 7.14
,如果使用更高的版本可能会出现不兼容的情况,相反使用更低的版本(7.x)是支持的。
Java REST Client 与 Java API Client 的区别
- Java REST Client 文档:Java REST Client [7.17] | Elastic (opens new window)
- Java API Client 文档:Getting started | Elasticsearch Java API Client [8.11] | Elastic (opens new window)
Java REST Client 已被弃用仅支持到 7.17
版本, 8.x
不再支持,取而代之的是 Java API Client。
有人在 ES 社区提问 (opens new window) Java REST Client 与 Java API Client 的区别
,ES 团队成员回复称:
性能方面:两者的性能相似,均不依赖昂贵的反射来序列化和反序列化对象。
功能方面:Java API 客户端提供了一种现代流畅的方式来构建请求对象并导航复杂的响应、更强的类型(无
Object
值)以及与 Jackson 等 JSON 对象映射器的紧密集成,以便您可以直接发送和检索应用程序类。
Java High Level REST Client 与 Java Low Level REST Client 的区别
抽象级别:Java High Level REST Client 提供了更高级别的抽象,以简化与 Elasticsearch 的交互。它提供了面向对象的 API,用于执行各种操作,如索引、搜索和聚合等。它隐藏了底层请求和响应的细节,使得开发者可以更加专注于业务逻辑的实现。而 Java Low Level REST Client 则提供了更底层的 API,更接近原始的 HTTP 请求和响应,需要开发者手动处理请求和响应的细节。
使用方式:Java High Level REST Client 使用起来更加简单和直观。它提供了更友好的方法链式调用,使得构建请求和解析响应更加方便。而 Java Low Level REST Client 则需要开发者显式地构建请求对象,设置请求参数,并手动处理响应数据。
功能覆盖:Java High Level REST Client 提供了一系列高级功能,如索引管理、搜索、聚合、索引别名、数据批量处理等。它通过更高级别的 API 封装了这些功能,使得开发者可以更轻松地使用它们。而 Java Low Level REST Client 提供了更底层的 API,可以更灵活地构建自定义的请求和处理逻辑。
综上所述,Java High Level REST Client 适用于大多数常见的 Elasticsearch 操作,提供了更高级别的抽象和便捷的使用方式。而 Java Low Level REST Client 适用于对请求和响应的细节要求较高,或者需要进行自定义操作的场景。选择哪个客户端取决于具体的需求和开发者的偏好。
# Java Low Level REST Client
# 依赖
Maven Repository | Java REST Client [7.14] | Elastic (opens new window)
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>7.14.2</version>
</dependency>
# 初始化
Basic authentication | Java REST Client [7.14] | Elastic (opens new window)
final CredentialsProvider credentialsProvider =
new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("user", "test-user-password"));
RestClientBuilder builder = RestClient.builder(
new HttpHost("localhost", 9200))
.setHttpClientConfigCallback(new HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(
HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder
.setDefaultCredentialsProvider(credentialsProvider);
}
});
# Java High Level REST Client
# 依赖
Maven Repository | Java REST Client [7.14] | Elastic (opens new window)
elasticsearch-rest-high-level-client
是有依赖 elasticsearch-rest-client
(Java Low Level REST Client),因此更推荐使用。
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.14.2</version>
</dependency>
elasticsearch-rest-high-level-client
依赖的 elasticsearch
版本不正确问题
由于 Spring Boot 的版本号管理 spring-boot-dependencies
指定了 elasticsearch
的版本号
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
情况 1:Maven 项目的父项目为 spring-boot-starter-parent
则可以添加 elasticsearch.version
覆盖 Spring Boot 的版本号控制
<properties>
<elasticsearch.version>7.14.2</elasticsearch.version>
</properties>
情况 2:使用 dependencyManagement 方式引入 Spring Boot 的版本号控制
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
这种情况不能通过覆盖 elasticsearch.version
实现版本修改。
目前解决办法(可能并非最优解):
<properties>
<elasticsearch.version>7.14.2</elasticsearch.version>
</properties>
...
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
参考:Maven – Introduction to the Dependency Mechanism#Transitive Dependencies (opens new window)
笔记
java.lang.NoClassDefFoundError: org/elasticsearch/core/CheckedConsumer
# 初始化
@Configuration
public class EsConfiguration {
@Value("${spring.elasticsearch.uris}")
private String uris;
@Value("${spring.elasticsearch.username}")
private String username;
@Value("${spring.elasticsearch.password}")
private String password;
@Bean
public RestHighLevelClient restHighLevelClient() {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(username, password));
RestClientBuilder builder = RestClient.builder(HttpHost.create(uris))
.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
return new RestHighLevelClient(builder);
}
}
# Java API Client
# 依赖
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.11.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>