SpringBoot整合Elasticsearch實(shí)現(xiàn)全文檢索功能
當(dāng)項(xiàng)目里出現(xiàn)模糊搜索、關(guān)鍵詞高亮、分詞檢索、熱搜推薦、商品搜索、文章全文檢索這類需求時(shí),MySQL 的 like %xxx% 已經(jīng)完全頂不住了,這時(shí)候就必須上專業(yè)的搜索引擎——Elasticsearch。
它天生支持分布式、PB 級(jí)數(shù)據(jù)、毫秒級(jí)響應(yīng)、強(qiáng)大的分詞與聚合能力,是目前后端全文檢索的標(biāo)配方案。
這一篇從零帶你整合 SpringBoot + ES,從環(huán)境搭建、分詞配置、CRUD、高亮查詢、分頁(yè)、聚合、到真實(shí)業(yè)務(wù)場(chǎng)景。
一、Elasticsearch 適用場(chǎng)景
- 商城商品搜索、店鋪搜索
- 文章/博客/文檔全文檢索
- 日志檢索、運(yùn)維監(jiān)控(ELK)
- 熱搜、聯(lián)想詞、推薦補(bǔ)全
- 多條件篩選 + 排序 + 高亮
- 高并發(fā)模糊查詢
二、環(huán)境說(shuō)明
- SpringBoot 2.x/3.x
- Elasticsearch 7.x / 8.x(本文以 7.x 為例)
- IK 分詞器(必須安裝,中文檢索必備)
- Kibana(可選,用于調(diào)試 DSL)
三、引入 Maven 依賴
注意:SpringBoot 版本與 ES 版本必須嚴(yán)格對(duì)應(yīng),否則會(huì)報(bào)版本不兼容錯(cuò)。
<!-- Elasticsearch -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>四、application.yml 配置
spring:
elasticsearch:
uris: http://localhost:9200
# 8.x 需要開啟賬號(hào)密碼
# username: elastic
# password: 123456五、核心注解說(shuō)明
@Document:標(biāo)記文檔,映射 ES 索引
indexName:索引名(相當(dāng)于數(shù)據(jù)庫(kù)名)shards:分片數(shù)replicas:副本數(shù)
@Id:文檔主鍵
@Field:字段類型、分詞器配置type = FieldType.Text:文本,可分詞type = FieldType.Keyword:不分詞,精確匹配analyzer = "ik_max_word":IK 分詞(中文)
六、實(shí)體類構(gòu)建(文章檢索示例)
package com.demo.entity;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.time.LocalDateTime;
@Data
@Document(
indexName = "article",
shards = 1,
replicas = 0
)
public class ArticleES {
@Id
private Long id;
// 標(biāo)題:分詞檢索
@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
private String title;
// 內(nèi)容:全文檢索
@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_max_word")
private String content;
// 作者:精確匹配,不分詞
@Field(type = FieldType.Keyword)
private String author;
// 瀏覽量
@Field(type = FieldType.Integer)
private Integer viewCount;
// 分類
@Field(type = FieldType.Keyword)
private String category;
@Field(type = FieldType.Date)
private LocalDateTime createTime;
}七、兩種操作方式
SpringBoot 操作 ES 主要兩種方式:
- ElasticsearchRepository:簡(jiǎn)單 CRUD,類似 JPA
- ElasticsearchTemplate / ElasticsearchRestTemplate:復(fù)雜高亮、聚合、多條件查詢
方式一:Repository 快速 CRUD
1. 定義 Repository
package com.demo.repository;
import com.demo.entity.ArticleES;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ArticleESRepository extends ElasticsearchRepository<ArticleES, Long> {
// 根據(jù)標(biāo)題檢索
List<ArticleES> findByTitle(String title);
}2. 基礎(chǔ)增刪改查
@Service
@RequiredArgsConstructor
public class ArticleESService {
private final ArticleESRepository repository;
// 新增/更新文檔
public ArticleES save(ArticleES articleES) {
return repository.save(articleES);
}
// 根據(jù)ID查詢
public ArticleES findById(Long id) {
return repository.findById(id).orElse(null);
}
// 查詢?nèi)?
public Iterable<ArticleES> findAll() {
return repository.findAll();
}
// 刪除
public void deleteById(Long id) {
repository.deleteById(id);
}
}方式二:RestTemplate 復(fù)雜查詢
支持高亮、多條件、分頁(yè)、排序、模糊、范圍、must/should 組合。
1. 全文檢索 + 高亮顯示
@Autowired
private ElasticsearchRestTemplate restTemplate;
public List<ArticleES> search(String keyword) {
// 1. 構(gòu)建查詢條件:標(biāo)題 or 內(nèi)容匹配關(guān)鍵詞
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.multiMatchQuery(keyword, "title", "content"))
// 高亮配置
.withHighlightFields(
new HighlightBuilder.Field("title").preTags("<span style='color:red'>").postTags("</span>"),
new HighlightBuilder.Field("content").preTags("<span style='color:red'>").postTags("</span>")
)
// 分頁(yè)
.withPageable(PageRequest.of(0, 10))
// 排序
.withSort(SortBuilders.fieldSort("viewCount").order(SortOrder.DESC))
.build();
// 2. 執(zhí)行查詢
SearchHits<ArticleES> searchHits = restTemplate.search(query, ArticleES.class);
// 3. 處理高亮結(jié)果
List<ArticleES> resultList = new ArrayList<>();
for (SearchHit<ArticleES> hit : searchHits.getSearchHits()) {
ArticleES article = hit.getContent();
// 替換高亮標(biāo)題
Map<String, List<String>> highlightFields = hit.getHighlightFields();
if (highlightFields.containsKey("title")) {
article.setTitle(highlightFields.get("title").get(0));
}
if (highlightFields.containsKey("content")) {
article.setContent(highlightFields.get("content").get(0));
}
resultList.add(article);
}
return resultList;
}八、更多常用查詢示例
1. 精確匹配(must)
.withQuery(QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("category", "Java"))
.must(QueryBuilders.rangeQuery("viewCount").gte(100))
)2. 或查詢(should)
.withQuery(QueryBuilders.boolQuery()
.should(QueryBuilders.matchQuery("title", "SpringBoot"))
.should(QueryBuilders.matchQuery("content", "Redis"))
)3. 范圍查詢
QueryBuilders.rangeQuery("viewCount").gte(100).lte(10000)4. 模糊查詢
QueryBuilders.fuzzyQuery("title", "SpringBoot")5. 聚合查詢(按分類統(tǒng)計(jì)數(shù)量)
.withAggregation(AggregationBuilders.terms("group_category").field("category"))九、數(shù)據(jù)同步(MySQL ↔ ES)
企業(yè)級(jí)必須做數(shù)據(jù)同步,常見(jiàn)方案:
- 簡(jiǎn)單方案:新增/更新數(shù)據(jù)庫(kù)時(shí),同步更新 ES
- 中間件方案:Canal / Debezium 監(jiān)聽 binlog 自動(dòng)同步
- 定時(shí)任務(wù):適合數(shù)據(jù)實(shí)時(shí)性要求不高的場(chǎng)景
十、IK 分詞器(中文必備)
安裝后才能正確拆分中文
支持自定義擴(kuò)展詞庫(kù)(如:Java、SpringBoot、云原生)
分詞模式:
ik_max_word:最細(xì)粒度拆分ik_smart:粗粒度拆分
十一、注意事項(xiàng)
1. SpringBoot 與 ES 版本不兼容 → 啟動(dòng)直接報(bào)錯(cuò)
2. 未安裝 IK 分詞 → 中文搜索效果極差
3. keyword 不能模糊查詢 → 必須用 text + 分詞
4. 高亮不生效 → 字段名與查詢不匹配
5. 深度分頁(yè)性能差 → 盡量用 scroll 或 search_after
6. 索引不存在 → 自動(dòng)創(chuàng)建或手動(dòng)創(chuàng)建索引
十二、總結(jié)
SpringBoot 整合 Elasticsearch 是全文檢索的標(biāo)準(zhǔn)方案:
- 引入依賴 → 配置連接 → 定義文檔 → 構(gòu)建查詢
- 簡(jiǎn)單 CRUD 用 Repository
- 復(fù)雜高亮、多條件、聚合用 RestTemplate
你們項(xiàng)目里用 ES 做什么業(yè)務(wù)?遇到過(guò)分詞、同步、性能問(wèn)題嗎?
以上就是SpringBoot整合Elasticsearch實(shí)現(xiàn)全文檢索功能的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot Elasticsearch全文檢索的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
IntelliJIDEA中實(shí)現(xiàn)SpringBoot多實(shí)例運(yùn)行的兩種方式
在微服務(wù)開發(fā)中,經(jīng)常需要同時(shí)啟動(dòng)多個(gè)服務(wù)實(shí)例進(jìn)行測(cè)試或模擬集群環(huán)境,?IntelliJ?IDEA?作為Java開發(fā)者常用工具,提供了靈活的多實(shí)例啟動(dòng)支持,本文將詳細(xì)介紹如何通過(guò)修改配置?和批量啟動(dòng)?兩種方式實(shí)現(xiàn)SpringBoot多實(shí)例運(yùn)行,并解決常見(jiàn)問(wèn)題,需要的朋友可以參考下2025-03-03
eclipse構(gòu)建和發(fā)布maven項(xiàng)目的教程
這篇文章主要為大家詳細(xì)介紹了eclipse構(gòu)建和發(fā)布maven項(xiàng)目的教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
SpringBoot實(shí)現(xiàn)全局異常的封裝和統(tǒng)一處理
在Spring Boot應(yīng)用中,全局異常的處理是一個(gè)非常重要的方面,本文主要為大家詳細(xì)介紹了如何在Spring Boot中進(jìn)行全局異常的封裝和統(tǒng)一處理,需要的可以參考下2023-12-12
Activiti7通過(guò)代碼動(dòng)態(tài)生成工作流實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了Activiti7通過(guò)代碼動(dòng)態(tài)生成工作流實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
SpringBoot基于Mybatis攔截器和JSqlParser實(shí)現(xiàn)數(shù)據(jù)隔離
本文將介紹如何在 Spring Boot 項(xiàng)目中利用Mybatis的強(qiáng)大攔截器機(jī)制結(jié)合JSqlParser,一個(gè)功能豐富的 SQL 解析器,來(lái)輕松實(shí)現(xiàn)數(shù)據(jù)隔離的目標(biāo),本文根據(jù)示例展示如何根據(jù)當(dāng)前的運(yùn)行環(huán)境來(lái)實(shí)現(xiàn)數(shù)據(jù)隔離,需要的朋友可以參考下2024-04-04

