更多SpringBoot3内容请关注我的专栏:《SpringBoot3》
期待您的点赞👍收藏⭐评论✍
这里写目录标题
- 1. 为什么选择 Elasticsearch?
 - 2. Spring Boot 3 和 Elasticsearch 8.x 的集成概述
 - 2.1 准备工作
 - 2.2 添加依赖
 
- 3. Elasticsearch 客户端配置方式
 - 3.1 使用 `RestClient` (低级客户端)
 - 3.2 官方 Java API 客户端(elasticsearch-java)
 - 3.3 Spring Data Elasticsearch 提供的 `ElasticsearchTemplate`
 
- 4. 总结
 
Elasticsearch 8.x 提供了更丰富的数据搜索和分析功能。随着 Spring Boot 3 的发布,如何将其与Elasticsearch 8.x 版本整合,成为了开发者关注的重点。本文将详细介绍 Spring Boot 3 如何整合 Elasticsearch 8.x 以及常见的客户端配置方式,以帮助大家顺利集成和配置 Elasticsearch 服务。
1. 为什么选择 Elasticsearch?
Elasticsearch 是一个分布式、RESTful 风格的搜索引擎,以其快速的全文检索、强大的数据分析和分布式架构而备受欢迎。常用于日志分析、实时数据分析、推荐系统等场景。
2. Spring Boot 3 和 Elasticsearch 8.x 的集成概述
Spring Boot 3 中推荐使用 Spring Data Elasticsearch 提供的客户端来访问 Elasticsearch,而不再使用低层次的 Transport Client。Elasticsearch 8.x 推出后,官方推荐使用 Java REST Client 和 ElasticsearchClient,Spring Data Elasticsearch 也支持这些新的客户端。
2.1 准备工作
在开始之前,请确保已安装并启动 Elasticsearch 8.x 实例,为了演示,本人通过 1panel 快速搭建一个演示版本的 ElasticSearch 8.x 版本。

默认用户名:elastic

2.2 添加依赖
在 pom.xml 文件中添加 Spring Data Elasticsearch 以及 Elasticsearch 客户端的依赖项:

3. Elasticsearch 客户端配置方式
在 Spring Boot 3 中有几种方式可以连接 Elasticsearch 8.x。以下是常用的几种配置方式:
- 官方低级别的 REST 客户端(low-level REST client);
 - 官方的Java API客户端 ElasticsearchClient ;
 - Spring Data Elasticsearch 提供的 
ReactiveElasticsearchClient; - Java High Level REST Client ,7.15.0 版本废弃;
 - Java Transport Client 7.0.0 版本废弃。
 
3.1 使用 RestClient (低级客户端)
 
RestClient 是 Elasticsearch 官方提供的低级 REST 客户端,它更灵活,但需要手动处理请求和响应的序列化。对于不需要处理复杂业务逻辑的场景,可以选择这种方式。
官方教程:https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/java-rest-low.html
依赖
        <!-- 官方低级别 REST 客户端(Low-Level REST Client) -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>8.15.3</version>
        </dependency>
 
特点
- 提供直接与 Elasticsearch 进行 HTTP 请求交互的接口。
 - 适用于对请求和响应结构有细粒度控制的场景,适合自定义复杂的请求。
 - 需要手动处理序列化和反序列化。
 
适用场景
当需要直接控制 HTTP 请求或需要编写自定义查询时,低级别 REST 客户端是不错的选择。它适用于高灵活性和精确控制的需求场景。
配置示例
默认配置可以直接使用配置文件:
spring:
  elasticsearch:
    uris: "http://localhost:9200"
    socket-timeout: "10s"
    username: "user"
    password: "secret"
 
更详细的配置可以添加配置类进行设置:
import org.elasticsearch.client.RestClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ElasticsearchConfig {
    @Bean
    public RestClient restClient() {
        return RestClient.builder(new HttpHost("localhost", 9200, "http")).build();
    }
}
 
