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 核心优势
二、版本对应关系(重中之重)
Spring Data Elasticsearch 必须严格与 ES 版本对应,否则启动报错!
| 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'
九、最佳实践与避坑指南
十、总结
Spring Data Elasticsearch 是 SpringBoot 集成 ES 最简单、最优雅、企业级首选方案:
按照本文步骤,你可以在 5 分钟内完成 ES 集成,快速实现搜索业务。

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


