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。

🔧適合自定義協議或處理特殊 JSON 請求場景

Spring官方對Elasticsearch的封裝

客戶端名稱簡介特點
Spring Data ElasticsearchSpring 官方對 Elasticsearch 的數據訪問封裝,支持 Repository 風格的接口編程。👍開發效率高、和 JPA 風格一致,但功能不如原生客戶端全

easy-es(dromara團隊),國人之光!

客戶端名稱簡介特點
easy-es風格類似 MyBatis-Plus,一致的 API 和分頁查詢方式,Java 開發者易于理解。👍開發效率高、但是是對RestHighLevelClient的深層封裝,容易受版本影響,小團隊維護

總結:

RestHighLevelClient 是ES7中使用最多的客戶端,但是在ES8中已經廢棄。

easy-es? 是基于RestHighLevelClient封裝的,會比較重,代碼風格類似 MyBatis-Plus,熟悉MP的同學容易上手,但是容易受RestHighLevelClient和Elasticsearch版本的限制,并且目前社區雖然活躍,但項目主要靠小團隊維護,不如官方客戶端那樣穩定長期。

Elasticsearch Java API Client 是 Elasticsearch 7.15 開始推出最新的客戶端,能使用Elasticsearch中所有功能,首選首選!!!!!!

Spring Data Elasticsearch 是Spring 官方對 Elasticsearch的封裝,Springboot3中已經棄用了RestHighLevelClient,選擇引用了Elasticsearch Java API Client,直接解決了依賴版本沖突的問題,Spring社區強大,所以...不用我說了吧....選我!!!!!

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-elasticsearchelasticsearch:uris: http://127.0.0.1:9200 #  這里還要注意是https還是http協議
#    username: elastic #如果有賬號密碼就要配置賬號密碼,否則可以不配置
#    password: 123456server:port: 20000

4、【簡單使用】Spring Data Elasticsearch

4.1 創建ES實體類

創建完實體類后,啟動項目Spring會自動根據注解,來創建ES的索引(index)和映射(mapping)

@Data
@Document(indexName = "news")
@JsonIgnoreProperties(ignoreUnknown = true)
@AllArgsConstructor
@NoArgsConstructor
public class EsNews {@Idprivate 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;//內容@Field(type = FieldType.Keyword)private String author;//作者@Field(type = FieldType.Keyword)private List<String> tags;//標簽@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")@Field(type = FieldType.Date,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd")@JsonProperty("publish_date")private Date publishDate;//發布時間@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")@Field(type = FieldType.Date,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd")@JsonProperty("create_time")private Date createTime;//創建時間@Field(type = FieldType.Long)@JsonProperty("view_count")private Long viewCount;//閱讀量}

注解解析:

@Document(indexName = "news")

該實體對應的索引名稱為: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:實際開發中業務實體類和ES實體類最好是分開的,業務實體類主要用來做數據庫操作,ES實體類只用來做ES檢索

4.2 繼承ElasticsearchRepository接口

public interface EsNewsRepository extends ElasticsearchRepository<EsNews,String> {}

查看ElasticsearchRepository源碼可以看到

ElasticsearchRepository也繼承了PagingAndSortingRepository(分頁和排序接口)、CrudRepository(常用基礎crud接口)

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

大部分關鍵詞用法:

關鍵詞說明等價 Elasticsearch 查詢類型
findBy查詢開始(必須)-
And / Or條件連接符bool 查詢
Is / Equals等于term
Between在兩個值之間range
LessThan小于range
LessThanEqual小于等于range
GreaterThan大于range
GreaterThanEqual大于等于range
After大于(時間)range
Before小于(時間)range
IsNull字段為 nullmust_not exists
IsNotNull / NotNull字段非 nullexists
Like類似(不建議用,Elasticsearch 中更推薦 Containingmatch (部分分詞匹配)
NotLike不類似bool + must_not
StartingWith以…開頭(需要 keyword 類型字段,match 不支持)prefix / wildcard
EndingWith以…結尾(需 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");//如果不設置ID,Spring則會幫你生成一個ES風格的隨機IDnews.setTitle("電影《不能說的秘密》熱映");news.setContent("內容:不能說的秘密............牛X..");news.setAuthor("周杰倫");news.setTags(Arrays.asList("電影", "國產"));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("內容 " + 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("內容:不能說的秘密........牛X..更新覆蓋操作");news.setAuthor("周杰倫");news.setTags(Arrays.asList("電影", "國產"));news.setPublishDate(new Date());news.setCreateTime(new Date());news.setViewCount(100L);esNewsRepository.save(news);}

如果你想做到只修改文檔中其中一條數據,比如只把作者周杰倫修改成CPW,那就需要用到第五節【高階用法】Elasticsearch Java API Client

4.3.3 查詢

需求:我要查詢文檔編號為999的文檔

tips:簡單的查詢,比如根據ID查詢文檔,ElasticsearchRepository已經自己封裝好了,不用另外寫。(findById)

    @Test@DisplayName("根據ID查詢文檔")void searchByID(){Optional<EsNews> news = esNewsRepository.findById("999");System.out.println(news);}

需求:我要分頁查詢,標題包含【奇幻世界】,作者精準是【作者1】的文檔

tips:這種復雜多條件的就需要我們自己寫,如果是模糊查詢的則用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);}}

