Springboot3.3.4使用spring-data-elasticsearch整合Elasticsearch7.12.1

发布于:2025-07-04 ⋅ 阅读:(11) ⋅ 点赞:(0)

Spring Boot 3 不建议使用 Elasticsearch 7.12.1,主要与两者的版本兼容性、技术架构升级及依赖管理机制变化有关,以下是具体原因分析:

一、基础架构与版本依赖的断层

  1. Spring Boot 3 的技术栈升级
    Spring Boot 3 基于 Java 17 及以上版本构建,底层依赖的 Spring Framework 6 全面采用反应式编程模型(Reactor) 和Kotlin 一等公民支持,并移除了对 Java 8/9/10 的支持。而 Elasticsearch 7.12.1 发布于 2021 年,其官方客户端(如 Elasticsearch Java Client)主要适配 Java 8-11,与 Java 17 的语法特性(如密封类、模式匹配)存在兼容性缺口,可能导致编译错误或运行时异常。

  2. Elasticsearch 客户端的版本割裂

    • Elasticsearch 7.12.1 对应的官方客户端版本为 7.12.x,该版本仅支持Transport Client(已废弃) 和低版本的 REST Client,无法适配 Spring Boot 3 中主推的Reactive REST Client(需 Elasticsearch 8.0 + 客户端支持)。
    • Spring Boot 3 的spring-data-elasticsearch依赖已升级至 4.4.x 版本,该版本强制要求 Elasticsearch 服务端版本≥8.0,否则会因 API 接口不匹配导致功能缺失(如无法使用响应式查询 API)。

二、核心功能兼容性问题

  1. 响应式编程模型不兼容
    Spring Boot 3 的spring-data-elasticsearch模块全面转向响应式编程(ReactiveCrudRepositoryFlux/Mono返回值),而 Elasticsearch 7.12.1 的客户端仅支持阻塞式操作(RestHighLevelClient),强行整合会导致:

    • 无法利用 Spring Boot 3 的非阻塞 IO 特性,反而可能因线程阻塞降低系统吞吐量;
    • 需要手动适配异步回调逻辑,增加代码复杂度和维护成本。
  2. 索引映射与 DSL 语法差异
    Elasticsearch 8.0 后对索引映射(Mapping)和查询 DSL 进行了多项优化(如字段类型自动推断、弃用_all字段),而 Spring Boot 3 的 Elasticsearch 集成模块基于 8.0 + 的语法规范设计。例如:

    • Spring Boot 3 默认使用@Document注解的createIndex = false(需手动创建索引),而 7.12.1 的自动索引创建机制可能与该配置冲突;
    • 部分查询 API(如MatchQuery的参数构造方式)在 7.12.1 与 8.0 + 之间存在签名变化,可能导致序列化失败或查询结果错误。

三、官方支持与生态演进

  1. Elasticsearch 官方的版本建议
    Elasticsearch 官方文档明确指出:7.17.x 是 7.x 系列的最后一个长期支持(LTS)版本,而 7.12.1 属于中期版本,已不再提供主流支持(截至 2023 年,该版本已过维护期)。Spring Boot 3 作为 2022 年发布的新一代框架,自然优先适配 Elasticsearch 的 LTS 版本(如 8.0+),以保证稳定性和安全性。

  2. 依赖管理机制的变化
    Spring Boot 3 采用BOM(Bill of Materials) 机制严格管控依赖版本,spring-data-elasticsearch的 4.4.x 版本会强制引入 Elasticsearch 8.0 + 的客户端依赖。若强行在 Spring Boot 3 中使用 7.12.1,可能引发依赖冲突(如elasticsearch-rest-client版本不兼容),甚至导致应用无法启动。


但Springboot3依旧是可以通过elasticsearch-rest-client依赖(不能同时存在spring-dataelasticsearch)elasticsearch7.12.1。下面简单演示一下demo。

1. 引入Maven依赖

在Spring Boot项目的pom.xml文件中添加Elasticsearch相关的依赖:

<dependencies>
    <!-- Elasticsearch High Level REST Client -->
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.12.1</version>
    </dependency>
    <!-- 其他依赖 -->
    <!-- ... -->
</dependencies>

2. 配置Elasticsearch客户端

