Springboot3整合Elasticsearch8(elasticsearch-java)最佳實踐
1、Elasticsearch的JAVA客戶端選擇
Elasticsearch官方支持的客戶端
| 客戶端名稱 | 簡介 | 使用建議 |
|---|---|---|
| Elasticsearch Java API Client(新客戶端) | 官方推薦的新客戶端,基于 JSON Mapping(如 ElasticsearchClient 類),從 Elasticsearch 7.15 開始推出。 | ?推薦用于 Spring Boot 3+,Elasticsearch 8+ |
| RestHighLevelClient(已廢棄) | 基于 REST 的高級客戶端,是 ES 6 ~ 7 的主力客戶端,ES 8 中已標記為 deprecated。 | ?不推薦新項目使用 |
| Low Level REST Client | 底層客戶端,只提供 HTTP 封裝,不解析 JSON。 | ??適合自定義協(xié)議或處理特殊 JSON 請求場景 |
Spring官方對Elasticsearch的封裝
| 客戶端名稱 | 簡介 | 特點 |
|---|---|---|
| Spring Data Elasticsearch | Spring 官方對 Elasticsearch 的數(shù)據(jù)訪問封裝,支持 Repository 風(fēng)格的接口編程。 | ??開發(fā)效率高、和 JPA 風(fēng)格一致,但功能不如原生客戶端全 |
easy-es(dromara團隊),國人之光!
| 客戶端名稱 | 簡介 | 特點 |
|---|---|---|
| easy-es | 風(fēng)格類似 MyBatis-Plus,一致的 API 和分頁查詢方式,Java 開發(fā)者易于理解。 | ??開發(fā)效率高、但是是對RestHighLevelClient的深層封裝,容易受版本影響,小團隊維護 |
總結(jié):
RestHighLevelClient 是ES7中使用最多的客戶端,但是在ES8中已經(jīng)廢棄。
easy-es 是基于RestHighLevelClient封裝的,會比較重,代碼風(fēng)格類似 MyBatis-Plus,熟悉MP的同學(xué)容易上手,但是容易受RestHighLevelClient和Elasticsearch版本的限制,并且目前社區(qū)雖然活躍,但項目主要靠小團隊維護,不如官方客戶端那樣穩(wěn)定長期。
Elasticsearch Java API Client 是 Elasticsearch 7.15 開始推出最新的客戶端,能使用Elasticsearch中所有功能,首選首選?。。。。?!
Spring Data Elasticsearch 是Spring 官方對 Elasticsearch的封裝,Springboot3中已經(jīng)棄用了RestHighLevelClient,選擇引用了Elasticsearch Java API Client,直接解決了依賴版本沖突的問題,Spring社區(qū)強大,所以...不用我說了吧....選我!?。。?!
2、Spring Data Elasticsearch 官方文檔
Elasticsearch Clients :: Spring Data Elasticsearch
3、Springboot3整合Spring Data Elasticsearch
tips:我使用的是Springboot3.3.4版本
3.1 maven引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>引入成功之后可以看到:

