SpringBoot 使用JestClient操作Elasticsearch


1.Jest介紹

image

操作Elasticsearch的客戶端有很多,SpringBoot也提供了方式去操作,這里介紹另外一種方式去使用Elasticsearch --- JestClient

JestClient是一款基於HTTP方式操作的Elasticsearch的客戶端,支持同步和異步操作,同時也可以結合ElasticSearch的依賴進行操作Elasticsearch。

支持多個版本的Elasticsearch,如下:

Jest Version Elasticsearch Version
>= 6.0.0 6
>= 5.0.0 5
>= 2.0.0 2
0.1.0 - 1.0.0 1
<= 0.0.6 < 1

更多信息可以查看github,地址是:https://github.com/searchbox-io/Jest

2.SpringBoot整合JestClient

接下來介紹如何在SpringBoot中使用JestClient操作Elasticsearch。

2.1 前置工作

首先啟動Elasticsearch,我這里是在本地啟動的Elasticsearch,版本是6.8.2,為了方便查看數據,這里使用Elasticsearch-Head插件,如下圖所示。

image

2.2 添加Jest依賴

創建項目,在pom文件中加入Jest依賴(這里根據上面版本對應添加依賴),這里額外添加量了elasticsearch和lombok為了方便操作,如下:

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.dalaoyang</groupId> <artifactId>springboot_jestclient</artifactId> <version>0.0.1-SNAPSHOT</version> <name>springboot_jestclient</name> <description>springboot_jestclient</description> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.2.6.RELEASE</spring-boot.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.searchbox</groupId> <artifactId>jest</artifactId> <version>6.3.1</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version> </dependency> <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elasticsearch</artifactId> <version>6.8.2</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.2.6.RELEASE</version> </plugin> </plugins> </build> </project> 

2.3 配置文件

在配置文件中添加elasticsearch相關配置,其中uris配置Elasticsearch的HTTP端口,如本文添加的配置:

spring.application.name=springboot_jestclient # 應用服務web訪問端口 server.port=8888 spring.elasticsearch.rest.uris=http://localhost:9200 spring.elasticsearch.jest.username=elastic spring.elasticsearch.jest.password=elastic 

到這里其實已經整合完成了,是不是非常簡單?

3.Elasticsearch基本操作

接下介紹如何操作Elasticsearch,這里分別介紹如下幾部分內容:

  • 索引文檔
  • 索引類操作
  • 文檔類操作
  • 查詢操作

3.1 文檔實體

這里創建一個Book文檔做為示例,其中@JestId為文檔id,即Elasticsearch中的_id字段,本文BookDocument內容如下:

package com.dalaoyang.document; import io.searchbox.annotations.JestId; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @AllArgsConstructor @NoArgsConstructor public class BookDocument { @JestId private String id; private String bookName; private String bookAuthor; private Integer pages; private String desc; } 

為了方便操作,這里創建了一個request對象進行操作,如下:

