springCloud学习【4】之elasticsearch(1)
生活随笔
收集整理的這篇文章主要介紹了
springCloud学习【4】之elasticsearch(1)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 一 初識elasticsearch
- 1.1 認識ES
- 1.2 基知:倒排索引
- 1.3 正向和倒排總結
- 1.4 es基礎概念
- 二 安裝elasticsearch
- 2.1 部署部署單點es
- 2.1.1 創建網絡
- 2.1.2 下載鏡像
- 2.1.3 加載鏡像
- 2.1.4 運行
- 2.1.5 訪問
- 2.2 部署kibana
- 2.2.1 下載鏡像
- 2.2.2 加載鏡像
- 2.2.3 運行kibana
- 2.2.4 查看日志
- 2.2.5 使用DevTools
- 2.3 安裝IK分詞器
- 2.3.1 在線安裝ik插件(較慢)
- 2.3.2 離線安裝ik插件(推薦)
- 2.4 拓展詞典
- 2.5 停用詞詞典
- 2.6 部署es集群【補充】
- 三 索引庫操作
- 3.1 mapping映射屬性
- 3.2 創建索引庫和映射
- 3.3 查詢索引庫
- 3.4 修改索引庫
- 3.5 刪除索引庫
- 3.6 總結
- 四 文檔操作
- 4.1 新增文檔
- 4.2 查詢文檔
- 4.3 刪除文檔
- 4.4 修改文檔
- 4.5 總結
- 五 RestAPI
- 5.1 分析數據結構:apping映射分析
- 5.2 初始化RestClient
- 5.3 創建索引庫
- 5.4 刪除索引庫
- 5.5 判斷索引庫存在
- 5.6 總結
- 六 RestClient操作文檔
- 6.1 新增文檔
- 6.2 查詢文檔
- 6.3 修改文檔
- 6.4 刪除文檔
- 6.5 批量導入文檔
- 6.6 小結
一 初識elasticsearch
1.1 認識ES
- elasticsearch的作用
- elasticsearch是一款非常強大的開源搜索引擎,具備非常多強大功能,可以幫助我們從海量數據中快速找到需要的內容
- elasticsearch是一款非常強大的開源搜索引擎,具備非常多強大功能,可以幫助我們從海量數據中快速找到需要的內容
- ELK技術棧
- elasticsearch結合kibana、Logstash、Beats,也就是elastic stack(ELK)。被廣泛應用在日志數據分析、實時監控等領域:
- 而elasticsearch是elastic stack的核心,負責存儲、搜索、分析數據。
- elasticsearch和lucene
- elasticsearch底層是基于lucene來實現的。
- Lucene是一個Java語言的搜索引擎類庫,是Apache公司的頂級項目,由DougCutting于1999年研發。
- elasticsearch的發展歷史:
- 2004年Shay Banon基于Lucene開發了Compass
- 2010年Shay Banon 重寫了Compass,取名為Elasticsearch。
1.2 基知:倒排索引
- 倒排索引的概念是基于MySQL這樣的正向索引而言的。
- 正向索引:
- 基于文檔id創建索引。查詢詞條時必須先找到文檔,而后判斷是否包含詞條
- 逐行掃描,也就是全表掃描,隨著數據量增加,其查詢效率也會越來越低。當數據量達到數百萬時,就是一場災難。
- elasticsearch采用倒排索引:
- 文檔(document):用來搜索的數據,每條數據就是一個文檔 例如:一個網頁、一個商品信息
- 詞條(term):對文檔數據或用戶搜索數據,利用某種算法分詞,得到的具備含義的詞語就是詞條。 例如:我是中國人,就可以分為:我、是、中國人、中國、國人這樣的幾個詞條
- 創建倒排索引是對正向索引的一種特殊處理,流程如下:
- 將每一個文檔的數據利用算法分詞,得到一個個詞條
- 創建表,每行數據包括詞條、詞條所在文檔id、位置等信息
- 因為詞條唯一性,可以給詞條創建索引,例如hash表結構索引
- 倒排索引的搜索流程如下(以搜索"華為手機"為例):
- 1)用戶輸入條件"華為手機"進行搜索。
- 2)對用戶輸入內容分詞,得到詞條:華為、手機。
- 3)拿著詞條在倒排索引中查找,可以得到包含詞條的文檔id:1、2、3。
- 4)拿著文檔id到正向索引中查找具體文檔。
- 雖然要先查詢倒排索引,再查詢倒排索引,但是無論是詞條、還是文檔id都建立了索引,查詢速度非???#xff01;無需全表掃描。
- posting list
- 倒排索引中包含兩部分內容:
- 詞條詞典(Term Dictionary):記錄所有詞條,以及詞條與倒排列表(Posting List)之間的關系,會給詞條創建索引,提高查詢和插入效率
- 倒排列表(Posting List):記錄詞條所在的文檔id、詞條出現頻率 、詞條在文檔中的位置等信息
- 文檔id:用于快速獲取文檔
- 詞條頻率(TF):文檔在詞條出現的次數,用于評分
1.3 正向和倒排總結
- 正向索引是最傳統的,根據id索引的方式。但根據詞條查詢時,必須先逐條獲取每個文檔,然后判斷文檔中是否包含所需要的詞條,是根據文檔找詞條的過程。
- 而倒排索引則相反,是先找到用戶要搜索的詞條,根據詞條得到保護詞條的文檔的id,然后根據id獲取文檔。是根據詞條找文檔的過程。
- 正向索引:
- 優點:
- 可以給多個字段創建索引
- 根據索引字段搜索、排序速度非???/li>
- 缺點:
- 根據非索引字段,或者索引字段中的部分詞條查找時,只能全表掃描。
- 優點:
- 倒排索引:
- 優點:
- 根據詞條搜索、模糊搜索時,速度非???/li>
- 缺點:
- 只能給詞條創建索引,而不是字段
- 無法根據字段做排序
- 優點:
1.4 es基礎概念
- 文檔和字段
- elasticsearch是面向文檔(Document) 存儲的,可以是數據庫中的一條商品數據,一個訂單信息。
- 文檔數據會被序列化為json格式后存儲在elasticsearch中,而Json文檔中往往包含很多的字段(Field)
- 索引和映射
- 索引(Index),就是相同類型的文檔的集合。
- 映射(mapping):索引中文檔的字段約束信息,類似表的結構約束
- **mysql與elasticsearch的概念對比:加粗樣式
| Table | Index | 索引(index),就是文檔的集合,類似數據庫的表(table) |
| Row | Document | 文檔(Document),就是一條條的數據,類似數據庫中的行(Row),文檔都是JSON格式 |
| Column | Field | 字段(Field),就是JSON文檔中的字段,類似數據庫中的列(Column) |
| Schema | Mapping | Mapping(映射)是索引中文檔的約束,例如字段類型約束。類似數據庫的表結構(Schema) |
| SQL | DSL | DSL是elasticsearch提供的JSON風格的請求語句,用來操作elasticsearch,實現CRUD |
- 架構
- Mysql:擅長事務類型操作,可以確保數據的安全和一致性
- Elasticsearch:擅長海量數據的搜索、分析、計算
- 因此在企業中,往往是兩者結合使用:
- 對安全性要求較高的寫操作,使用mysql實現
- 對查詢性能要求較高的搜索需求,使用elasticsearch實現
- 兩者再基于某種方式,實現數據的同步,保證一致性
二 安裝elasticsearch
2.1 部署部署單點es
2.1.1 創建網絡
- 因為還需要部署kibana容器,因此需要讓es和kibana容器互聯。先創建一個網絡:docker network create es-net
2.1.2 下載鏡像
- 這里采用elasticsearch的7.12.1版本的鏡像,不建議pull。
- Elasticsearch中文社區下載地址
- 記得將壓縮包的名稱修改為es.tar
2.1.3 加載鏡像
[root@kongyue ~]# systemctl start docker [root@kongyue ~]# cd /tmp/ [root@kongyue tmp]# docker load -i es.tar 2653d992f4ef: Loading layer [==================================================>] 216.5MB/216.5MB 0ba8eff8aa04: Loading layer [==================================================>] 101.4MB/101.4MB 2a944434ad00: Loading layer [==================================================>] 314.9kB/314.9kB ade95a7611c0: Loading layer [==================================================>] 543.9MB/543.9MB 09a575a6e776: Loading layer [==================================================>] 26.62kB/26.62kB 498ae65924d7: Loading layer [==================================================>] 7.68kB/7.68kB 36b3f8db7aaa: Loading layer [==================================================>] 490.5kB/490.5kB Loaded image: elasticsearch:7.12.12.1.4 運行
docker run -d \--name es \-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \-e "discovery.type=single-node" \-v es-data:/usr/share/elasticsearch/data \-v es-plugins:/usr/share/elasticsearch/plugins \--privileged \--network es-net \-p 9200:9200 \-p 9300:9300 \ elasticsearch:7.12.1命令解釋:
- -e "cluster.name=es-docker-cluster":設置集群名稱
- -e "http.host=0.0.0.0":監聽的地址,可以外網訪問
- -e "ES_JAVA_OPTS=-Xms512m -Xmx512m":內存大小
- -e "discovery.type=single-node":非集群模式
- -v es-data:/usr/share/elasticsearch/data:掛載邏輯卷,綁定es的數據目錄
- -v es-logs:/usr/share/elasticsearch/logs:掛載邏輯卷,綁定es的日志目錄
- -v es-plugins:/usr/share/elasticsearch/plugins:掛載邏輯卷,綁定es的插件目錄
- --privileged:授予邏輯卷訪問權
- --network es-net :加入一個名為es-net的網絡中
- -p 9200:9200:端口映射配置
2.1.5 訪問
- 訪問:http://xxx.xxx.xxx.xxx:9200 即可看到elasticsearch的響應結果:
2.2 部署kibana
2.2.1 下載鏡像
- 官方地址Download Kibana
- Elasticsearch中文社區下載地址
- 記得將壓縮包的名稱修改為kibana.tar
2.2.2 加載鏡像
[root@kongyue tmp]# docker load -i kibana.tar d797e87ed4ce: Loading layer [==================================================>] 112.9MB/112.9MB 80ce41fc1f8a: Loading layer [==================================================>] 26.62kB/26.62kB 3345a8ffd0ea: Loading layer [==================================================>] 3.584kB/3.584kB d736a1702974: Loading layer [==================================================>] 20.34MB/20.34MB 570575469db2: Loading layer [==================================================>] 56.83kB/56.83kB 459d502a3562: Loading layer [==================================================>] 770.7MB/770.7MB f22a9f0649d0: Loading layer [==================================================>] 2.048kB/2.048kB 4b66f24ba0de: Loading layer [==================================================>] 4.096kB/4.096kB 0a50faa06266: Loading layer [==================================================>] 15.36kB/15.36kB 8a310ff91413: Loading layer [==================================================>] 4.096kB/4.096kB 5997553ddc84: Loading layer [==================================================>] 479.2kB/479.2kB f87dadd7c340: Loading layer [==================================================>] 309.8kB/309.8kB Loaded image: kibana:7.12.12.2.3 運行kibana
- kibana啟動一般比較慢,需要多等待一會
- --network es-net :加入一個名為es-net的網絡中,與elasticsearch在同一個網絡中
- -e ELASTICSEARCH_HOSTS=http://es:9200":設置elasticsearch的地址,因為kibana已經與elasticsearch在一個網絡,因此可以用容器名直接訪問elasticsearch
- -p 5601:5601:端口映射配置
2.2.4 查看日志
- 可以通過命令,查看運行日志:docker logs -f kibana
- 當查看到下面的日志,說明成功:{"type":"log","@timestamp":"2023-03-24T05:05:05+00:00","tags":["info","http","server","Kibana"],"pid":7,"message":"http server running at http://0.0.0.0:5601"}
2.2.5 使用DevTools
- 訪問http://xxx.xxx.xxx.xxx:5601,即可看到以下頁面,選擇Explore on my own
- 選擇開發工具
- 然后進入以下界面
- 界面中可以編寫DSL來操作elasticsearch。并且對DSL語句有自動補全功能。
2.3 安裝IK分詞器
2.3.1 在線安裝ik插件(較慢)
# 進入容器內部 docker exec -it elasticsearch /bin/bash# 在線下載并安裝 ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip#退出 exit #重啟容器 docker restart elasticsearch2.3.2 離線安裝ik插件(推薦)
- 安裝插件需要知道elasticsearch的plugins目錄位置,而我們用了數據卷掛載,因此需要查看elasticsearch的數據卷目錄
- 通過下面命令查看:docker volume inspect es-plugins
- 顯示結果:[root@kongyue tmp]# docker volume inspect es-plugins
[{"CreatedAt": "2023-03-24T12:51:40+08:00","Driver": "local","Labels": null,"Mountpoint": "/var/lib/docker/volumes/es-plugins/_data","Name": "es-plugins","Options": null,"Scope": "local"}
]
- 說明plugins目錄被掛載到了:/var/lib/docker/volumes/es-plugins/_data 這個目錄中。
- Elasticsearch中文社區下載地址
- 把ik分詞器解壓縮,重命名為ik
- 將ik文件夾上傳到查詢出來的掛載目錄
- IK分詞器包含兩種模式:
- ik_smart:最少切分
- ik_max_word:最細切分
2.4 拓展詞典
- 隨著互聯網的發展,出現了很多新的詞語,在原有的詞匯列表中并不存在。所以我們的詞匯也需要不斷的更新,IK分詞器提供了擴展詞匯的功能。
- 注意當前文件的編碼必須是 UTF-8 格式
2.5 停用詞詞典
- 在互聯網項目中,在網絡間傳輸的速度很快,所以很多語言是不允許在網絡上傳遞的,如:關于宗教、政治等敏感詞語,那么我們在搜索時也應該忽略當前詞匯。
- IK分詞器也提供了強大的停用詞功能,讓我們在索引時就直接忽略當前的停用詞匯表中的內容。
- 注意當前文件的編碼必須是 UTF-8 格式
2.6 部署es集群【補充】
- 部署es集群可以直接使用docker-compose來完成,不過要求你的Linux虛擬機至少有4G的內存空間
三 索引庫操作
- 索引庫就類似數據庫表,mapping映射就類似表的結構。要向es中存儲數據,必須先創建“庫”和“表”。
- 使用統一使用Kibana編寫DSL的方式來演示
3.1 mapping映射屬性
- type:字段數據類型,常見的簡單類型有:
- 字符串:text(可分詞的文本)、keyword(精確值,例如:品牌、國家、ip地址)
- 數值:long、integer、short、byte、double、float、
- 布爾:boolean
- 日期:date
- 對象:object
- index:是否創建索引,默認為true
- analyzer:使用哪種分詞器
- properties:該字段的子字段
- 舉例:{"age": 21,"weight": 52.1,"isMarried": false,"info": "武神","email": "zy@itcast.cn","score": [99.1, 99.5, 98.9],"name": {"firstName": "云","lastName": "趙"} }
- 對應的每個字段映射(mapping):
- age:類型為 integer;參與搜索,因此需要index為true;無需分詞器
- weight:類型為float;參與搜索,因此需要index為true;無需分詞器
- isMarried:類型為boolean;參與搜索,因此需要index為true;無需分詞器
- info:類型為字符串,需要分詞,因此是text;參與搜索,因此需要index為true;分詞器可以用ik_smart
- email:類型為字符串,但是不需要分詞,因此是keyword;不參與搜索,因此需要index為false;無需分詞器
- score:雖然是數組,但是我們只看元素的類型,類型為float;參與搜索,因此需要index為true;無需分詞器
- name:類型為object,需要定義多個子屬性
- name.firstName;類型為字符串,但是不需要分詞,因此是keyword;參與搜索,因此需要index為true;無需分詞器
- name.lastName;類型為字符串,但是不需要分詞,因此是keyword;參與搜索,因此需要index為true;無需分詞器
3.2 創建索引庫和映射
- 基本語法:
- 請求方式:PUT
- 請求路徑:/索引庫名,可以自定義
- 請求參數:mapping映射
- 格式:PUT /索引庫名稱 {"mappings": {"properties": {"字段名":{"type": "text","analyzer": "ik_smart"},"字段名2":{"type": "keyword","index": "false"},"字段名3":{"properties": {"子字段": {"type": "keyword"}}}}} }
- 舉例:PUT /test01 {"mappings": {"properties": {"info":{"type": "text","analyzer": "ik_smart"},"email":{"type": "keyword","index": "false"},"name":{"properties": {"firstName": {"type": "keyword"}}}}} }
- 演示結果:{"acknowledged" : true,"shards_acknowledged" : true,"index" : "test01" }
3.3 查詢索引庫
-
基本語法:
- 請求方式:GET
- 請求路徑:/索引庫名
- 請求參數:無
-
格式:
GET /索引庫名 -
演示:
3.4 修改索引庫
- 倒排索引結構雖然不復雜,但是一旦數據結構改變(比如改變了分詞器),就需要重新創建倒排索引,這簡直是災難。因此索引庫一旦創建,無法修改mapping。
- 雖然無法修改mapping中已有的字段,但是卻允許添加新的字段到mapping中,因為不會對倒排索引產生影響。
- 語法說明:PUT /索引庫名/_mapping {"properties": {"新字段名":{"type": "integer"}} }
- 演示:
3.5 刪除索引庫
- 語法:
- 請求方式:DELETE
- 請求路徑:/索引庫名
- 請求參數:無
- 格式:DELETE /索引庫名
3.6 總結
- 索引庫操作:
- 創建索引庫:PUT /索引庫名
- 查詢索引庫:GET /索引庫名
- 刪除索引庫:DELETE /索引庫名
- 添加字段:PUT /索引庫名/_mapping
四 文檔操作
4.1 新增文檔
- 語法:POST /索引庫名/_doc/文檔id {"字段1": "值1","字段2": "值2","字段3": {"子屬性1": "值3","子屬性2": "值4"},// ... }
- 演示:
4.2 查詢文檔
- 語法:GET /{索引庫名稱}/_doc/{id}
- 通過kibana查看數據:GET /heima/_doc/1
- 演示:
4.3 刪除文檔
- 語法:DELETE /{索引庫名}/_doc/id值
- 演示:
4.4 修改文檔
- 修改有兩種方式:
- 全量修改:直接覆蓋原來的文檔
- 增量修改:修改文檔中的部分字段
- 全量修改
- 全量修改是覆蓋原來的文檔,其本質是:
- 根據指定的id刪除文檔
- 新增一個相同id的文檔
- 注意:如果根據id刪除時,id不存在,第二步的新增也會執行,也就從修改變成了新增操作了。
- 語法:PUT /{索引庫名}/_doc/文檔id {"字段1": "值1","字段2": "值2",// ... 略 }
- 演示:
- 增量修改
- 增量修改是只修改指定id匹配的文檔中的部分字段。
- 語法:POST /{索引庫名}/_update/文檔id {"doc": {"字段名": "新的值"} }
- 演示:
4.5 總結
- 文檔操作:
- 創建文檔:POST /{索引庫名}/_doc/文檔id { json文檔 }
- 查詢文檔:GET /{索引庫名}/_doc/文檔id
- 刪除文檔:DELETE /{索引庫名}/_doc/文檔id
- 修改文檔:
- 全量修改:PUT /{索引庫名}/_doc/文檔id { json文檔 }
- 增量修改:POST /{索引庫名}/_update/文檔id { "doc": {字段}}
五 RestAPI
- ES官方提供了各種不同語言的客戶端,用來操作ES。這些客戶端的本質就是組裝DSL語句,通過http請求發送給ES。官方文檔地址
- 其中的Java Rest Client又包括兩種:
- Java Low Level Rest Client
- Java High Level Rest Client
- 這里使用Java HighLevel Rest Client客戶端API
5.1 分析數據結構:apping映射分析
- 創建索引庫,最關鍵的是mapping映射,而mapping映射要考慮的信息包括:
- 字段名
- 字段數據類型
- 是否參與搜索
- 是否需要分詞
- 如果分詞,分詞器是什么?
- 其中:
- 字段名、字段數據類型,可以參考數據表結構的名稱和類型
- 是否參與搜索要分析業務來判斷,例如圖片地址,就無需參與搜索
- 是否分詞呢要看內容,內容如果是一個整體就無需分詞,反之則要分詞
- 分詞器,我們可以統一使用ik_max_word
- 幾個特殊字段說明:
- location:地理坐標,里面包含精度、緯度
- all:一個組合字段,其目的是將多字段的值 利用copy_to合并,提供給用戶搜索
- 地理坐標說明:
- copy_to說明:
5.2 初始化RestClient
- 在elasticsearch提供的API中,與elasticsearch一切交互都封裝在一個名為RestHighLevelClient的類中,必須先完成這個對象的初始化,建立與elasticsearch的連接。
- 步驟分為三步:
- 引入es的RestHighLevelClient依賴: <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>
- 因為SpringBoot默認的ES版本是7.6.2,所以我們需要覆蓋默認的ES版本: <properties><java.version>1.8</java.version><elasticsearch.version>7.12.1</elasticsearch.version> </properties>
- 初始化RestHighLevelClient: RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.150.101:9200") ));
- 測試,創建一個測試類HotelIndexTest,然后將初始化的代碼編寫在@BeforeEach方法中: public class HotelIndexTest {private RestHighLevelClient client;@BeforeEachvoid setUp() {this.client = new RestHighLevelClient(RestClient.builder(//xxx.xxx.xxx.xxx 虛擬主機的IPHttpHost.create("http://xxx.xxx.xxx.xxx:9200")));}@AfterEachvoid tearDown() throws IOException {this.client.close();} }
5.3 創建索引庫
- 代碼分為三步:
- 創建Request對象。因為是創建索引庫的操作,因此Request是CreateIndexRequest。
- 添加請求參數,其實就是DSL的JSON參數部分。因為json字符串很長,這里是定義了靜態字符串常量MAPPING_TEMPLATE,讓代碼看起來更加優雅。
- 發送請求,client.indices()方法的返回值是IndicesClient類型,封裝了所有與索引庫操作有關的方法。
- 演示
5.4 刪除索引庫
- 刪除索引庫的DSL語句非常簡單:DELETE /hotel
- 與創建索引庫相比:
- 請求方式從PUT變為DELTE
- 請求路徑不變
- 無請求參數
- 所以代碼的差異,注意體現在Request對象上。依然是三步走:
- 創建Request對象。這次是DeleteIndexRequest對象
- 準備參數。這里是無參
- 發送請求。改用delete方法
- 編寫單元測試,實現刪除索引:@Test void testDeleteHotelIndex() throws IOException {// 1.創建Request對象DeleteIndexRequest request = new DeleteIndexRequest("hotel");// 2.發送請求client.indices().delete(request, RequestOptions.DEFAULT); }
5.5 判斷索引庫存在
- 判斷索引庫是否存在,本質就是查詢,對應的DSL是:GET /hotel
- 因此與刪除的Java代碼流程是類似的。依然是三步走:
- 創建Request對象。這次是GetIndexRequest對象
- 準備參數。這里是無參
- 發送請求。改用exists方法 @Test void testExistsHotelIndex() throws IOException {// 1.創建Request對象GetIndexRequest request = new GetIndexRequest("hotel");// 2.發送請求boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);// 3.輸出System.err.println(exists ? "索引庫已經存在!" : "索引庫不存在!"); }
5.6 總結
- JavaRestClient操作elasticsearch的流程基本類似。核心是client.indices()方法來獲取索引庫的操作對象。
- 索引庫操作的基本步驟:
- 初始化RestHighLevelClient
- 創建XxxIndexRequest。XXX是Create、Get、Delete
- 準備DSL( Create時需要,其它是無參)
- 發送請求。調用RestHighLevelClient#indices().xxx()方法,xxx是create、exists、delete
六 RestClient操作文檔
- 為了與索引庫操作分離,需要增加加一個測試類:
- 初始化RestHighLevelClient
- 酒店數據在數據庫,需要利用IHotelService去查詢,所以注入這個接口
6.1 新增文檔
- 數據庫實體類->索引庫實體類
- 導入酒店數據,基本流程一致,但是需要考慮幾點變化:
- 酒店數據來自于數據庫,需要先查詢出來,得到hotel對象
- hotel對象需要轉為HotelDoc對象
- HotelDoc需要序列化為json格式
- 因此,代碼整體步驟如下:
- 根據id查詢酒店數據Hotel
- 將Hotel封裝為HotelDoc
- 將HotelDoc序列化為JSON
- 創建IndexRequest,指定索引庫名和id
- 準備請求參數,也就是JSON文檔
- 發送請求 @Test void testAddDocument() throws IOException {// 1.根據id查詢酒店數據Hotel hotel = hotelService.getById(61083L);// 2.轉換為文檔類型HotelDoc hotelDoc = new HotelDoc(hotel);// 3.將HotelDoc轉jsonString json = JSON.toJSONString(hotelDoc);// 1.準備Request對象IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());// 2.準備Json文檔request.source(json, XContentType.JSON);// 3.發送請求client.index(request, RequestOptions.DEFAULT); }
- 測試運行結果:
6.2 查詢文檔
- 詢的目的是得到結果,解析為HotelDoc,因此難點是結果的解析
- 結果是一個JSON,其中文檔放在一個_source屬性中,因此解析就是拿到_source,反序列化為Java對象即可
- 三步走:
- 準備Request對象。這次是查詢,所以是GetRequest
- 發送請求,得到結果。因為是查詢,這里調用client.get()方法
- 解析結果,就是對JSON做反序列化
- 編寫單元測試:@Test void testGetDocumentById() throws IOException {// 1.準備RequestGetRequest request = new GetRequest("hotel", "61082");// 2.發送請求,得到響應GetResponse response = client.get(request, RequestOptions.DEFAULT);// 3.解析響應結果String json = response.getSourceAsString();HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println(hotelDoc); }
6.3 修改文檔
-
在RestClient的API中,全量修改與新增的API完全一致,判斷依據是ID:
- 如果新增時,ID已經存在,則修改
- 如果新增時,ID不存在,則新增
-
Upsert:如果文檔尚不存在,則可以使用以下upsert方法定義一些內容,這些內容將作為新文檔插入
String jsonString = "{\"created\":\"2017-01-01\"}"; request.upsert(jsonString, XContentType.JSON); -
全量修改:
@Testvoid testUpdateDocument() throws IOException {// 1.準備RequestUpdateRequest request = new UpdateRequest("hotel", "61083");// 2.準備請求參數UpdateRequest doc = request.doc("price", "952","starName", "四鉆");request.upsert(doc, XContentType.JSON);// 3.發送請求client.update(request, RequestOptions.DEFAULT);}
- 增量修改/*** 增量修改* @throws IOException*/ @Test void testUpdateDocument2() throws IOException {// 1.準備RequestUpdateRequest request = new UpdateRequest("hotel", "61083");// 2.準備請求參數UpdateRequest doc = request.doc("price", "888","starName", "八鉆");// 3.發送請求client.update(request, RequestOptions.DEFAULT); }
6.4 刪除文檔
- 三步走:
- 準備Request對象,因為是刪除,這次是DeleteRequest對象。要指定索引庫名和id
- 準備參數,無參
- 發送請求。因為是刪除,所以是client.delete()方法 @Test void testDeleteDocument() throws IOException {// 1.準備RequestDeleteRequest request = new DeleteRequest("hotel", "61083");// 2.發送請求client.delete(request, RequestOptions.DEFAULT); }
6.5 批量導入文檔
-
需求:利用BulkRequest批量將數據庫數據導入到索引庫中
-
步驟如下:
- 利用mybatis-plus查詢酒店數據
- 將查詢到的酒店數據(Hotel)轉換為文檔類型數據(HotelDoc)
- 利用JavaRestClient中的BulkRequest批處理,實現批量新增文檔
-
批量處理BulkRequest,其本質就是將多個普通的CRUD請求組合在一起發送。
- 其中提供了一個add方法,用來添加其他請求:
- 其中提供了一個add方法,用來添加其他請求:
-
能添加的請求包括:
- IndexRequest:新增
- UpdateRequest:修改
- DeleteRequest:刪除
-
Bulk中添加了多個IndexRequest——批量新增功能
-
編寫單元測試
@Test void testBulkRequest() throws IOException {// 批量查詢酒店數據List<Hotel> hotels = hotelService.list();// 1.創建RequestBulkRequest request = new BulkRequest();// 2.準備參數,添加多個新增的Requestfor (Hotel hotel : hotels) {// 2.1.轉換為文檔類型HotelDocHotelDoc hotelDoc = new HotelDoc(hotel);// 2.2.創建新增文檔的Request對象request.add(new IndexRequest("hotel").id(hotelDoc.getId().toString()).source(JSON.toJSONString(hotelDoc), XContentType.JSON));}// 3.發送請求client.bulk(request, RequestOptions.DEFAULT); } -
測試運行結果:
- 查詢數據庫的數據量
- 查詢索引庫的文檔數量
6.6 小結
- 文檔操作的基本步驟:
- 初始化RestHighLevelClient
- 創建XxxRequest。XXX:Index、Get、Update、Delete、Bulk
- 準備參數(Index、Update、Bulk時需要)
- 發送請求。調用RestHighLevelClient#.xxx()方法,xxx:index、get、update、delete、bulk
- 解析結果(Get時需要)
總結
以上是生活随笔為你收集整理的springCloud学习【4】之elasticsearch(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [SSD核心技术:FTL 13] 不求同
- 下一篇: 跨平台flutter- window与A