SpringBoot+ElasticSearch 實現(xiàn)模糊查詢涣仿,批量CRUD勤庐,排序,分頁好港,高亮愉镰!

原文:blog.csdn.net/qq_52355487/article/details/123805713

一、導入elasticsearch依賴

在pom.xml里加入如下依賴

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

非常重要:檢查依賴版本是否與你當前所用的版本是否一致钧汹,如果不一致丈探,會連接失敗拔莱!

image

二类嗤、創(chuàng)建高級客戶端

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ElasticSearchClientConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("服務(wù)器IP", 9200, "http")));
        return client;
    }
}

三、基本用法

1.創(chuàng)建辨宠、判斷存在、刪除索引

import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;

@SpringBootTest
class ElasticsearchApplicationTests {

 @Autowired
 private RestHighLevelClient restHighLevelClient;

 @Test
 void testCreateIndex() throws IOException {
  //1.創(chuàng)建索引請求
  CreateIndexRequest request = new CreateIndexRequest("ljx666");
  //2.客戶端執(zhí)行請求IndicesClient货裹,執(zhí)行create方法創(chuàng)建索引嗤形,請求后獲得響應
  CreateIndexResponse response=
    restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
  System.out.println(response);
 }

 @Test
 void testExistIndex() throws IOException {
        //1.查詢索引請求
  GetIndexRequest request=new GetIndexRequest("ljx666");
        //2.執(zhí)行exists方法判斷是否存在
  boolean exists=restHighLevelClient.indices().exists(request,RequestOptions.DEFAULT);
  System.out.println(exists);
 }

 @Test
 void testDeleteIndex() throws IOException {
        //1.刪除索引請求
  DeleteIndexRequest request=new DeleteIndexRequest("ljx666");
        //執(zhí)行delete方法刪除指定索引
  AcknowledgedResponse delete = restHighLevelClient.indices().delete(request, RequestOptions.DEFAULT);
  System.out.println(delete.isAcknowledged());
 }

}

2.對文檔的CRUD

創(chuàng)建文檔:

注意:如果添加時不指定文檔ID,他就會隨機生成一個ID弧圆,ID唯一赋兵。

創(chuàng)建文檔時若該ID已存在笔咽,發(fā)送創(chuàng)建文檔請求后會更新文檔中的數(shù)據(jù)。

@Test
void testAddUser() throws IOException {
 //1.創(chuàng)建對象
 User user=new User("Go",21,new String[]{"內(nèi)卷","吃飯"});
 //2.創(chuàng)建請求
 IndexRequest request=new IndexRequest("ljx666");
 //3.設(shè)置規(guī)則 PUT /ljx666/_doc/1
 //設(shè)置文檔id=6霹期,設(shè)置超時=1s等叶组,不設(shè)置會使用默認的
 //同時支持鏈式編程如 request.id("6").timeout("1s");
 request.id("6");
 request.timeout("1s");

 //4.將數(shù)據(jù)放入請求,要將對象轉(zhuǎn)化為json格式
    //XContentType.JSON历造,告訴它傳的數(shù)據(jù)是JSON類型
 request.source(JSONValue.toJSONString(user), XContentType.JSON);
    
 //5.客戶端發(fā)送請求甩十,獲取響應結(jié)果
 IndexResponse indexResponse=restHighLevelClient.index(request,RequestOptions.DEFAULT);
 System.out.println(indexResponse.toString());
 System.out.println(indexResponse.status());
}

獲取文檔中的數(shù)據(jù):

@Test
void testGetUser() throws IOException {
 //1.創(chuàng)建請求,指定索引、文檔id
 GetRequest request=new GetRequest("ljx666","1");
 GetResponse getResponse=restHighLevelClient.get(request,RequestOptions.DEFAULT);
  
 System.out.println(getResponse);//獲取響應結(jié)果
 //getResponse.getSource() 返回的是Map集合
 System.out.println(getResponse.getSourceAsString());//獲取響應結(jié)果source中內(nèi)容吭产,轉(zhuǎn)化為字符串
  
}