创建一个配置类来配置Elasticsearch的RestHighLevelClient:

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ElasticsearchConfig {

    @Bean
    public RestHighLevelClient restHighLevelClient() {
        // 配置Elasticsearch的主机和端口
        HttpHost httpHost = new HttpHost("localhost", 9200, "http");
        RestClientBuilder builder = RestClient.builder(httpHost);
        return new RestHighLevelClient(builder);
    }
}

3. 创建实体类和索引映射

创建一个实体类来表示Elasticsearch中的文档,并定义一个索引映射模板:

import java.io.Serializable;

public class MyDocument implements Serializable {
    private String id;
    private String content;

    // getters and setters
    // ...
}

索引映射模板(JSON格式)可以定义在配置文件中,或者通过代码动态创建。这里假设已经有一个名为my_index的索引,并且其映射已经定义好。

4. 创建Service类实现增删改查

创建一个Service类来处理Elasticsearch的增删改查操作:

import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ElasticsearchService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    // 增加文档
    public String indexDocument(MyDocument document) throws Exception {
        IndexRequest request = new IndexRequest("my_index")
                .id(document.getId())
                .source(new ObjectMapper().writeValueAsString(document), XContentType.JSON);
        IndexResponse indexResponse = restHighLevelClient.index(request, RequestOptions.DEFAULT);
        return indexResponse.getResult().name();
    }

    // 获取文档
    public MyDocument getDocument(String id) throws Exception {
        GetRequest request = new GetRequest("my_index", id);
        GetResponse getResponse = restHighLevelClient.get(request, RequestOptions.DEFAULT);
        if (getResponse.isExists()) {
            return new ObjectMapper().readValue(getResponse.getSourceAsString(), MyDocument.class);
        } else {
            return null;
        }
    }

    // 删除文档
    public String deleteDocument(String id) throws Exception {
        DeleteRequest request = new DeleteRequest("my_index", id);
        DeleteResponse deleteResponse = restHighLevelClient.delete(request, RequestOptions.DEFAULT);
        return deleteResponse.getResult().name();
    }

    // 更新文档
    public String updateDocument(String id, MyDocument document) throws Exception {
        UpdateRequest request = new UpdateRequest("my_index", id)
                .doc(new ObjectMapper().writeValueAsString(document), XContentType.JSON);
        UpdateResponse updateResponse = restHighLevelClient.update(request, RequestOptions.DEFAULT);
        return updateResponse.getResult().name();
    }
}

注意:在实际代码中,需要使用com.fasterxml.jackson.databind.ObjectMapper来处理JSON序列化和反序列化,因此需要添加Jackson的依赖。

5. 创建Controller类处理HTTP请求

创建一个Controller类来处理来自前端的HTTP请求,并调用Service类的方法来实现业务逻辑:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/elasticsearch")
public class ElasticsearchController {

    @Autowired
    private ElasticsearchService elasticsearchService;

    @PostMapping("/index")
    public String indexDocument(@RequestBody MyDocument document) {
        try {
            return elasticsearchService.indexDocument(document);
        } catch (Exception e) {
            e.printStackTrace();
            return "Error indexing document";
        }
    }

    @GetMapping("/{id}")
    public MyDocument getDocument(@PathVariable String id) {
        try {
            return elasticsearchService.getDocument(id);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @DeleteMapping("/{id}")
    public String deleteDocument(@PathVariable String id) {
        try {
            return elasticsearchService.deleteDocument(id);
        } catch (Exception e) {
            e.printStackTrace();
            return "Error deleting document";
        }
    }

    @PutMapping("/{id}")
    public String updateDocument(@PathVariable String id, @RequestBody MyDocument document) {
        try {
            return elasticsearchService.updateDocument(id, document);
        } catch (Exception e) {
            e.printStackTrace();
            return "Error updating document";
        }
    }
}

6. 配置文件

application.propertiesapplication.yml文件中配置Elasticsearch的相关属性(如果需要的话,但在这个示例中已经在配置类中硬编码了主机和端口):

# Elasticsearch配置(可选)
# elasticsearch.host=localhost
# elasticsearch.port=9200

7. 运行项目

确保Elasticsearch服务已经启动,并且可以通过http://localhost:9200访问。然后运行Spring Boot项目,并通过Postman或其他HTTP客户端工具测试Elasticsearch的增删改查功能。

这个示例Demo展示了如何在Spring Boot 3.3.4项目中整合Elasticsearch 7.12.1,并实现了基本的增删改查功能。你可以根据自己的需求进行扩展和修改。


网站公告

今日签到

点亮在社区的每一天
去签到