使用示例
在 Service 层中,通过 RestClient 来操作 Elasticsearch:
package com.coderjia.boot318es.service;
import jakarta.annotation.Resource;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.springframework.stereotype.Service;
/**
 * @author CoderJia
 * @create 2024/11/3 上午 11:28
 * @Description
 **/
@Service
public class MyElasticsearchService {
    @Resource
    private RestClient restClient;
    public void addDocument(String index, String id, String jsonContent) throws Exception {
        Request request = new Request("PUT", "/" + index + "/_doc/" + id);
        request.setEntity(new StringEntity(jsonContent, ContentType.APPLICATION_JSON));
        restClient.performRequest(request);
    }
    public String getDocument(String index, String id) throws Exception {
        Request request = new Request("GET", "/" + index + "/_doc/" + id);
        Response response = restClient.performRequest(request);
        return EntityUtils.toString(response.getEntity());
    }
    public void updateDocument(String index, String id, String jsonContent) throws Exception {
        Request request = new Request("POST", "/" + index + "/_update/" + id);
        StringEntity entity = new StringEntity("{\"doc\":" + jsonContent + "}", ContentType.APPLICATION_JSON);
        request.setEntity(entity);
        restClient.performRequest(request);
    }
    public void deleteDocument(String index, String id) throws Exception {
        Request request = new Request("DELETE", "/" + index + "/_doc/" + id);
        restClient.performRequest(request);
    }
}
 
结果:

3.2 官方 Java API 客户端(elasticsearch-java)
官方推荐的 Java 和 ES 8.x 交互方式。
官方教程:https://www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/index.html
依赖
        <!-- 官方 Java API 客户端 -->
        <dependency>
            <groupId>co.elastic.clients</groupId>
            <artifactId>elasticsearch-java</artifactId>
            <version>8.15.3</version>
        </dependency>
        <!--JSON对象映射库-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.17.0</version>
        </dependency>
 
特点
- 这是 Elasticsearch 官方推荐的高层次客户端,提供对 Elasticsearch API 的完整封装。
 - 自动处理序列化和反序列化,支持更简洁的代码。
 - 兼容 Java 8+,适用于最新的 Spring Boot 3 和 Elasticsearch 8.x 版本。
 
适用场景:当希望高效地集成 Elasticsearch API 并且减少对请求响应的手动处理时,该客户端是最优选择,尤其适合数据处理或搜索的微服务。
配置示例
默认配置可以直接使用配置文件:
spring:
  elasticsearch:
    uris: "http://localhost:9200"
    socket-timeout: "10s"
    username: "user"
    password: "secret"
 
更详细的配置可以添加配置类进行设置:
package com.coderjia.boot318es.config;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import jakarta.annotation.Resource;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchProperties;
import org.springframework.context.annotation.Bean;
/**
 * @author CoderJia
 * @create 2024/11/3 下午 02:31
 * @Description
 **/
public class ElasticsearchClientConfig {
    @Resource
    private ElasticsearchProperties elasticsearchProperties;
    @Bean
    public ElasticsearchClient elasticsearchClient() {
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(elasticsearchProperties.getUsername(), elasticsearchProperties.getPassword()));
        RestClient restClient = RestClient.builder(HttpHost.create(elasticsearchProperties.getUris().get(0)))
                .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder
                        .setDefaultCredentialsProvider(credentialsProvider))
                .build();
        RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
        return new ElasticsearchClient(transport);
    }
}
 
使用示例
在 Service 层中,通过 RestClient 来操作 Elasticsearch:
package com.coderjia.boot318es.service;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.DeleteResponse;
import co.elastic.clients.elasticsearch.core.GetResponse;
import co.elastic.clients.elasticsearch.core.IndexResponse;
import co.elastic.clients.elasticsearch.core.UpdateResponse;
import com.coderjia.boot318es.User;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.io.IOException;
/**
 * @author CoderJia
 * @create 2024/11/3 下午 02:47
 * @Description
 **/