更新文檔數(shù)據(jù):

注意:需要將User對象中的屬性全部指定值侣监,不然會被設(shè)置為空,如User只設(shè)置了名稱臣淤,那么只有名稱會被修改成功橄霉,其他會被修改為null。

@Test
void testUpdateUser() throws IOException {
 //1.創(chuàng)建請求,指定索引邑蒋、文檔id
 UpdateRequest request=new UpdateRequest("ljx666","6");

 User user =new User("GoGo",21,new String[]{"內(nèi)卷","吃飯"});
 //將創(chuàng)建的對象放入文檔中
 request.doc(JSONValue.toJSONString(user),XContentType.JSON);

 UpdateResponse updateResponse=restHighLevelClient.update(request,RequestOptions.DEFAULT);
 System.out.println(updateResponse.status());//更新成功返回OK
}

刪除文檔:

@Test
void testDeleteUser() throws IOException {
 //創(chuàng)建刪除請求姓蜂,指定要刪除的索引與文檔ID
 DeleteRequest request=new DeleteRequest("ljx666","6");

 DeleteResponse updateResponse=restHighLevelClient.delete(request,RequestOptions.DEFAULT);
 System.out.println(updateResponse.status());//刪除成功返回OK,沒有找到返回NOT_FOUND
}

3.批量CRUD數(shù)據(jù)

這里只列出了批量插入數(shù)據(jù)医吊,其他與此類似

注意:hasFailures()方法是返回是否失敗钱慢,即它的值為false時說明上傳成功

@Test
void testBulkAddUser() throws IOException {
 BulkRequest bulkRequest=new BulkRequest();
 //設(shè)置超時
 bulkRequest.timeout("10s");

 ArrayList<User> list=new ArrayList<>();
 list.add(new User("Java",25,new String[]{"內(nèi)卷"}));
 list.add(new User("Go",18,new String[]{"內(nèi)卷"}));
 list.add(new User("C",30,new String[]{"內(nèi)卷"}));
 list.add(new User("C++",26,new String[]{"內(nèi)卷"}));
 list.add(new User("Python",20,new String[]{"內(nèi)卷"}));

 int id=1;
 //批量處理請求
 for (User u :list){
  //不設(shè)置id會生成隨機id
  bulkRequest.add(new IndexRequest("ljx666")
    .id(""+(id++))
    .source(JSONValue.toJSONString(u),XContentType.JSON));
 }

 BulkResponse bulkResponse=restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
 System.out.println(bulkResponse.hasFailures());//是否執(zhí)行失敗,false為執(zhí)行成功
}

4.查詢所有、模糊查詢遮咖、分頁查詢滩字、排序、高亮顯示

@Test
void testSearch() throws IOException {
 SearchRequest searchRequest=new SearchRequest("ljx666");//里面可以放多個索引
 SearchSourceBuilder sourceBuilder=new SearchSourceBuilder();//構(gòu)造搜索條件

 //此處可以使用QueryBuilders工具類中的方法
 //1.查詢所有
 sourceBuilder.query(QueryBuilders.matchAllQuery());
 //2.查詢name中含有Java的
 sourceBuilder.query(QueryBuilders.multiMatchQuery("java","name"));
 //3.分頁查詢
 sourceBuilder.from(0).size(5);
    
 //4.按照score正序排列
 //sourceBuilder.sort(SortBuilders.scoreSort().order(SortOrder.ASC));
 //5.按照id倒序排列(score會失效返回NaN)
 //sourceBuilder.sort(SortBuilders.fieldSort("_id").order(SortOrder.DESC));

 //6.給指定字段加上指定高亮樣式
 HighlightBuilder highlightBuilder=new HighlightBuilder();
 highlightBuilder.field("name").preTags("<span style='color:red;'>").postTags("</span>");
 sourceBuilder.highlighter(highlightBuilder);
  
 searchRequest.source(sourceBuilder);
 SearchResponse searchResponse=restHighLevelClient.search(searchRequest,RequestOptions.DEFAULT);

 //獲取總條數(shù)
 System.out.println(searchResponse.getHits().getTotalHits().value);
 //輸出結(jié)果數(shù)據(jù)(如果不設(shè)置返回條數(shù)御吞,大于10條默認只返回10條)
 SearchHit[] hits=searchResponse.getHits().getHits();
 for(SearchHit hit :hits){
  System.out.println("分數(shù):"+hit.getScore());
  Map<String,Object> source=hit.getSourceAsMap();
  System.out.println("index->"+hit.getIndex());
  System.out.println("id->"+hit.getId());
  for(Map.Entry<String,Object> s:source.entrySet()){
   System.out.println(s.getKey()+"--"+s.getValue());
  }
 }
}