根據4.2中的關鍵詞,還有更多的用法例如過濾、排序

4.3.4?刪除

刪除就沒什么好說的了,直接上代碼!

    @Test@DisplayName("根據ID刪除文檔")void deleteDocById(){esNewsRepository.deleteById("1");System.out.println("ID為1的文檔刪除成功");}@Test@DisplayName("批量刪除文檔")void deleteBatchDoc(){esNewsRepository.deleteAll();System.out.println("文檔批量刪除成功");}@Test@DisplayName("根據ID批量刪除文檔")void deleteBatchDocByIds(){List<String> idList = Arrays.asList("1", "2");esNewsRepository.deleteAllById(idList);System.out.println("根據ID批量刪除文檔刪除成功");}

5、【高階用法】Elasticsearch Java API Client

一句話:Spring Data Elasticsearch不能實現的,再用Elasticsearch Java API Client例如只更新數據中的個別字段數據,高級查詢(聚合查詢),bulk函數等。。

Elasticsearch Java API Client對熟悉ES語句的同學非常友好,學會基本代碼用法跟寫語句一樣絲滑。

不熟悉語句建議看一下ES入門教程:Elasticsearch8(ES)保姆級菜鳥入門教程-CSDN博客

建議看著文檔配合服用~

5.1?ElasticsearchClient

    @Autowiredprivate ElasticsearchClient elasticsearchClient;

所有的ES8功能都在ElasticsearchClient中,先來看看有哪些方法:

可以看出CRUD的方法和參數,分別不同:

查詢的語句用的是SearchRequest

更新的語句用的是UpdateRequest

新增的語句用的是CreateRequest

刪除的語句用的是DeleteRequest

批量操作語句用的是BulkRequest

5.2 更新數據個別字段

需求:更新999號文檔,將作者名修改為CPW,標題修改為:CPW的《不能說的秘密》

    @Test@DisplayName("更新數據的個別字段")void updateNews() throws IOException {UpdateRequest<Object, Object> updateRequest = UpdateRequest.of(u -> u.index("news").id("999").doc(Map.of("author", "CPW","title", "CPW的《不能說的秘密》")));elasticsearchClient.update(updateRequest, EsNews.class);}

對比語句:

效果:

5.3 bulk(高性能批量操作)