@Service
public class ElasticsearchClientService {
    @Resource
    private ElasticsearchClient esClient;
    public String addDocument(String index,  User user) throws IOException {
        IndexResponse response = esClient.index(i -> i
                .index(index)
                .id(user.getId().toString())
                .document(user)
        );
        System.out.println("Indexed with version " + response.version());
        return response.id();
    }
    public User getDocument(String index, String id) throws IOException {
        GetResponse<User> response = esClient.get(g -> g.index(index).id(id), User.class);
        if (response.found()) {
            return response.source();
        } else {
            return null;
        }
    }
    public void updateDocument(String index, User user) throws IOException {
        UpdateResponse<User> response = esClient.update(u -> u
                .index(index)
                .id(user.getId().toString())
                .doc(user)  // 用于更新已存在文档的字段
                .upsert(user), // 如果文档不存在,则插入
                User.class);
        System.out.println("Updated with version " + response.version());
    }
    public void deleteDocument(String index, String id) throws IOException {
        DeleteResponse response = esClient.delete(d -> d.index(index).id(id));
        System.out.println("Deleted with version " + response.version());
    }
}
 
结果

3.3 Spring Data Elasticsearch 提供的 ElasticsearchTemplate
 
Spring Data Elasticsearch 提供了 ElasticsearchTemplate 作为 Elasticsearch 的操作模板,ElasticsearchTemplate 提供了许多高层次的 API,简化了与 Elasticsearch 的交互,用户无需直接编写复杂的 Elasticsearch 查询。
依赖
        <!-- Spring Data Elasticsearch 提供的 ElasticsearchClient -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
 
特点
- 简化的操作: 
ElasticsearchTemplate提供了许多高层次的 API,简化了与 Elasticsearch 的交互,用户无需直接编写复杂的 Elasticsearch 查询。 - 对象映射: 
ElasticsearchTemplate支持将 Java 对象映射到 Elasticsearch 文档,方便在应用程序中操作对象而无需手动处理 JSON。 
配置示例
在 application.yml 中配置 Elasticsearch 连接地址:
spring:
  elasticsearch:
    uris: "http://localhost:9200"
    socket-timeout: "10s"
    username: "user"
    password: "secret"
 
使用示例
下面是使用 ElasticsearchTemplate 实现增、删、改、查的简单示例。
数据模型
创建一个简单的文档模型类,用于存储在 Elasticsearch 索引中的数据。
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
@Document(indexName = "products")
public class Product {
    @Id
    private String id;
    private String name;
    private String description;
    private double price;
    // Getters and Setters
}
 
使用示例
在 Service 层中使用 Repository 来完成数据存储和查询:
package com.coderjia.boot318es.service;
import com.coderjia.boot318es.bean.Product;
import jakarta.annotation.Resource;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.stereotype.Service;
/**
 * @author CoderJia
 * @create 2024/11/3 下午 04:58
 * @Description
 **/
@Service
public class EsTemplateService {
    @Resource
    private ElasticsearchTemplate elasticsearchTemplate;
    public Product saveProduct(Product product) {
        return elasticsearchTemplate.save(product);
    }
    public Product getProductById(String id) {
        return elasticsearchTemplate.get(id, Product.class);
    }
    public Product updateProduct(Product Product) {
        return elasticsearchTemplate.save(Product);
    }
    public void deleteProduct(String id) {
        elasticsearchTemplate.delete(id, Product.class);
    }
}
 
结果

4. 总结
在 Spring Boot 3 中集成 Elasticsearch 8.x 可以通过多种方式实现,包括 RestClient、ElasticsearchClient 和 ElasticsearchTemplate 等不同的客户端方案。本文提供了多种整合方式的详细示例,让您能够根据需求选择合适的集成方式。希望本文能帮助您在实际项目中顺利使用 Elasticsearch 进行高效的数据存储和查询。
后面会继续介绍 Spring Data Elasticsearch Repository 的使用,像 JPA Repository 一样操作 ES,以及 ES 各种其他使用功能,敬请期待!



















