springCloud学习【4】之elasticsearch(1)
生活随笔
收集整理的這篇文章主要介紹了
springCloud学习【4】之elasticsearch(1)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
文章目錄
- 一 初識(shí)elasticsearch
- 1.1 認(rèn)識(shí)ES
- 1.2 基知:倒排索引
- 1.3 正向和倒排總結(jié)
- 1.4 es基礎(chǔ)概念
- 二 安裝elasticsearch
- 2.1 部署部署單點(diǎn)es
- 2.1.1 創(chuàng)建網(wǎng)絡(luò)
- 2.1.2 下載鏡像
- 2.1.3 加載鏡像
- 2.1.4 運(yùn)行
- 2.1.5 訪問
- 2.2 部署kibana
- 2.2.1 下載鏡像
- 2.2.2 加載鏡像
- 2.2.3 運(yùn)行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集群【補(bǔ)充】
- 三 索引庫操作
- 3.1 mapping映射屬性
- 3.2 創(chuàng)建索引庫和映射
- 3.3 查詢索引庫
- 3.4 修改索引庫
- 3.5 刪除索引庫
- 3.6 總結(jié)
- 四 文檔操作
- 4.1 新增文檔
- 4.2 查詢文檔
- 4.3 刪除文檔
- 4.4 修改文檔
- 4.5 總結(jié)
- 五 RestAPI
- 5.1 分析數(shù)據(jù)結(jié)構(gòu):apping映射分析
- 5.2 初始化RestClient
- 5.3 創(chuàng)建索引庫
- 5.4 刪除索引庫
- 5.5 判斷索引庫存在
- 5.6 總結(jié)
- 六 RestClient操作文檔
- 6.1 新增文檔
- 6.2 查詢文檔
- 6.3 修改文檔
- 6.4 刪除文檔
- 6.5 批量導(dǎo)入文檔
- 6.6 小結(jié)
一 初識(shí)elasticsearch
1.1 認(rèn)識(shí)ES
- elasticsearch的作用
- elasticsearch是一款非常強(qiáng)大的開源搜索引擎,具備非常多強(qiáng)大功能,可以幫助我們從海量數(shù)據(jù)中快速找到需要的內(nèi)容
- elasticsearch是一款非常強(qiáng)大的開源搜索引擎,具備非常多強(qiáng)大功能,可以幫助我們從海量數(shù)據(jù)中快速找到需要的內(nèi)容
- ELK技術(shù)棧
- elasticsearch結(jié)合kibana、Logstash、Beats,也就是elastic stack(ELK)。被廣泛應(yīng)用在日志數(shù)據(jù)分析、實(shí)時(shí)監(jiān)控等領(lǐng)域:
- 而elasticsearch是elastic stack的核心,負(fù)責(zé)存儲(chǔ)、搜索、分析數(shù)據(jù)。
- elasticsearch和lucene
- elasticsearch底層是基于lucene來實(shí)現(xiàn)的。
- Lucene是一個(gè)Java語言的搜索引擎類庫,是Apache公司的頂級(jí)項(xiàng)目,由DougCutting于1999年研發(fā)。
- elasticsearch的發(fā)展歷史:
- 2004年Shay Banon基于Lucene開發(fā)了Compass
- 2010年Shay Banon 重寫了Compass,取名為Elasticsearch。
1.2 基知:倒排索引
- 倒排索引的概念是基于MySQL這樣的正向索引而言的。
- 正向索引:
- 基于文檔id創(chuàng)建索引。查詢詞條時(shí)必須先找到文檔,而后判斷是否包含詞條
- 逐行掃描,也就是全表掃描,隨著數(shù)據(jù)量增加,其查詢效率也會(huì)越來越低。當(dāng)數(shù)據(jù)量達(dá)到數(shù)百萬時(shí),就是一場災(zāi)難。
- elasticsearch采用倒排索引:
- 文檔(document):用來搜索的數(shù)據(jù),每條數(shù)據(jù)就是一個(gè)文檔 例如:一個(gè)網(wǎng)頁、一個(gè)商品信息
- 詞條(term):對(duì)文檔數(shù)據(jù)或用戶搜索數(shù)據(jù),利用某種算法分詞,得到的具備含義的詞語就是詞條。 例如:我是中國人,就可以分為:我、是、中國人、中國、國人這樣的幾個(gè)詞條
- 創(chuàng)建倒排索引是對(duì)正向索引的一種特殊處理,流程如下:
- 將每一個(gè)文檔的數(shù)據(jù)利用算法分詞,得到一個(gè)個(gè)詞條
- 創(chuàng)建表,每行數(shù)據(jù)包括詞條、詞條所在文檔id、位置等信息
- 因?yàn)樵~條唯一性,可以給詞條創(chuàng)建索引,例如hash表結(jié)構(gòu)索引
- 倒排索引的搜索流程如下(以搜索"華為手機(jī)"為例):
- 1)用戶輸入條件"華為手機(jī)"進(jìn)行搜索。
- 2)對(duì)用戶輸入內(nèi)容分詞,得到詞條:華為、手機(jī)。
- 3)拿著詞條在倒排索引中查找,可以得到包含詞條的文檔id:1、2、3。
- 4)拿著文檔id到正向索引中查找具體文檔。
- 雖然要先查詢倒排索引,再查詢倒排索引,但是無論是詞條、還是文檔id都建立了索引,查詢速度非???#xff01;無需全表掃描。
- posting list
- 倒排索引中包含兩部分內(nèi)容:
- 詞條詞典(Term Dictionary):記錄所有詞條,以及詞條與倒排列表(Posting List)之間的關(guān)系,會(huì)給詞條創(chuàng)建索引,提高查詢和插入效率
- 倒排列表(Posting List):記錄詞條所在的文檔id、詞條出現(xiàn)頻率 、詞條在文檔中的位置等信息
- 文檔id:用于快速獲取文檔
- 詞條頻率(TF):文檔在詞條出現(xiàn)的次數(shù),用于評(píng)分
1.3 正向和倒排總結(jié)
- 正向索引是最傳統(tǒng)的,根據(jù)id索引的方式。但根據(jù)詞條查詢時(shí),必須先逐條獲取每個(gè)文檔,然后判斷文檔中是否包含所需要的詞條,是根據(jù)文檔找詞條的過程。
- 而倒排索引則相反,是先找到用戶要搜索的詞條,根據(jù)詞條得到保護(hù)詞條的文檔的id,然后根據(jù)id獲取文檔。是根據(jù)詞條找文檔的過程。
- 正向索引:
- 優(yōu)點(diǎn):
- 可以給多個(gè)字段創(chuàng)建索引
- 根據(jù)索引字段搜索、排序速度非常快
- 缺點(diǎn):
- 根據(jù)非索引字段,或者索引字段中的部分詞條查找時(shí),只能全表掃描。
- 優(yōu)點(diǎn):
- 倒排索引:
- 優(yōu)點(diǎn):
- 根據(jù)詞條搜索、模糊搜索時(shí),速度非???/li>
- 缺點(diǎn):
- 只能給詞條創(chuàng)建索引,而不是字段
- 無法根據(jù)字段做排序
- 優(yōu)點(diǎn):
1.4 es基礎(chǔ)概念
- 文檔和字段
- elasticsearch是面向文檔(Document) 存儲(chǔ)的,可以是數(shù)據(jù)庫中的一條商品數(shù)據(jù),一個(gè)訂單信息。
- 文檔數(shù)據(jù)會(huì)被序列化為json格式后存儲(chǔ)在elasticsearch中,而Json文檔中往往包含很多的字段(Field)
- 索引和映射
- 索引(Index),就是相同類型的文檔的集合。
- 映射(mapping):索引中文檔的字段約束信息,類似表的結(jié)構(gòu)約束
- **mysql與elasticsearch的概念對(duì)比:加粗樣式
| Table | Index | 索引(index),就是文檔的集合,類似數(shù)據(jù)庫的表(table) |
| Row | Document | 文檔(Document),就是一條條的數(shù)據(jù),類似數(shù)據(jù)庫中的行(Row),文檔都是JSON格式 |
| Column | Field | 字段(Field),就是JSON文檔中的字段,類似數(shù)據(jù)庫中的列(Column) |
| Schema | Mapping | Mapping(映射)是索引中文檔的約束,例如字段類型約束。類似數(shù)據(jù)庫的表結(jié)構(gòu)(Schema) |
| SQL | DSL | DSL是elasticsearch提供的JSON風(fēng)格的請(qǐng)求語句,用來操作elasticsearch,實(shí)現(xiàn)CRUD |
- 架構(gòu)
- Mysql:擅長事務(wù)類型操作,可以確保數(shù)據(jù)的安全和一致性
- Elasticsearch:擅長海量數(shù)據(jù)的搜索、分析、計(jì)算
- 因此在企業(yè)中,往往是兩者結(jié)合使用:
- 對(duì)安全性要求較高的寫操作,使用mysql實(shí)現(xiàn)
- 對(duì)查詢性能要求較高的搜索需求,使用elasticsearch實(shí)現(xiàn)
- 兩者再基于某種方式,實(shí)現(xiàn)數(shù)據(jù)的同步,保證一致性
二 安裝elasticsearch
2.1 部署部署單點(diǎn)es
2.1.1 創(chuàng)建網(wǎng)絡(luò)
- 因?yàn)檫€需要部署kibana容器,因此需要讓es和kibana容器互聯(lián)。先創(chuàng)建一個(gè)網(wǎng)絡(luò):docker network create es-net
2.1.2 下載鏡像
- 這里采用elasticsearch的7.12.1版本的鏡像,不建議pull。
- Elasticsearch中文社區(qū)下載地址
- 記得將壓縮包的名稱修改為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 運(yùn)行
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":設(shè)置集群名稱
- -e "http.host=0.0.0.0":監(jiān)聽的地址,可以外網(wǎng)訪問
- -e "ES_JAVA_OPTS=-Xms512m -Xmx512m":內(nèi)存大小
- -e "discovery.type=single-node":非集群模式
- -v es-data:/usr/share/elasticsearch/data:掛載邏輯卷,綁定es的數(shù)據(jù)目錄
- -v es-logs:/usr/share/elasticsearch/logs:掛載邏輯卷,綁定es的日志目錄
- -v es-plugins:/usr/share/elasticsearch/plugins:掛載邏輯卷,綁定es的插件目錄
- --privileged:授予邏輯卷訪問權(quán)
- --network es-net :加入一個(gè)名為es-net的網(wǎng)絡(luò)中
- -p 9200:9200:端口映射配置
2.1.5 訪問
- 訪問:http://xxx.xxx.xxx.xxx:9200 即可看到elasticsearch的響應(yīng)結(jié)果:
2.2 部署kibana
2.2.1 下載鏡像
- 官方地址Download Kibana
- Elasticsearch中文社區(qū)下載地址
- 記得將壓縮包的名稱修改為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 運(yùn)行kibana
- kibana啟動(dòng)一般比較慢,需要多等待一會(huì)
- --network es-net :加入一個(gè)名為es-net的網(wǎng)絡(luò)中,與elasticsearch在同一個(gè)網(wǎng)絡(luò)中
- -e ELASTICSEARCH_HOSTS=http://es:9200":設(shè)置elasticsearch的地址,因?yàn)閗ibana已經(jīng)與elasticsearch在一個(gè)網(wǎng)絡(luò),因此可以用容器名直接訪問elasticsearch
- -p 5601:5601:端口映射配置
2.2.4 查看日志
- 可以通過命令,查看運(yùn)行日志:docker logs -f kibana
- 當(dāng)查看到下面的日志,說明成功:{"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
- 選擇開發(fā)工具
- 然后進(jìn)入以下界面
- 界面中可以編寫DSL來操作elasticsearch。并且對(duì)DSL語句有自動(dòng)補(bǔ)全功能。
2.3 安裝IK分詞器
2.3.1 在線安裝ik插件(較慢)
# 進(jìn)入容器內(nèi)部 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目錄位置,而我們用了數(shù)據(jù)卷掛載,因此需要查看elasticsearch的數(shù)據(jù)卷目錄
- 通過下面命令查看:docker volume inspect es-plugins
- 顯示結(jié)果:[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 這個(gè)目錄中。
- Elasticsearch中文社區(qū)下載地址
- 把ik分詞器解壓縮,重命名為ik
- 將ik文件夾上傳到查詢出來的掛載目錄
- IK分詞器包含兩種模式:
- ik_smart:最少切分
- ik_max_word:最細(xì)切分
2.4 拓展詞典
- 隨著互聯(lián)網(wǎng)的發(fā)展,出現(xiàn)了很多新的詞語,在原有的詞匯列表中并不存在。所以我們的詞匯也需要不斷的更新,IK分詞器提供了擴(kuò)展詞匯的功能。
- 注意當(dāng)前文件的編碼必須是 UTF-8 格式
2.5 停用詞詞典
- 在互聯(lián)網(wǎng)項(xiàng)目中,在網(wǎng)絡(luò)間傳輸?shù)乃俣群芸?#xff0c;所以很多語言是不允許在網(wǎng)絡(luò)上傳遞的,如:關(guān)于宗教、政治等敏感詞語,那么我們在搜索時(shí)也應(yīng)該忽略當(dāng)前詞匯。
- IK分詞器也提供了強(qiáng)大的停用詞功能,讓我們在索引時(shí)就直接忽略當(dāng)前的停用詞匯表中的內(nèi)容。
- 注意當(dāng)前文件的編碼必須是 UTF-8 格式
2.6 部署es集群【補(bǔ)充】
- 部署es集群可以直接使用docker-compose來完成,不過要求你的Linux虛擬機(jī)至少有4G的內(nèi)存空間
三 索引庫操作
- 索引庫就類似數(shù)據(jù)庫表,mapping映射就類似表的結(jié)構(gòu)。要向es中存儲(chǔ)數(shù)據(jù),必須先創(chuàng)建“庫”和“表”。
- 使用統(tǒng)一使用Kibana編寫DSL的方式來演示
3.1 mapping映射屬性
- type:字段數(shù)據(jù)類型,常見的簡單類型有:
- 字符串:text(可分詞的文本)、keyword(精確值,例如:品牌、國家、ip地址)
- 數(shù)值:long、integer、short、byte、double、float、
- 布爾:boolean
- 日期:date
- 對(duì)象:object
- index:是否創(chuàng)建索引,默認(rèn)為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": "趙"} }
- 對(duì)應(yīng)的每個(gè)字段映射(mapping):
- age:類型為 integer;參與搜索,因此需要index為true;無需分詞器
- weight:類型為float;參與搜索,因此需要index為true;無需分詞器
- isMarried:類型為boolean;參與搜索,因此需要index為true;無需分詞器
- info:類型為字符串,需要分詞,因此是text;參與搜索,因此需要index為true;分詞器可以用ik_smart
- email:類型為字符串,但是不需要分詞,因此是keyword;不參與搜索,因此需要index為false;無需分詞器
- score:雖然是數(shù)組,但是我們只看元素的類型,類型為float;參與搜索,因此需要index為true;無需分詞器
- name:類型為object,需要定義多個(gè)子屬性
- name.firstName;類型為字符串,但是不需要分詞,因此是keyword;參與搜索,因此需要index為true;無需分詞器
- name.lastName;類型為字符串,但是不需要分詞,因此是keyword;參與搜索,因此需要index為true;無需分詞器
3.2 創(chuàng)建索引庫和映射
- 基本語法:
- 請(qǐng)求方式:PUT
- 請(qǐng)求路徑:/索引庫名,可以自定義
- 請(qǐng)求參數(shù):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"}}}}} }
- 演示結(jié)果:{"acknowledged" : true,"shards_acknowledged" : true,"index" : "test01" }
3.3 查詢索引庫
-
基本語法:
- 請(qǐng)求方式:GET
- 請(qǐng)求路徑:/索引庫名
- 請(qǐng)求參數(shù):無
-
格式:
GET /索引庫名 -
演示:
3.4 修改索引庫
- 倒排索引結(jié)構(gòu)雖然不復(fù)雜,但是一旦數(shù)據(jù)結(jié)構(gòu)改變(比如改變了分詞器),就需要重新創(chuàng)建倒排索引,這簡直是災(zāi)難。因此索引庫一旦創(chuàng)建,無法修改mapping。
- 雖然無法修改mapping中已有的字段,但是卻允許添加新的字段到mapping中,因?yàn)椴粫?huì)對(duì)倒排索引產(chǎn)生影響。
- 語法說明:PUT /索引庫名/_mapping {"properties": {"新字段名":{"type": "integer"}} }
- 演示:
3.5 刪除索引庫
- 語法:
- 請(qǐng)求方式:DELETE
- 請(qǐng)求路徑:/索引庫名
- 請(qǐng)求參數(shù):無
- 格式:DELETE /索引庫名
3.6 總結(jié)
- 索引庫操作:
- 創(chuàng)建索引庫: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查看數(shù)據(jù):GET /heima/_doc/1
- 演示:
4.3 刪除文檔
- 語法:DELETE /{索引庫名}/_doc/id值
- 演示:
4.4 修改文檔
- 修改有兩種方式:
- 全量修改:直接覆蓋原來的文檔
- 增量修改:修改文檔中的部分字段
- 全量修改
- 全量修改是覆蓋原來的文檔,其本質(zhì)是:
- 根據(jù)指定的id刪除文檔
- 新增一個(gè)相同id的文檔
- 注意:如果根據(jù)id刪除時(shí),id不存在,第二步的新增也會(huì)執(zhí)行,也就從修改變成了新增操作了。
- 語法:PUT /{索引庫名}/_doc/文檔id {"字段1": "值1","字段2": "值2",// ... 略 }
- 演示:
- 增量修改
- 增量修改是只修改指定id匹配的文檔中的部分字段。
- 語法:POST /{索引庫名}/_update/文檔id {"doc": {"字段名": "新的值"} }
- 演示:
4.5 總結(jié)
- 文檔操作:
- 創(chuàng)建文檔:POST /{索引庫名}/_doc/文檔id { json文檔 }
- 查詢文檔:GET /{索引庫名}/_doc/文檔id
- 刪除文檔:DELETE /{索引庫名}/_doc/文檔id
- 修改文檔:
- 全量修改:PUT /{索引庫名}/_doc/文檔id { json文檔 }
- 增量修改:POST /{索引庫名}/_update/文檔id { "doc": {字段}}
五 RestAPI
- ES官方提供了各種不同語言的客戶端,用來操作ES。這些客戶端的本質(zhì)就是組裝DSL語句,通過http請(qǐng)求發(fā)送給ES。官方文檔地址
- 其中的Java Rest Client又包括兩種:
- Java Low Level Rest Client
- Java High Level Rest Client
- 這里使用Java HighLevel Rest Client客戶端API
5.1 分析數(shù)據(jù)結(jié)構(gòu):apping映射分析
- 創(chuàng)建索引庫,最關(guān)鍵的是mapping映射,而mapping映射要考慮的信息包括:
- 字段名
- 字段數(shù)據(jù)類型
- 是否參與搜索
- 是否需要分詞
- 如果分詞,分詞器是什么?
- 其中:
- 字段名、字段數(shù)據(jù)類型,可以參考數(shù)據(jù)表結(jié)構(gòu)的名稱和類型
- 是否參與搜索要分析業(yè)務(wù)來判斷,例如圖片地址,就無需參與搜索
- 是否分詞呢要看內(nèi)容,內(nèi)容如果是一個(gè)整體就無需分詞,反之則要分詞
- 分詞器,我們可以統(tǒng)一使用ik_max_word
- 幾個(gè)特殊字段說明:
- location:地理坐標(biāo),里面包含精度、緯度
- all:一個(gè)組合字段,其目的是將多字段的值 利用copy_to合并,提供給用戶搜索
- 地理坐標(biāo)說明:
- copy_to說明:
5.2 初始化RestClient
- 在elasticsearch提供的API中,與elasticsearch一切交互都封裝在一個(gè)名為RestHighLevelClient的類中,必須先完成這個(gè)對(duì)象的初始化,建立與elasticsearch的連接。
- 步驟分為三步:
- 引入es的RestHighLevelClient依賴: <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>
- 因?yàn)镾pringBoot默認(rèn)的ES版本是7.6.2,所以我們需要覆蓋默認(rèn)的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") ));
- 測試,創(chuàng)建一個(gè)測試類HotelIndexTest,然后將初始化的代碼編寫在@BeforeEach方法中: public class HotelIndexTest {private RestHighLevelClient client;@BeforeEachvoid setUp() {this.client = new RestHighLevelClient(RestClient.builder(//xxx.xxx.xxx.xxx 虛擬主機(jī)的IPHttpHost.create("http://xxx.xxx.xxx.xxx:9200")));}@AfterEachvoid tearDown() throws IOException {this.client.close();} }
5.3 創(chuàng)建索引庫
- 代碼分為三步:
- 創(chuàng)建Request對(duì)象。因?yàn)槭莿?chuàng)建索引庫的操作,因此Request是CreateIndexRequest。
- 添加請(qǐng)求參數(shù),其實(shí)就是DSL的JSON參數(shù)部分。因?yàn)閖son字符串很長,這里是定義了靜態(tài)字符串常量MAPPING_TEMPLATE,讓代碼看起來更加優(yōu)雅。
- 發(fā)送請(qǐng)求,client.indices()方法的返回值是IndicesClient類型,封裝了所有與索引庫操作有關(guān)的方法。
- 演示
5.4 刪除索引庫
- 刪除索引庫的DSL語句非常簡單:DELETE /hotel
- 與創(chuàng)建索引庫相比:
- 請(qǐng)求方式從PUT變?yōu)镈ELTE
- 請(qǐng)求路徑不變
- 無請(qǐng)求參數(shù)
- 所以代碼的差異,注意體現(xiàn)在Request對(duì)象上。依然是三步走:
- 創(chuàng)建Request對(duì)象。這次是DeleteIndexRequest對(duì)象
- 準(zhǔn)備參數(shù)。這里是無參
- 發(fā)送請(qǐng)求。改用delete方法
- 編寫單元測試,實(shí)現(xiàn)刪除索引:@Test void testDeleteHotelIndex() throws IOException {// 1.創(chuàng)建Request對(duì)象DeleteIndexRequest request = new DeleteIndexRequest("hotel");// 2.發(fā)送請(qǐng)求client.indices().delete(request, RequestOptions.DEFAULT); }
5.5 判斷索引庫存在
- 判斷索引庫是否存在,本質(zhì)就是查詢,對(duì)應(yīng)的DSL是:GET /hotel
- 因此與刪除的Java代碼流程是類似的。依然是三步走:
- 創(chuàng)建Request對(duì)象。這次是GetIndexRequest對(duì)象
- 準(zhǔn)備參數(shù)。這里是無參
- 發(fā)送請(qǐng)求。改用exists方法 @Test void testExistsHotelIndex() throws IOException {// 1.創(chuàng)建Request對(duì)象GetIndexRequest request = new GetIndexRequest("hotel");// 2.發(fā)送請(qǐng)求boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);// 3.輸出System.err.println(exists ? "索引庫已經(jīng)存在!" : "索引庫不存在!"); }
5.6 總結(jié)
- JavaRestClient操作elasticsearch的流程基本類似。核心是client.indices()方法來獲取索引庫的操作對(duì)象。
- 索引庫操作的基本步驟:
- 初始化RestHighLevelClient
- 創(chuàng)建XxxIndexRequest。XXX是Create、Get、Delete
- 準(zhǔn)備DSL( Create時(shí)需要,其它是無參)
- 發(fā)送請(qǐng)求。調(diào)用RestHighLevelClient#indices().xxx()方法,xxx是create、exists、delete
六 RestClient操作文檔
- 為了與索引庫操作分離,需要增加加一個(gè)測試類:
- 初始化RestHighLevelClient
- 酒店數(shù)據(jù)在數(shù)據(jù)庫,需要利用IHotelService去查詢,所以注入這個(gè)接口
6.1 新增文檔
- 數(shù)據(jù)庫實(shí)體類->索引庫實(shí)體類
- 導(dǎo)入酒店數(shù)據(jù),基本流程一致,但是需要考慮幾點(diǎn)變化:
- 酒店數(shù)據(jù)來自于數(shù)據(jù)庫,需要先查詢出來,得到hotel對(duì)象
- hotel對(duì)象需要轉(zhuǎn)為HotelDoc對(duì)象
- HotelDoc需要序列化為json格式
- 因此,代碼整體步驟如下:
- 根據(jù)id查詢酒店數(shù)據(jù)Hotel
- 將Hotel封裝為HotelDoc
- 將HotelDoc序列化為JSON
- 創(chuàng)建IndexRequest,指定索引庫名和id
- 準(zhǔn)備請(qǐng)求參數(shù),也就是JSON文檔
- 發(fā)送請(qǐng)求 @Test void testAddDocument() throws IOException {// 1.根據(jù)id查詢酒店數(shù)據(jù)Hotel hotel = hotelService.getById(61083L);// 2.轉(zhuǎn)換為文檔類型HotelDoc hotelDoc = new HotelDoc(hotel);// 3.將HotelDoc轉(zhuǎn)jsonString json = JSON.toJSONString(hotelDoc);// 1.準(zhǔn)備Request對(duì)象IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());// 2.準(zhǔn)備Json文檔request.source(json, XContentType.JSON);// 3.發(fā)送請(qǐng)求client.index(request, RequestOptions.DEFAULT); }
- 測試運(yùn)行結(jié)果:
6.2 查詢文檔
- 詢的目的是得到結(jié)果,解析為HotelDoc,因此難點(diǎn)是結(jié)果的解析
- 結(jié)果是一個(gè)JSON,其中文檔放在一個(gè)_source屬性中,因此解析就是拿到_source,反序列化為Java對(duì)象即可
- 三步走:
- 準(zhǔn)備Request對(duì)象。這次是查詢,所以是GetRequest
- 發(fā)送請(qǐng)求,得到結(jié)果。因?yàn)槭遣樵?#xff0c;這里調(diào)用client.get()方法
- 解析結(jié)果,就是對(duì)JSON做反序列化
- 編寫單元測試:@Test void testGetDocumentById() throws IOException {// 1.準(zhǔn)備RequestGetRequest request = new GetRequest("hotel", "61082");// 2.發(fā)送請(qǐng)求,得到響應(yīng)GetResponse response = client.get(request, RequestOptions.DEFAULT);// 3.解析響應(yīng)結(jié)果String json = response.getSourceAsString();HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println(hotelDoc); }
6.3 修改文檔
-
在RestClient的API中,全量修改與新增的API完全一致,判斷依據(jù)是ID:
- 如果新增時(shí),ID已經(jīng)存在,則修改
- 如果新增時(shí),ID不存在,則新增
-
Upsert:如果文檔尚不存在,則可以使用以下upsert方法定義一些內(nèi)容,這些內(nèi)容將作為新文檔插入
String jsonString = "{\"created\":\"2017-01-01\"}"; request.upsert(jsonString, XContentType.JSON); -
全量修改:
@Testvoid testUpdateDocument() throws IOException {// 1.準(zhǔn)備RequestUpdateRequest request = new UpdateRequest("hotel", "61083");// 2.準(zhǔn)備請(qǐng)求參數(shù)UpdateRequest doc = request.doc("price", "952","starName", "四鉆");request.upsert(doc, XContentType.JSON);// 3.發(fā)送請(qǐng)求client.update(request, RequestOptions.DEFAULT);}
- 增量修改/*** 增量修改* @throws IOException*/ @Test void testUpdateDocument2() throws IOException {// 1.準(zhǔn)備RequestUpdateRequest request = new UpdateRequest("hotel", "61083");// 2.準(zhǔn)備請(qǐng)求參數(shù)UpdateRequest doc = request.doc("price", "888","starName", "八鉆");// 3.發(fā)送請(qǐng)求client.update(request, RequestOptions.DEFAULT); }
6.4 刪除文檔
- 三步走:
- 準(zhǔn)備Request對(duì)象,因?yàn)槭莿h除,這次是DeleteRequest對(duì)象。要指定索引庫名和id
- 準(zhǔn)備參數(shù),無參
- 發(fā)送請(qǐng)求。因?yàn)槭莿h除,所以是client.delete()方法 @Test void testDeleteDocument() throws IOException {// 1.準(zhǔn)備RequestDeleteRequest request = new DeleteRequest("hotel", "61083");// 2.發(fā)送請(qǐng)求client.delete(request, RequestOptions.DEFAULT); }
6.5 批量導(dǎo)入文檔
-
需求:利用BulkRequest批量將數(shù)據(jù)庫數(shù)據(jù)導(dǎo)入到索引庫中
-
步驟如下:
- 利用mybatis-plus查詢酒店數(shù)據(jù)
- 將查詢到的酒店數(shù)據(jù)(Hotel)轉(zhuǎn)換為文檔類型數(shù)據(jù)(HotelDoc)
- 利用JavaRestClient中的BulkRequest批處理,實(shí)現(xiàn)批量新增文檔
-
批量處理BulkRequest,其本質(zhì)就是將多個(gè)普通的CRUD請(qǐng)求組合在一起發(fā)送。
- 其中提供了一個(gè)add方法,用來添加其他請(qǐng)求:
- 其中提供了一個(gè)add方法,用來添加其他請(qǐng)求:
-
能添加的請(qǐng)求包括:
- IndexRequest:新增
- UpdateRequest:修改
- DeleteRequest:刪除
-
Bulk中添加了多個(gè)IndexRequest——批量新增功能
-
編寫單元測試
@Test void testBulkRequest() throws IOException {// 批量查詢酒店數(shù)據(jù)List<Hotel> hotels = hotelService.list();// 1.創(chuàng)建RequestBulkRequest request = new BulkRequest();// 2.準(zhǔn)備參數(shù),添加多個(gè)新增的Requestfor (Hotel hotel : hotels) {// 2.1.轉(zhuǎn)換為文檔類型HotelDocHotelDoc hotelDoc = new HotelDoc(hotel);// 2.2.創(chuàng)建新增文檔的Request對(duì)象request.add(new IndexRequest("hotel").id(hotelDoc.getId().toString()).source(JSON.toJSONString(hotelDoc), XContentType.JSON));}// 3.發(fā)送請(qǐng)求client.bulk(request, RequestOptions.DEFAULT); } -
測試運(yùn)行結(jié)果:
- 查詢數(shù)據(jù)庫的數(shù)據(jù)量
- 查詢索引庫的文檔數(shù)量
6.6 小結(jié)
- 文檔操作的基本步驟:
- 初始化RestHighLevelClient
- 創(chuàng)建XxxRequest。XXX:Index、Get、Update、Delete、Bulk
- 準(zhǔn)備參數(shù)(Index、Update、Bulk時(shí)需要)
- 發(fā)送請(qǐng)求。調(diào)用RestHighLevelClient#.xxx()方法,xxx:index、get、update、delete、bulk
- 解析結(jié)果(Get時(shí)需要)
總結(jié)
以上是生活随笔為你收集整理的springCloud学习【4】之elasticsearch(1)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [SSD核心技术:FTL 13] 不求同
- 下一篇: 实测:一周不更新文章头条号指数会掉多少?