例子:bulk的批量插入

    @Test@DisplayName("bulk的批量使用")void bulkNews() throws IOException {//數據List<EsNews> newsList = new ArrayList<>();EsNews news1 = new EsNews("777", "CPW的Elasticsearch入門1", "CPW寫的Elasticsearch入門教程,整合了Springboot3", "張三", Arrays.asList("教程", "入門"),new Date(), new Date(), 1000L);EsNews news2 = new EsNews("888", "CPW的Elasticsearch入門2", "CPW寫的Elasticsearch入門教程,整合了Springboot3", "李四", Arrays.asList("教程", "入門"),new Date(), new Date(), 1000L);newsList.add(news1);newsList.add(news2);//構建bulkRequest請求BulkRequest.Builder builder = new BulkRequest.Builder();for (EsNews news : newsList) {builder.operations(op -> op.index(idx -> idx.index("news").id(news.getId()).document(news)));}BulkResponse bulk = elasticsearchClient.bulk(builder.build());if (bulk.errors()) {System.out.println("存在失敗的操作:");bulk.items().forEach(item -> {if (item.error() != null) {System.out.println("失敗項: " + item.error().reason());}});} else {System.out.println("批量新增成功,共新增: " + bulk.items().size() + " 條");}}

需要使用到批量更新,刪除,等操作直接修改builder.operations下的接口即可。

5.4 高亮查詢

    @Test@DisplayName("高亮查詢")void highLightNews() throws IOException {SearchRequest searchRequest = SearchRequest.of(s -> s.index("news").query(q -> q.multiMatch(m -> m.query("CPW").fields("title", "content"))).highlight(h -> h.fields("title",f -> f)//f->f啟動默認配置,等同于.preTags("<em>").postTags("</em>").fields("content",f -> f).preTags("<em style='color:red'>") // 自定義高亮前綴標簽.postTags("</em>")));SearchResponse<EsNews> search = elasticsearchClient.search(searchRequest, EsNews.class);List<Hit<EsNews>> hits = search.hits().hits();hits.forEach(hit->{if(hit.highlight().containsKey("title") && hit.source() != null){hit.source().setTitle(hit.highlight().get("title").get((0)));}if(hit.highlight().containsKey("content") && hit.source() != null){hit.source().setContent(hit.highlight().get("content").get((0)));}System.out.println(hit.source());});}

ES語句對比:

返回結果:

5.5 聚合查詢

需求:查詢每個作者,各自寫了多少篇新聞。

@Test@DisplayName("聚合查詢")void BucketingNews() throws IOException {SearchRequest searchRequest = SearchRequest.of(s -> s.index("news").size(0).aggregations("author_count",a -> a.terms(t -> t.field("author"))));SearchResponse<EsNews> search = elasticsearchClient.search(searchRequest, EsNews.class);List<StringTermsBucket> CountList = search.aggregations().get("author_count").sterms().buckets().array();System.out.println(CountList);}

6、【最佳實踐】Elasticsearch+消息隊列(RabbitMQ)+數據庫(MYSQL)

實際應用

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90067.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90067.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90067.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenCV 官翻8 - 其他算法

文章目錄高動態范圍成像引言曝光序列源代碼示例圖像說明結果色調映射圖像曝光融合附加資源高級圖像拼接 API&#xff08;Stitcher 類&#xff09;目標代碼說明相機模型試用指南圖像拼接詳解 (Python OpenCV >4.0.1)stitching_detailed如何使用背景減除方法目標代碼代碼解析結…

2025年一區SCI-回旋鏢氣動橢圓優化算法Boomerang Aerodynamic Ellipse-附Matlab免費代碼

引言 本期介紹一種新的元啟發式算法——回旋鏢氣動橢圓優化算法Boomerang Aerodynamic Ellipse Optimizer (BAEO)。該優化器的靈感來自于飛行中的回旋鏢的空氣動力學行為&#xff0c;明確地建模了釋放角和發射力如何塑造其軌跡。于2025年7月最新發表在JCR 1區&#xff0c;中科…

Custom SRP - Custom Render Pipeline

https://catlikecoding.com/unity/tutorials/custom-srp/custom-render-pipeline/ 1. 新建 Render Pipeline 任何內容的渲染&#xff0c;最終都是要由 unity 決定在哪里&#xff0c;什么時候&#xff0c;以哪些參數進行渲染。根據目標效果的復雜程度&#xff0c;決定渲染的過程…

C語言面向對象編程

1.內核通用鏈表一、什么是 list_head&#xff1f;list_head 是 Linux 內核中自己實現的一種 雙向循環鏈表 的結構&#xff0c;定義在 <linux/list.h> 中。它設計得非常輕巧、靈活&#xff0c;廣泛用于內核模塊、驅動、進程調度、網絡協議棧等。它的關鍵思想是&#xff1a…

Spring Boot+Redis Zset:三步構建高可靠延遲隊列系統

系統設計架構圖---------------- ----------------- ---------------- | | | | | | | 生產者 |------>| Redis ZSet |------>| 定時任務消費者 | | (添加延遲任務) | | (延…

MCP vs 傳統集成方案:REST API、GraphQL、gRPC的終極對比

MCP vs 傳統集成方案&#xff1a;REST API、GraphQL、gRPC的終極對比 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般絢爛的技術棧中&#xff0c;我是那個永不停歇的色彩收集者。 &#x1f98b; 每一個優化都是我培育的花朵&#xff0c;每一個特…

SQL語句中鎖的使用與優化

一、鎖機制簡介1.定義在數據庫中&#xff0c;除了傳統的計算資源&#xff08;如CPU、RAM、I/O等&#xff09;的爭用以外&#xff0c;數據也是一種供需要用戶共享的資源。如何保證數據并發訪問的一致性、有效性是所有數據庫必須解決的一個問題&#xff0c;鎖沖突也是影響數據庫并…

Linux筆記1——簡介安裝

操作系統給用戶一個操作界面&#xff0c;用戶通過操作界面使用系統資源Linux內核管理控制硬件&#xff0c;和硬件打交道SCSI&#xff08;盤&#xff09;sd**;第一個*表示磁盤順序&#xff0c;第二個*表示分區。例如&#xff1a;sda\sdb\sdc,sda1,sda2NVMe&#xff08;盤&#x…

GoLand 部署第一個項目

前言&#xff1a;Go環境部署分為兩種模式&#xff0c;一種是基于GOPATH部署&#xff08;老版本&#xff09;&#xff0c;另一種是基于Module部署&#xff08;新版本v1.11開始&#xff09;。GOPATH&#xff1a;需要配置GOPATH路徑&#xff0c;將GOPATH目錄視為工作目錄&#xff…

Mosaic數據增強介紹

1. 核心概念與目標Mosaic 是一種在計算機視覺&#xff08;尤其是目標檢測任務&#xff09;中非常流行且強大的數據增強技術。它最早由 Ultralytics 的 Alexey Bochkovskiy 在 YOLOv4 中提出并推廣&#xff0c;后來被廣泛應用于 YOLOv5, YOLOv7, YOLOv8 等模型以及其他目標檢測框…

LINUX 722 邏輯卷快照

邏輯卷快照 lvcreate -L 128M -s -n lv1-snap /dev/vg1/lv1 lvs lvscan mount -o ro /dev/vg1/lv1 /mmt/lv1-snap dmsetup ls --tree 測試 lvs /dev/vg1/lv1-snap dd if/dev/zero of/uc1/test bs1M count40 lvs /dev/vg1/lv1-snap 問題 [rootweb ~]# cd /mnt [rootweb mnt]# m…

Springboot+vue個人健康管理系統的設計與實現

文章目錄前言詳細視頻演示具體實現截圖后端框架SpringBoot前端框架Vue持久層框架MyBaits成功系統案例&#xff1a;代碼參考數據庫源碼獲取前言 博主介紹:CSDN特邀作者、985高校計算機專業畢業、現任某互聯網大廠高級全棧開發工程師、Gitee/掘金/華為云/阿里云/GitHub等平臺持續…

數據結構 --棧和隊鏈

一.棧的概念一種特殊的線性表&#xff0c;只能從固定的一端插入和刪除元素。棧中元素遵循先進后出的原則。二.模擬實現public class MyStack {public int size;public int[] array;public MyStack(){array new int[10];}private void grow(){array Arrays.copyOf(array,array…

文檔處理控件TX Text Control系列教程:使用 C# .NET 將二維碼添加到 PDF 文檔

PDF 文檔通常是合同、發票、證書和報告的最終格式。盡管它們在設計上是靜態的&#xff0c;但用戶現在希望能夠與它們交互、驗證信息并直接從這些文件訪問數字服務。這時&#xff0c;二維碼就變得至關重要。 PDF 文檔中的二維碼將印刷或數字內容與動態在線體驗連接起來。用戶只需…

Google Chrome 谷歌瀏覽器全部版本集合

Google Chrome 谷歌瀏覽器全部版本集合 Collection of all software versions of Google Chrome. 項目介紹 本項目為Google Chrome谷歌瀏覽器的全部版本集合&#xff0c;方便大家下載舊版本使用。 因為Gitee項目限制倉庫1G大小&#xff0c;所以許多谷歌瀏覽器版本無法上傳。…

論文略讀:Towards Safer Large Language Models through Machine Unlearning

ACL 2024大型語言模型&#xff08;LLMs&#xff09;的迅猛發展展現了其在多個領域的巨大潛力&#xff0c;這主要得益于其廣泛的預訓練知識和出色的泛化能力。然而&#xff0c;當面對問題性提示&#xff08;problematic prompts&#xff09;時&#xff0c;LLMs 仍然容易生成有害…

深度學習 ---參數初始化以及損失函數

深度學習 —參數初始化以及損失函數 文章目錄深度學習 ---參數初始化以及損失函數一&#xff0c;參數初始化1.1 固定值初始化1.1.1 全0初始化1.1.2 全1初始化1.3 任意常數初始化1.2 隨機初始化一&#xff0c;參數初始化 神經網絡的參數初始化是訓練深度學習模型的關鍵步驟之一…

JS--M端事件

移動端&#xff08;Mobile 端&#xff0c;簡稱 M 端&#xff09;開發中&#xff0c;由于設備特性&#xff08;觸摸屏、手勢操作等&#xff09;&#xff0c;需要處理一些與桌面端不同的事件。這些事件主要針對觸摸交互、手勢識別等場景 一、觸摸事件&#xff08;Touch Events&am…

Linux網絡編程-tcp

tcp、udp對比&#xff1a;UDP1. 特點無連接&#xff1a;無需建立連接即可發送數據。不可靠&#xff1a;不保證數據順序或完整性。低延遲&#xff1a;適合實時性要求高的場景。2. 應用場景視頻/音頻流傳輸&#xff08;如直播&#xff09;。DNS 查詢、在線游戲。TCP1. 特點面向連…

記一次flink資源使用優化

一.現狀分析 現有任務的資源配置如下&#xff0c;根據ui監控中Garbage Collection可以發現&#xff0c;此任務頻繁的發生GC&#xff0c;且老年代GC時間較久二.整體memory使用分析如下Framework Heap&#xff08;框架堆內存&#xff09;用于Flink框架自身的堆內存&#xff08;如…