package com.dalaoyang.model; import com.dalaoyang.document.BookDocument; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @Builder @AllArgsConstructor @NoArgsConstructor public class BookRequest { //刪除文檔用 private String id; //查詢用 private String keyword; private String indexName; private String typeName; //新增文檔用 private BookDocument body; } 

在使用相關操作時,其實都是通過io.searchbox.client.JestClient#execute來進行操作(需要注意,這里沒有對JestClient進行配置,只是使用的默認的配置),將對應動作當做參數傳入,接下來介紹幾個常用的動作。

3.2 索引類操作

結合MySQL來看的話,索引可以理解為一個數據庫,索引相關的操作可能不是很多,這里介紹相對比較常用的是創建索引和刪除索引,如下:

3.2.1 創建索引

CreateIndex createIndex = new CreateIndex.Builder(indexName).build(); 

3.2.2 刪除索引

DeleteIndex deleteIndex = new DeleteIndex.Builder(indexName).build(); 

通過上面兩個操作可以看到,都是通過使用對應的Index實體來操作對應實體,當然還有一些不是很常用的,如果有需要可以查看相關文檔進行使用,這里不一一介紹了,完整s示例內容如下:

package com.dalaoyang.web; import io.searchbox.client.JestClient; import io.searchbox.client.JestResult; import io.searchbox.indices.CreateIndex; import io.searchbox.indices.DeleteIndex; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class IndexController { @Autowired private JestClient jestClient; @GetMapping("createIndex") public String createIndex(String indexName) throws Exception{ CreateIndex createIndex = new CreateIndex.Builder(indexName).build(); JestResult result = jestClient.execute(createIndex); return result.getJsonString(); } @GetMapping("deleteIndex") public String deleteIndex(String indexName) throws Exception{ DeleteIndex deleteIndex = new DeleteIndex.Builder(indexName).build(); JestResult result = jestClient.execute(deleteIndex); return result.getJsonString(); } } 

3.3 文檔類操作

文檔相當於MySQL中的行記錄,也就是說一條數據,由於新增和修改在同一個方法內,所以這里也是對新增(和修改)和刪除方法進行介紹,如下:

3.3.1 新增或修改文檔

首先會判斷索引是否存在,不存在的話會根據索引文檔進行創建索引,然后進行新增或修改操作,如果沒有指定id的話(上文說的注解@JestId字段),會自動生成一個id。

Index.Builder builder = new Index.Builder(bookRequest.getBody()); Index index = builder.index(bookRequest.getIndexName()).type(bookRequest.getTypeName()).build(); 

這里使用新增文檔創建三條數據方便后面查詢,如下:

{
    "indexName": "book", "typeName": "book", "body": {"id":"test0001","bookName":"數學書","bookAuthor":"復旦大學","pages":100,"desc":"復旦大學的數學書"} } 
{
    "indexName": "book", "typeName": "book", "body": {"id":"test0003","bookName":"語文書","bookAuthor":"北京大學","pages":100,"desc":"北京大學的語文書"} } 
{
    "indexName": "book", "typeName": "book", "body": {"id":"test0003","bookName":"英文書","bookAuthor":"清華大學","pages":200,"desc":"清華大學的英文書"} } 

3.3.2 刪除文檔(根據id)

Delete index = new Delete.Builder(bookRequest.getId()).index(bookRequest.getIndexName()).type(bookRequest.getTypeName()).build(); 

完整示例內容如下:

package com.dalaoyang.web; import com.dalaoyang.model.BookRequest; import io.searchbox.client.JestClient; import io.searchbox.client.JestResult; import io.searchbox.core.Delete; import io.searchbox.core.Index; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController public class DocumentController { @Autowired private JestClient jestClient; @PostMapping("saveOrUpdateDocument") public String saveOrUpdateDocument(@RequestBody BookRequest bookRequest) throws Exception{ Index.Builder builder = new Index.Builder(bookRequest.getBody()); Index index = builder.index(bookRequest.getIndexName()).type(bookRequest.getTypeName()).build(); JestResult result = jestClient.execute(index); return result.getJsonString(); } @PostMapping("deleteDocumentById") public String deleteDocumentById(@RequestBody BookRequest bookRequest) throws Exception{ Delete index = new Delete.Builder(bookRequest.getId()).index(bookRequest.getIndexName()).type(bookRequest.getTypeName()).build(); JestResult result = jestClient.execute(index); return result.getJsonString(); } } 

3.4 查詢操作

查詢操作可能是對Elasticsearch最需要使用的場景,這里舉一個簡單的場景,輸入關鍵字,查詢對應book文檔,關鍵字匹配(bookName,bookAuthor,desc)三個字段,這里結合Elasticsearch官方依賴進行操作,完整示例如下:


package com.dalaoyang.web;

import com.dalaoyang.model.BookRequest; import io.searchbox.client.JestClient; import io.searchbox.core.Search; import io.searchbox.core.SearchResult; import lombok.extern.slf4j.Slf4j; import org.elasticsearch.index.query.MultiMatchQueryBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController @Slf4j public class QueryController { @Autowired private JestClient jestClient; @PostMapping("search") public String search(@RequestBody BookRequest bookRequest) throws Exception{ SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(new MultiMatchQueryBuilder(bookRequest.getKeyword(), "bookName","bookAuthor","desc")); log.info(searchSourceBuilder.toString()); SearchResult result = jestClient.execute(new Search.Builder(searchSourceBuilder.toString()) .addIndex(bookRequest.getIndexName()) .addType(bookRequest.getTypeName()) .build()); return result.getJsonString(); } } 

比如這里搜索清華,這里我打印了一下查詢語句,如下:

{
    "query":{ "multi_match":{ "query":"清華", "fields":[ "bookAuthor^1.0", "bookName^1.0", "desc^1.0" ], "type":"best_fields", "operator":"OR", "slop":0, "prefix_length":0, "max_expansions":50, "zero_terms_query":"NONE", "auto_generate_synonyms_phrase_query":true, "fuzzy_transpositions":true, "boost":1 } } } 

查詢的結構只有一條,與在Elasticsearch-Head中查詢一致,如圖

image

4.一些建議

相關操作Elasticsearch的客戶端有很多,這里就不做相關對比了,JestClient本人也在真實上線項目中使用過,這里只是在使用過幾種的前提下做出幾點建議:

  • Elastic官方已經開始建議使用HTTP方式去操作Elasticsearch了
  • 當初選擇這種的原因是考慮到更好的去擴展版本,封裝響應的操作類可以兼容更多的版本。
  • 在高版本的Elasticsearch中,有一些文檔類型的內容被單獨抽離出來了,比如父子文檔。

 

參考:https://www.cnblogs.com/dalaoyang/p/12824499.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM