欢迎光临
我们一直在努力

Elasticsearch集成实战:Spring Data Elasticsearch从入门到精通,彻底简化开发

Elasticsearch集成实战:Spring Data Elasticsearch从入门到精通,彻底简化开发

    • 前言
    • 一、Spring Data Elasticsearch 是什么?
      • 1.1 核心定义
      • 1.2 集成架构流程图
      • 1.3 核心优势
    • 二、版本对应关系(重中之重)
    • 三、快速集成:三步搭建环境
      • 3.1 引入 Maven 依赖
      • 3.2 配置 application.yml
      • 3.3 启动类开启注解
    • 四、核心注解:实体类映射 ES 索引
      • 4.1 常用注解一览
      • 4.2 实体类编写(商品示例)
    • 五、核心功能:Repository 接口开发
      • 5.1 基础 Repository 接口
      • 5.2 基础 CRUD 实战
    • 六、高级查询:方法名 DSL(零代码查询)
      • 6.1 语法规则
      • 6.2 常用查询示例
    • 七、复杂查询:NativeSearchQuery 构建
      • 7.1 高亮查询实战
    • 八、完整开发流程图
    • 九、最佳实践与避坑指南
    • 十、总结

🌺The Begin🌺点点关注,收藏不迷路🌺

前言

在 SpringBoot 项目中直接使用 RestHighLevelClient 操作 Elasticsearch,需要手动构建请求、解析响应、封装结果,代码冗余且开发效率极低。

Spring Data Elasticsearch(简称 SDE) 是 Spring 官方提供的 ES 集成框架,屏蔽了底层客户端细节,只需编写简单接口,就能实现 ES 的增删改查、分页、排序、聚合、高亮等所有操作,开发效率提升 10 倍以上。

本文将从环境搭建 → 核心注解 → 接口编写 → 高级查询 → 实战案例全流程讲解,带你用最简单的方式完成 SpringBoot 与 ES 集成。


一、Spring Data Elasticsearch 是什么?

1.1 核心定义

  • Spring Data 家族的子模块,专门用于简化 Elasticsearch 开发
  • 基于 RestHighLevelClient 封装,底层自动管理连接池
  • 提供 Repository 模式,无需编写实现类,只需定义接口

1.2 集成架构流程图

#mermaid-svg-MvdNGwc51nkVM8Qj{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MvdNGwc51nkVM8Qj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MvdNGwc51nkVM8Qj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MvdNGwc51nkVM8Qj .error-icon{fill:#552222;}#mermaid-svg-MvdNGwc51nkVM8Qj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MvdNGwc51nkVM8Qj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MvdNGwc51nkVM8Qj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MvdNGwc51nkVM8Qj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MvdNGwc51nkVM8Qj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MvdNGwc51nkVM8Qj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MvdNGwc51nkVM8Qj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MvdNGwc51nkVM8Qj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MvdNGwc51nkVM8Qj .marker.cross{stroke:#333333;}#mermaid-svg-MvdNGwc51nkVM8Qj svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MvdNGwc51nkVM8Qj p{margin:0;}#mermaid-svg-MvdNGwc51nkVM8Qj .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-MvdNGwc51nkVM8Qj .cluster-label text{fill:#333;}#mermaid-svg-MvdNGwc51nkVM8Qj .cluster-label span{color:#333;}#mermaid-svg-MvdNGwc51nkVM8Qj .cluster-label span p{background-color:transparent;}#mermaid-svg-MvdNGwc51nkVM8Qj .label text,#mermaid-svg-MvdNGwc51nkVM8Qj span{fill:#333;color:#333;}#mermaid-svg-MvdNGwc51nkVM8Qj .node rect,#mermaid-svg-MvdNGwc51nkVM8Qj .node circle,#mermaid-svg-MvdNGwc51nkVM8Qj .node ellipse,#mermaid-svg-MvdNGwc51nkVM8Qj .node polygon,#mermaid-svg-MvdNGwc51nkVM8Qj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MvdNGwc51nkVM8Qj .rough-node .label text,#mermaid-svg-MvdNGwc51nkVM8Qj .node .label text,#mermaid-svg-MvdNGwc51nkVM8Qj .image-shape .label,#mermaid-svg-MvdNGwc51nkVM8Qj .icon-shape .label{text-anchor:middle;}#mermaid-svg-MvdNGwc51nkVM8Qj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MvdNGwc51nkVM8Qj .rough-node .label,#mermaid-svg-MvdNGwc51nkVM8Qj .node .label,#mermaid-svg-MvdNGwc51nkVM8Qj .image-shape .label,#mermaid-svg-MvdNGwc51nkVM8Qj .icon-shape .label{text-align:center;}#mermaid-svg-MvdNGwc51nkVM8Qj .node.clickable{cursor:pointer;}#mermaid-svg-MvdNGwc51nkVM8Qj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MvdNGwc51nkVM8Qj .arrowheadPath{fill:#333333;}#mermaid-svg-MvdNGwc51nkVM8Qj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MvdNGwc51nkVM8Qj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MvdNGwc51nkVM8Qj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MvdNGwc51nkVM8Qj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MvdNGwc51nkVM8Qj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MvdNGwc51nkVM8Qj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MvdNGwc51nkVM8Qj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MvdNGwc51nkVM8Qj .cluster text{fill:#333;}#mermaid-svg-MvdNGwc51nkVM8Qj .cluster span{color:#333;}#mermaid-svg-MvdNGwc51nkVM8Qj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MvdNGwc51nkVM8Qj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MvdNGwc51nkVM8Qj rect.text{fill:none;stroke-width:0;}#mermaid-svg-MvdNGwc51nkVM8Qj .icon-shape,#mermaid-svg-MvdNGwc51nkVM8Qj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MvdNGwc51nkVM8Qj .icon-shape p,#mermaid-svg-MvdNGwc51nkVM8Qj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MvdNGwc51nkVM8Qj .icon-shape .label rect,#mermaid-svg-MvdNGwc51nkVM8Qj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MvdNGwc51nkVM8Qj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MvdNGwc51nkVM8Qj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MvdNGwc51nkVM8Qj :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

业务代码

自定义Repository接口

Spring Data Elasticsearch 自动实现

RestHighLevelClient 底层调用

Elasticsearch 集群

结果自动封装返回

1.3 核心优势

  • 零底层代码:无需操作原生客户端
  • ORM 映射:实体类直接映射 ES 索引
  • Repository 模式:继承接口即可拥有 CRUD
  • 支持 DSL 方法名:按规则写方法名自动生成查询
  • 无缝整合 SpringBoot:自动配置、开箱即用

  • 二、版本对应关系(重中之重)

    Spring Data Elasticsearch 必须严格与 ES 版本对应,否则启动报错!

    Spring Data ESSpring BootElasticsearch
    4.4.x 2.7.x 7.17.0
    4.3.x 2.6.x 7.15.0
    4.1.x 2.4.x 7.9.0
    4.0.x 2.3.x 7.6.0

    本文环境:

    • Spring Boot:2.7.0
    • Spring Data Elasticsearch:4.4.0
    • Elasticsearch:7.17.0

    三、快速集成:三步搭建环境

    3.1 引入 Maven 依赖

    <!– Spring Data Elasticsearch 核心依赖 –>
    <dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-elasticsearch</artifactId>
    <version>4.4.0</version>
    </dependency>

    3.2 配置 application.yml

    spring:
    elasticsearch:
    rest:
    uris: http://127.0.0.1:9200 # ES地址
    username: elastic # 无密码可删除
    password: 123456
    connection-timeout: 3s
    read-timeout: 10s

    3.3 启动类开启注解

    @SpringBootApplication
    // 开启 Elasticsearch 仓库支持
    @EnableElasticsearchRepositories(basePackages = "com.es.repository")
    public class EsApplication {
    public static void main(String[] args) {
    SpringApplication.run(EsApplication.class, args);
    }
    }


    四、核心注解:实体类映射 ES 索引

    4.1 常用注解一览

    注解作用
    @Document 标记为 ES 文档,指定索引名
    @Id 标记文档 ID
    @Field 标记字段,指定类型、分词器
    @MultiField 多类型字段

    4.2 实体类编写(商品示例)

    import org.springframework.data.annotation.Id;
    import org.springframework.data.elasticsearch.annotations.*;
    import java.math.BigDecimal;

    // indexName = 索引名(必须小写)
    @Document(indexName = "product_index", createIndex = true)
    public class Product {

    @Id // 文档唯一ID
    private Long id;

    // 标题:text类型,ik分词,支持keyword精准查询
    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String title;

    // 分类:keyword,不分词
    @Field(type = FieldType.Keyword)
    private String category;

    // 价格:浮点类型
    @Field(type = FieldType.Double)
    private BigDecimal price;

    // 库存:整数
    @Field(type = FieldType.Integer)
    private Integer stock;
    }


    五、核心功能:Repository 接口开发

    5.1 基础 Repository 接口

    只需继承,无需编写实现类,自动拥有 CRUD 功能:

    import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
    import org.springframework.stereotype.Repository;

    @Repository
    public interface ProductRepository
    extends ElasticsearchRepository<Product, Long> {
    // 自动拥有:增删改查、分页、排序、count 等方法
    }

    5.2 基础 CRUD 实战

    @Service
    public class ProductService {

    @Autowired
    private ProductRepository repository;

    // 1. 新增/修改文档
    public Product save(Product product) {
    return repository.save(product);
    }

    // 2. 根据ID查询
    public Product getById(Long id) {
    return repository.findById(id).orElse(null);
    }

    // 3. 查询全部
    public Iterable<Product> findAll() {
    return repository.findAll();
    }

    // 4. 分页查询
    public Page<Product> findByPage(Pageable page) {
    return repository.findAll(page);
    }

    // 5. 删除文档
    public void delete(Long id) {
    repository.deleteById(id);
    }
    }


    六、高级查询:方法名 DSL(零代码查询)

    6.1 语法规则

    Repository 中按规则写方法名,自动生成 ES 查询:

    findBy + 字段名 + 条件(And/Or/Between/Like 等)

    6.2 常用查询示例

    @Repository
    public interface ProductRepository extends ElasticsearchRepository<Product, Long> {

    // 1. 根据标题分词查询
    List<Product> findByTitle(String title);

    // 2. 标题包含 + 分类精准匹配
    List<Product> findByTitleAndCategory(String title, String category);

    // 3. 价格区间查询
    List<Product> findByPriceBetween(BigDecimal min, BigDecimal max);

    // 4. 库存大于
    List<Product> findByStockGreaterThan(Integer stock);

    // 5. 分页 + 排序
    Page<Product> findByCategory(String category, Pageable page);
    }


    七、复杂查询:NativeSearchQuery 构建

    复杂场景(高亮、聚合、bool 查询)使用 NativeSearchQuery:

    7.1 高亮查询实战

    @Autowired
    private ElasticsearchRestTemplate template;

    public List<Product> searchHighLight(String keyword) {
    // 构建查询
    NativeSearchQuery query = new NativeSearchQueryBuilder()
    .withQuery(QueryBuilders.matchQuery("title", keyword))
    // 高亮配置
    .withHighlightFields(
    new HighlightBuilder.Field("title")
    .preTags("<span style='color:red'>")
    .postTags("</span>")
    )
    .build();

    // 执行查询并处理高亮
    SearchHits<Product> hits = template.search(query, Product.class);
    List<Product> result = new ArrayList<>();

    for (SearchHit<Product> hit : hits) {
    Product product = hit.getContent();
    // 设置高亮标题
    product.setTitle(hit.getHighlightFields().get("title").get(0));
    result.add(product);
    }
    return result;
    }


    八、完整开发流程图

    渲染错误: Mermaid 渲染失败: Parse error on line 3: …–> B[配置ES连接]B –> C[编写实体类+@Document注解] ———————-^ Expecting 'AMP', 'COLON', 'PIPE', 'TESTSTR', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'LINK_ID'


    九、最佳实践与避坑指南

  • 版本必须严格对应,否则启动失败
  • 索引名必须全小写
  • 文本分词用 ik_max_word,精准查询用 keyword
  • 大数据量必须使用分页查询
  • 复杂查询优先使用 ElasticsearchRestTemplate
  • 禁止频繁创建索引,createIndex 上线设为 false

  • 十、总结

    Spring Data Elasticsearch 是 SpringBoot 集成 ES 最简单、最优雅、企业级首选方案:

  • 简化 90% 代码:无需操作 RestHighLevelClient
  • ORM 映射:实体类 = ES 索引结构
  • Repository 模式:继承即拥有全部 CRUD
  • 方法名 DSL:零代码实现复杂查询
  • 模板增强:支持高亮、聚合、bool 等高级功能
  • 按照本文步骤,你可以在 5 分钟内完成 ES 集成,快速实现搜索业务。


    在这里插入图片描述

    🌺The End🌺点点关注,收藏不迷路🌺

    赞(0)
    未经允许不得转载:171主机测评 » Elasticsearch集成实战:Spring Data Elasticsearch从入门到精通,彻底简化开发
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址