四麦箍、總結(jié)

1.大致流程

創(chuàng)建對應的請求 --> 設(shè)置請求(添加規(guī)則,添加數(shù)據(jù)等) --> 執(zhí)行對應的方法(傳入請求陶珠,默認請求選項)–> 接收響應結(jié)果(執(zhí)行方法返回值)–> 輸出響應結(jié)果中需要的數(shù)據(jù)(source挟裂,status等)

2.注意事項

  • 如果不指定id,會自動生成一個隨機id
  • 正常情況下揍诽,不應該這樣使用new IndexRequest(“l(fā)jx777”)诀蓉,如果索引發(fā)生改變了,那么代碼都需要修改暑脆,可以定義一個枚舉類或者一個專門存放常量的類渠啤,將變量用final static等進行修飾,并指定索引值添吗。其他地方引用該常量即可沥曹,需要修改也只需修改該類即可。
  • elasticsearch相關(guān)的東西,版本都必須一致妓美,不然會報錯
  • elasticsearch很消耗內(nèi)存僵腺,建議在內(nèi)存較大的服務(wù)器上運行elasticsearch,否則會因為內(nèi)存不足導致elasticsearch自動killed

推薦:2022年Java面試題整理 持續(xù)更新中

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末壶栋,一起剝皮案震驚了整個濱河市辰如,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贵试,老刑警劉巖琉兜,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異锡移,居然都是意外死亡呕童,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門淆珊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來夺饲,“玉大人,你說我怎么就攤上這事施符⊥” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵戳吝,是天一觀的道長浩销。 經(jīng)常有香客問我,道長听哭,這世上最難降的妖魔是什么慢洋? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮陆盘,結(jié)果婚禮上普筹,老公的妹妹穿的比我還像新娘。我一直安慰自己隘马,他們只是感情好太防,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著酸员,像睡著了一般蜒车。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上幔嗦,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天酿愧,我揣著相機與錄音,去河邊找鬼邀泉。 笑死嬉挡,一個胖子當著我的面吹牛叛氨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播棘伴,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼屁置!你這毒婦竟也來了焊夸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蓝角,失蹤者是張志新(化名)和其女友劉穎阱穗,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體使鹅,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡揪阶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了患朱。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鲁僚。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖裁厅,靈堂內(nèi)的尸體忽然破棺而出冰沙,到底是詐尸還是另有隱情,我是刑警寧澤执虹,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布拓挥,位于F島的核電站,受9級特大地震影響袋励,放射性物質(zhì)發(fā)生泄漏侥啤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一茬故、第九天 我趴在偏房一處隱蔽的房頂上張望盖灸。 院中可真熱鬧,春花似錦均牢、人聲如沸糠雨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽甘邀。三九已至,卻和暖如春垮庐,著一層夾襖步出監(jiān)牢的瞬間松邪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工哨查, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留逗抑,地道東北人。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像邮府,于是被迫代替她去往敵國和親荧关。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容