elasticsearch的新客戶端elasticsearch-java也被引入了進來。
3.2 配置
yml配置文件
spring:
application:
name: cloud-elasticsearch
elasticsearch:
uris: http://127.0.0.1:9200 # 這里還要注意是https還是http協(xié)議
# username: elastic #如果有賬號密碼就要配置賬號密碼,否則可以不配置
# password: 123456
server:
port: 200004、【簡單使用】Spring Data Elasticsearch
4.1 創(chuàng)建ES實體類
創(chuàng)建完實體類后,啟動項目Spring會自動根據(jù)注解,來創(chuàng)建ES的索引(index)和映射(mapping)
@Data
@Document(indexName = "news")
public class EsNews {
@Id
private String id;
@Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer = "ik_smart")
private String title;//標題
@Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer = "ik_smart")
private String content;//內(nèi)容
@Field(type = FieldType.Keyword)
private String author;//作者
@Field(type = FieldType.Keyword)
private List<String> tags;//標簽
@Field(type = FieldType.Date,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd")
@JsonProperty("publish_date")
private Date publishDate;//發(fā)布時間
@Field(type = FieldType.Date,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd")
@JsonProperty("create_time")
private Date createTime;//創(chuàng)建時間
@Field(type = FieldType.Long)
@JsonProperty("view_count")
private Long viewCount;//閱讀量
}注解解析:
@Document(indexName = "news")
該實體對應(yīng)的索引名稱為:news
@Id
ES的唯一標識
@Field
@Field(type = FieldType.Text, analyzer = "ik_max_word",searchAnalyzer = "ik_smart")
Field(字段名) , type = FieldType.Text(字段類型為TEXT) ,analyzer = "ik_max_word"(存入時的分詞器為ik_max_word),searchAnalyzer = "ik_smart"(搜索時的分詞器為ik_smart)
@JsonProperty("publish_date")
ES中JSON字段,迎來進行序列化映射
tips:實際開發(fā)中業(yè)務(wù)實體類和ES實體類最好是分開的,業(yè)務(wù)實體類主要用來做數(shù)據(jù)庫操作,ES實體類只用來做ES檢索

4.2 繼承ElasticsearchRepository接口
public interface EsNewsRepository extends ElasticsearchRepository<EsNews,String> {
}查看ElasticsearchRepository源碼可以看到
ElasticsearchRepository也繼承了PagingAndSortingRepository(分頁和排序接口)、CrudRepository(常用基礎(chǔ)crud接口)

當你的類接口繼承了ElasticsearchRepository后,你輸入find,你會看到Spring幫你生成的所有常用簡單的查詢語句。

大部分關(guān)鍵詞用法:
| 關(guān)鍵詞 | 說明 | 等價 Elasticsearch 查詢類型 |
|---|---|---|
findBy | 查詢開始(必須) | - |
And / Or | 條件連接符 | bool 查詢 |
Is / Equals | 等于 | term |
Between | 在兩個值之間 | range |
LessThan | 小于 | range |
LessThanEqual | 小于等于 | range |
GreaterThan | 大于 | range |
GreaterThanEqual | 大于等于 | range |
After | 大于(時間) | range |
Before | 小于(時間) | range |
IsNull | 字段為 null | must_not exists |
IsNotNull / NotNull | 字段非 null | exists |
Like | 類似(不建議用,Elasticsearch 中更推薦 Containing) | match (部分分詞匹配) |
NotLike | 不類似 | bool + must_not |
StartingWith | 以…開頭(需要 keyword 類型字段,match 不支持) | prefix / wildcard |
EndingWith | 以…結(jié)尾(需 keyword 類型字段) | wildcard |
Containing / Contains | 包含(常用于全文檢索) | match |
NotContaining | 不包含 | bool + must_not |
In | 包含在列表中 | terms |
NotIn | 不包含在列表中 | bool + must_not terms |
True / False | 布爾值判斷 | term |
OrderBy | 排序 | sort |
4.3 CRUD接口使用
使用SpringBoot單元測試
4.3.1 新增
文檔單個新增(save):
@Test
@DisplayName("新增單個文檔")
void saveDoc(){
EsNews news = new EsNews();
news.setId("1");//如果不設(shè)置ID,Spring則會幫你生成一個ES風(fēng)格的隨機ID
news.setTitle("電影《不能說的秘密》熱映");
news.setContent("內(nèi)容:不能說的秘密............牛X..");
news.setAuthor("周杰倫");
news.setTags(Arrays.asList("電影", "國產(chǎn)"));
news.setPublishDate(new Date());
news.setCreateTime(new Date());
news.setViewCount(100L);
esNewsRepository.save(news);
}文檔批量新增(saveAll):
@Test
@DisplayName("批量新增文檔")
void saveBatchDoc(){
List<EsNews> newsList = new ArrayList<>();
for (int i = 1; i <= 11; i++) {
EsNews news = new EsNews();
news.setId(String.valueOf(i));
news.setTitle("電影《CPW的奇幻世界 " + i + "》");
news.setContent("內(nèi)容 " + i);
news.setAuthor("作者" + i);
news.setTags(Arrays.asList("電影", "奇幻"));
news.setPublishDate(new Date());
news.setCreateTime(new Date());
news.setViewCount(100L + i);
newsList.add(news);
}
esNewsRepository.saveAll(newsList);
}4.3.3 修改
?。?!ElasticsearchRepository?。?!的修改跟新增是同一個接口,如果你的對象攜帶ID,那么ES會先查詢文檔庫里是有存在這么一個ID,如果存在的話則進行 先刪除 然后 覆蓋??!
@Test
@DisplayName("新增單個文檔")
void saveDoc(){
EsNews news = new EsNews();
news.setId("1");//ES會先找文檔庫里是否存在改ID,先刪除再覆蓋
news.setTitle("電影《不能說的秘密》熱映");
news.setContent("內(nèi)容:不能說的秘密........牛X..更新覆蓋操作");
news.setAuthor("周杰倫");
news.setTags(Arrays.asList("電影", "國產(chǎn)"));
news.setPublishDate(new Date());
news.setCreateTime(new Date());
news.setViewCount(100L);
esNewsRepository.save(news);
}如果你想做到只修改文檔中其中一條數(shù)據(jù),比如只把作者周杰倫修改成CPW,那就需要用到第五節(jié)【高階用法】Elasticsearch Java API Client
4.3.3 查詢
需求:我要查詢文檔編號為999的文檔
tips:簡單的查詢,比如根據(jù)ID查詢文檔,ElasticsearchRepository已經(jīng)自己封裝好了,不用另外寫。(findById)
@Test
@DisplayName("根據(jù)ID查詢文檔")
void searchByID(){
Optional<EsNews> news = esNewsRepository.findById("999");
System.out.println(news);
}
需求:我要分頁查詢,標題包含【奇幻世界】,作者精準是【作者1】的文檔
tips:這種復(fù)雜多條件的就需要我們自己寫,如果是模糊查詢的則用Containing
1、EsNewsRepository新增接口findByTitleContainingOrAuthor:
public interface EsNewsRepository extends ElasticsearchRepository<EsNews,String> {
Page<EsNews> findByTitleContainingOrAuthor(String Title, String Author,Pageable pageable);
}2、使用
@Test
@DisplayName("分頁查詢條件")
void searchAll(){
Pageable pageable = PageRequest.of(0, 10);
Page<EsNews> pageList = esNewsRepository.findByTitleContainingOrAuthor("奇幻世界","作者1",pageable);
for (EsNews news : pageList) {
System.out.println(news);
}
}
根據(jù)4.2中的關(guān)鍵詞,還有更多的用法例如過濾、排序
4.3.4 刪除
刪除就沒什么好說的了,直接上代碼!
@Test
@DisplayName("根據(jù)ID刪除文檔")
void deleteDocById(){
esNewsRepository.deleteById("1");
System.out.println("ID為1的文檔刪除成功");
}
@Test
@DisplayName("批量刪除文檔")
void deleteBatchDoc(){
esNewsRepository.deleteAll();
System.out.println("文檔批量刪除成功");
}
@Test
@DisplayName("根據(jù)ID批量刪除文檔")
void deleteBatchDocByIds(){
List<String> idList = Arrays.asList("1", "2");
esNewsRepository.deleteAllById(idList);
System.out.println("根據(jù)ID批量刪除文檔刪除成功");
}5、【高階用法】Elasticsearch Java API Client
1、修改文檔中的某一條數(shù)據(jù)
2、高級聚合查詢
6、【最佳實踐】Elasticsearch+消息隊列(RabbitMQ)+數(shù)據(jù)庫(MYSQL)
實際應(yīng)用
到此這篇關(guān)于Springboot3整合Elasticsearch8(elasticsearch-java)最佳實踐的文章就介紹到這了,更多相關(guān)Springboot3整合Elasticsearch內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springboot整合spring-boot-starter-data-elasticsearch的過程
- SpringBoot2如何集成Elasticsearch6.x(TransportClient方式)
- SpringBoot集成ElasticSearch(ES)實現(xiàn)全文搜索功能
- SpringBoot3集成ElasticSearch的方法詳解
- SpringBoot實現(xiàn)elasticsearch 查詢操作(RestHighLevelClient 的案例實戰(zhàn))
- SpringBoot集成elasticsearch使用圖文詳解
- SpringBoot整合ES-Elasticsearch的實例
- 解決SpringBoot整合ElasticSearch遇到的連接問題
- springBoot集成Elasticsearch 報錯 Health check failed的解決
- springboot中使用ElasticSearch的詳細教程
相關(guān)文章
SpringBoot預(yù)加載與懶加載實現(xiàn)方法超詳細講解
Spring一直被詬病啟動時間慢,可Spring/SpringBoot是輕量級的框架。因為當Spring項目越來越大的時候,在啟動時加載和初始化Bean就會變得越來越慢,很多時候我們在啟動時并不需要加載全部的Bean,在調(diào)用時再加載就行,那這就需要預(yù)加載與懶加載的功能了2022-11-11
springboot多模塊項目mvn打包遇到存在依賴但卻無法發(fā)現(xiàn)符號問題
在SpringBoot多模塊項目中,如果遇到依賴存在但無法發(fā)現(xiàn)符號的問題,常見原因可能是pom.xml配置問題,例如,如果某個模塊僅作為依賴而不是啟動工程,不應(yīng)在其pom中配置spring-boot-maven-plugin插件,因為這將影響jar包的生成方式2024-09-09
Java中Dijkstra算法求解最短路徑的實現(xiàn)
Dijkstra算法是一種解決最短路徑問題的常用算法,本文主要介紹了Java中Dijkstra算法求解最短路徑的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-09-09
java控制臺實現(xiàn)學(xué)生信息管理系統(tǒng)
這篇文章主要為大家詳細介紹了java控制臺實現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02
結(jié)合mybatis-plus實現(xiàn)簡單不需要寫sql的多表查詢
這篇文章主要給大家介紹了關(guān)于結(jié)合mybatis-plus實現(xiàn)簡單不需要寫sql的多表查詢的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用mybatis-plus具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09

