簡介elasticsearch

我是@颶哥,經(jīng)常會(huì)分享Java后臺(tái)硬核知識(shí),歡迎大家關(guān)注~

全文搜索屬于最常見的需求,開源的 Elasticsearch 是目前全文搜索引擎的首選。它可以快速地存儲(chǔ)、搜索和分析海量數(shù)據(jù)。 維基百" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁 > 營銷資訊 > 網(wǎng)站運(yùn)營 > ES從入門到實(shí)戰(zhàn)

ES從入門到實(shí)戰(zhàn)

時(shí)間:2023-05-30 12:12:01 | 來源:網(wǎng)站運(yùn)營

時(shí)間:2023-05-30 12:12:01 來源:網(wǎng)站運(yùn)營

ES從入門到實(shí)戰(zhàn):

簡介

elasticsearch

我是@颶哥,經(jīng)常會(huì)分享Java后臺(tái)硬核知識(shí),歡迎大家關(guān)注~

全文搜索屬于最常見的需求,開源的 Elasticsearch 是目前全文搜索引擎的首選。它可以快速地存儲(chǔ)、搜索和分析海量數(shù)據(jù)。 維基百科、Stack Overflow、Github 都采用它。 Elastic 的底層是開源庫 Lucene。 但是,你沒法直接用 Lucene,必須自己寫代碼去調(diào)用它的接口。 Elastic 是 Lucene 的封裝,提供了 REST API 的操作接口,開箱即用。 REST API:天然的跨平臺(tái)。





一、基本概念

  1. Index(索引)
    動(dòng)詞,相當(dāng)于 MySQL 中的 insert; 名詞,相當(dāng)于 MySQL 中的 Database
  2. Type(類型)
    在 Index(索引)中,可以定義一個(gè)或多個(gè)類型; 類似于 MySQL 中的 Table;每一種類型的數(shù)據(jù)放在一起。
  3. Document(文檔)
    保存在某個(gè)索引(Index)下,某種類型(Type)的一個(gè)數(shù)據(jù)(Document),文檔是 JSON 格式的, Document 就像是 MySQL 中的某個(gè) Table 里面的內(nèi)容。
  4. 倒排索引機(jī)制
分詞:將整句分拆為單詞

保存的記錄
檢索: 1)、紅海特工行動(dòng)? 2)、紅海行動(dòng)?




二、Docker 安裝




1、下載鏡像文件

下載elasticsearch

docker pull elasticsearch:7.4.2 # 存儲(chǔ)和檢索數(shù)據(jù)

下載kibana

docker pull kibana:7.4.2 # 可視化檢索數(shù)據(jù)
注意:elasticsearch 要和 kibana 的版本保持一致!



2、創(chuàng)建實(shí)例

1. ElasticSearch

mkdir -p /mydata/elasticsearch/config # 在mydata文件夾下創(chuàng)建es的config文件夾,將docker中es的配置掛載在外部,當(dāng)我們在linux虛擬機(jī)中修改es的配置文件時(shí),就會(huì)同時(shí)修改docker中的es的配置mkdir -p /mydata/elasticsearch/data #在mydata文件夾下創(chuàng)建es的data文件夾echo "http.host:0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml # [http.host:0.0.0.0]允許任何遠(yuǎn)程機(jī)器訪問es,并將其寫入es的配置文件中chmod -R 777 /mydata/elasticsearch/ # 保證權(quán)限問題docker run --name elasticsearch -p 9200:9200 -p 9300:9300 /-e "discovery.type=single-node" /-e ES_JAVA_OPTS="-Xms64m -Xmx128m" /-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml /-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data /-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins /-d elasticsearch:7.4.2# docker run --name elasticsearch 創(chuàng)建一個(gè)es容器并起一個(gè)名字;# -p 9200:9200 將linux的9200端口映射到docker容器的9200端口,用來給es發(fā)送http請求# -p 9300:9300 9300是es在分布式集群狀態(tài)下節(jié)點(diǎn)之間的通信端口 / 換行符# -e 指定一個(gè)參數(shù),當(dāng)前es以單節(jié)點(diǎn)模式運(yùn)行# *注意,ES_JAVA_OPTS非常重要,指定開發(fā)時(shí)es運(yùn)行時(shí)的最小和最大內(nèi)存占用為64M和128M,否則就會(huì)占用全部可用內(nèi)存# -v 掛載命令,將虛擬機(jī)中的路徑和docker中的路徑進(jìn)行關(guān)聯(lián)# -d 后臺(tái)啟動(dòng)服務(wù)安裝完 elasticsearch 后我們來啟動(dòng)一下,會(huì)發(fā)現(xiàn)使用docker ps命令查看啟動(dòng)的容器時(shí)沒有找到我們的 es,這是因?yàn)槟壳?es 的配置文件的權(quán)限導(dǎo)致的,因此我們還需要修改一下 es 的配置文件的權(quán)限:




修改完文件權(quán)限后,我們使用docker start elasticsearch再次啟動(dòng) es,使用docker ps命令查看后發(fā)現(xiàn)容器還是沒有啟動(dòng),這是問什么呢? 我們使用docker logs elasticsearch看一下 es 的啟動(dòng)日志:




上述錯(cuò)誤是由于我之前配置elasticsearch.yml文件的時(shí)候k-v鍵值對配置錯(cuò)誤導(dǎo)致的,查看 yml 文件會(huì)發(fā)現(xiàn)我配置的內(nèi)容是這樣的:

http.host:0.0.0.0而實(shí)際上k-v鍵值對之間應(yīng)該有空格,注意 yml 配置文件中key: value格式冒號后面要跟一個(gè)空格。否則就會(huì)導(dǎo)致上面的錯(cuò)誤。 因此需要修改一下elasticsearch.yml文件,修改為:

http.host: 0.0.0.0修改并保存之后再次使用docker start elasticsearch啟動(dòng) es,使用docker ps命令產(chǎn)看后可以看到我的 es 容器已經(jīng)啟動(dòng)起來了:

在瀏覽器地址欄訪問http://124.220.176.158:9200/,可以看到 es 啟動(dòng)成功后返回類似下面的數(shù)據(jù):

注意124.220.176.158 是我的linux虛擬機(jī)的地址,讀者需要根據(jù)自己的虛擬機(jī)地址來進(jìn)行訪問



2, Kibana

安裝可視化界面

docker run --name kibana -e ELASTICSEARCH_HOSTS=http://124.220.176.158:9200 -p 5601:5601 /-d kibana:7.4.2安裝完成后在瀏覽器地址欄訪問http://124.220.176.158:5601/,可以看到 kibana 已經(jīng)啟動(dòng)成功:

選擇yes或no都可以:

安裝成功的界面:

三、初步檢索

對 ES 的所有請求都被封裝成了 REST API,因此我們可以使用 postman 來訪問它。

使用 postman 或者在瀏覽器地址欄輸入請求路徑http://124.220.176.158:9200/_cat/xxx



1、_cat

green 表示健康

2、索引一個(gè)文檔(對應(yīng)成Mysql就是保存一條記錄)

保存一個(gè)數(shù)據(jù),保存在哪個(gè)索引的哪個(gè)類型下,指定用哪個(gè)唯一標(biāo)識(shí)PUT customer/external/1; 在 customer 索引下的 external 類型下保存 1 號數(shù)據(jù)為




PUT customer/external/1



{

"name":"lohn Doe"

}

PUTPOST都可以;

POST新增。如果不指定id,會(huì)自動(dòng)生成 id。指定 id 就會(huì)修改這個(gè)數(shù)據(jù),并新增版本號;

PUT可以新增也可以修改。PUT 必須指定 id;由于 PUT 需要指定 id,我們一般都用來做修改

可以看到創(chuàng)建記錄成功:

再一次發(fā)送請求后得到如下結(jié)果:

所以 put 方法既可以用來新增,也可以用來更新。
在 postman 中使用 post 方法發(fā)送 http://192.168.56.10:9200/customer/external/ 請求,注意沒有帶 id,使用的還是上面 put 方法中的參數(shù), 可以看到創(chuàng)建記錄成功,es 幫我們生成了一個(gè)id:



當(dāng)我們使用這個(gè) id 再一次發(fā)送 post 請求時(shí),就會(huì)變成更新操作:

所以 post 方法不帶 id 時(shí)是新增,帶 id 不存在時(shí)也是新增,帶 id 且數(shù)據(jù)存在時(shí)是更新操作。




那么問題來了,put 和 post 方法有啥區(qū)別呢?如果使用 put 方法不帶 id 發(fā)送請求行不行?

可以看到使用 put 方法不帶 id 請求會(huì)報(bào)錯(cuò),也就是說 put 是不允許不帶 id 請求的,而 post 是允許的。




3、查詢文檔




3.1、get查詢數(shù)據(jù)

GET customer/external/1

3.2、樂觀鎖修改

要使用樂觀鎖修改,我們就需要在 put 或 post 請求的路徑中加上?if_seq_no=0&if_primary_term=1字段; 我們在 postman 中使用 put 方法發(fā)送 http://192.168.56.10:9200/customer/external/1?if_seq_no=0&if_primary_term=1 請求,參數(shù)傳



如果我們使用最新的序列號去更新,就會(huì)返回狀態(tài) 更新成功的結(jié)果:

4、更新文檔

使用帶_update的 post 請求更新數(shù)據(jù),在 postman 中使用 post 方法發(fā)送http://192.168.56.10:9200/customer/external/1/_update請求,參數(shù)傳:

發(fā)送請求可以得到下面的結(jié)果,可以看到更新成功:

再次發(fā)送請求,可以看到如果數(shù)據(jù)相同,對比原來數(shù)據(jù),與原來一樣就什么都不做,_version_seq_no也不會(huì)變:




5、刪除文檔&索引




5.1、刪除文檔

在 postman 中使用 delete 方法發(fā)送 http://192.168.56.10:9200/customer/external/1 請求,可以看到以下結(jié)果,可以看到刪除文檔成功:

再發(fā)送一次請求,會(huì)返回一個(gè) 404 狀態(tài)的not_found結(jié)果:

5.2、刪除索引

在 kibanda中使用 delete 方法發(fā)送http://192.168.56.10:9200/customer請求,可以看到以下結(jié)果,可以看到刪除索引成功:

查詢一下剛才刪除的索引,會(huì)返回一個(gè)no such index [customer]的 404 狀態(tài)的結(jié)果:

6、bulk 批量 API

要使用 bulk 批量 API,就需要在 kibana 中來執(zhí)行我們的操作,如果在 postman 中請求會(huì)報(bào)錯(cuò): 首先我們的請求體中的數(shù)據(jù)已經(jīng)不是 json 格式了,我們是用 text 格式,會(huì)報(bào)下面的錯(cuò)誤:

進(jìn)行一個(gè)復(fù)雜的批量操作

POST /_bulk{"delete":{"_index":"website","_type":"blog","_id":"123"}}{"create":{"_index":"website","_type":"blog","_id":"123"}}{"title":"My first blog post"}{"index":{"_index":"website","_type":"blog"}}{"title":"My second blog post"}{"update":{"_index":"website","_type":"blog","_id":"123"}}{"doc":{"title":"My updated blog post"}}上面直接使用了/_bulk,沒有指定具體的索引,表示在 ES 全局執(zhí)行。執(zhí)行結(jié)果如下:

bulk API 以此按順序執(zhí)行所有的 action (動(dòng)作) 。 如果一個(gè)單個(gè)的動(dòng)作因任何原因而失敗,它將繼續(xù)處理它后面剩余的動(dòng)作。 當(dāng) bulk API 返回時(shí),它將提供每個(gè)動(dòng)作的狀態(tài)(與發(fā)送的順序相同) ,所以你可以檢查是否一個(gè)指定的動(dòng)作是不是失敗了。

7、樣本測試數(shù)據(jù)

我準(zhǔn)備了一份顧客銀行賬戶信息的虛構(gòu)的 JSON 文檔樣本。每個(gè)文檔都有下列的 schema(模式) :

上面的數(shù)據(jù)是從 github 的 ES 官方文檔中截取的,可以訪問下面的地址:

accounts.json 導(dǎo)入測試數(shù)據(jù)

在 ES 中執(zhí)行測試數(shù)據(jù) POST bank/account/_bulk:




四、進(jìn)階檢索

1、SearchAPl


ES 支持兩種基本方式檢索:


1)、檢索信息
一切檢索從_search開始 uri+檢索參數(shù):



uri+請求體 進(jìn)行檢索:

GET /example/_search

{ "query": { "match_all": {} }

}

HTTP 客戶端工具(POSTMAN),get 請求不能攜帶請求體,我們變?yōu)?post 也是一樣的我們 POST 一個(gè) JSON 風(fēng)格的查詢請求體到_search APl。
需要了解,一旦搜索的結(jié)果被返回, Elasticsearch 就完成了這次請求,并且不會(huì)維護(hù)任何服務(wù)端的資源或者結(jié)果的 cursor (游標(biāo))

2、Query DSL

GET /example/_search{ "query": { "match_all": {} }, "sort": [ { "id": "asc" } ]}1)、基本語法格式
Elastisearch 提供了一個(gè)可以執(zhí)行查詢的 Json 風(fēng)格的 DSl (domain-specific language 領(lǐng)域特定語言) 。這個(gè)被稱為Query DSL。 該查詢語言非常全面,并且剛開始的時(shí)候感覺有點(diǎn)復(fù)雜,真正學(xué)好它的方法是從一些基礎(chǔ)的示例開始的。


{ QUERY_NAME:{ ARGUMENT: VALUE, ARGUMENT: VALUE, ... }}例如:

如果是針對某個(gè)字段,那么它的結(jié)構(gòu)如下:

{ QUERY_NAME:{ FIELD_NAME:{ ARGUMENT: VALUE, ARGUMENT: VALUE, ... } }}例如:

GET /bank/_search{ "query": { "match_all": {} }, "sort": [ { "balance": { "order": "desc" } } ], "from": 0, "size": 5}- query 定義如何查詢;
- match_all 查詢類型【代表查詢所有的所有】, es 中可以在 query 中組合非常多的查詢類型完成復(fù)雜查詢
- 除了 query 參數(shù)之外,我們也可以傳遞其它的參數(shù)以改變查詢結(jié)果。如 sort,size;
- from+size 限定,完成分頁功能;
- sort 排序,多字段排序,會(huì)在前序字段相等時(shí)后續(xù)字段內(nèi)部排序,否則以前序?yàn)闇?zhǔn)



2)、返回部分字段

GET /example/_search{ "query": { "match_all": {} }, "sort": [ { "id": "asc" } ], "from": 0, "size": 5,"_source": ["name","counter"] }只返回_source中指定的字段,類似于 MySQL 中的select field_1,field_2,... from table




3)、match【匹配查詢】

match 返回 id=1的數(shù)據(jù):

GET /example/_search{ "query": { "match": { "id": 1 } }}最終查詢出 name中包含 張的所有記錄,當(dāng)搜索字符串類型的時(shí)候,會(huì)進(jìn)行全文檢索,并且每條記錄有相關(guān)性得分。

GET /example/_search{ "query": { "match": { "name": "張" } }}

4)、match_phrase 【短語匹配】

將需要匹配的值當(dāng)成一個(gè)整體單詞(不分詞)進(jìn)行檢索

舉個(gè)栗子:查出 name中包含張的所有記錄,并給出相關(guān)性得分

GET /example/_search{ "query": { "match_phrase": { "name": "張 三" } }}

5)、multi_match 【多字段匹配】

舉例:id或 counter包含 1




GET /example/_search{ "query": { "multi_match": { "query": "1", "fields": ["id","counter"] } }}

6)、bool 【復(fù)合查詢】

bool 用來做復(fù)合查詢:

復(fù)合語句可以合并任何其它查詢語句,包括復(fù)合語句,了解這一點(diǎn)是很重要的。 這就意味著,復(fù)合語句之間可以互相嵌套,可以表達(dá)非常復(fù)雜的邏輯。

GET /example/_search{ "query": { "bool": { "must": [ { "match": { "id": 2 } }, { "match": { "name": "張三" } } ] } }}must_not:子句(查詢)不得出現(xiàn)在匹配的文檔中




should:子句(查詢)應(yīng)出現(xiàn)在匹配的文檔中。(should表示有最好,沒有也可以)

布爾查詢

與文檔匹配的查詢,這些文檔與其他查詢的布爾組合匹配。布爾查詢映射到LuceneBooleanQuery。它是使用一個(gè)或多個(gè)布爾子句構(gòu)建的,每個(gè)子句都具有類型的出現(xiàn)。發(fā)生類型為:

7)、filter 【結(jié)果過濾】
并不是所有的查詢都需要產(chǎn)生分?jǐn)?shù),特別是那些僅用于 "fitering" (過濾)的文檔。為了不計(jì)算分?jǐn)?shù) Elasticsearch 會(huì)自動(dòng)檢查場景并且優(yōu)化查詢的執(zhí)行。 在 filter 元素下指定的查詢對得分沒有影響-得分以 0 形式返回。分?jǐn)?shù)僅受指定查詢的影響。 以 must 查詢?yōu)槔?br>


使用filter來替代must查詢,需要注意的是,使用filter查詢出的結(jié)果和must查詢出的結(jié)果是一致的,差異僅是沒有相關(guān)性得分:

所以我們在should之后還可以加上filter條件進(jìn)行過濾:




8)、term

和 match 一樣。匹配某個(gè)屬性的值。全文檢索字段用 match,其他非 text 字段匹配用 term。

非文本值使用 term 檢索:

GET /example/_search{ "query": { "term": { "id":1 } }}注意:如果對于文本值使用 term 檢索時(shí),并不會(huì)進(jìn)行分詞,而是精確檢索,所以可能會(huì)匹配不到數(shù)據(jù):




9) 、aggregations (執(zhí)行聚合)
聚合提供了從數(shù)據(jù)中分組和提取數(shù)據(jù)的能力。 最簡單的聚合方法大致等于 SQL GROUP BYSQL 聚合函數(shù)。 在 Elasticsearch 中,您有執(zhí)行搜索返回 hits (命中結(jié)果),并且同時(shí)返回聚合結(jié)果, 把一個(gè)響應(yīng)中的所有hits(命中結(jié)果)分隔開的能力。這是非常強(qiáng)大且有效的,您可以執(zhí)行查詢和多個(gè)聚合, 并且在一次使用中得到各自的(任何一個(gè)的)返回結(jié)果,使用一次簡潔和簡化的 API 來避免網(wǎng)絡(luò)往返。
aggregations 查詢語法:



"aggregations" : { "<aggregation_name>" : { "<aggregation_type>" : { <aggregation_body> } [,"meta" : { [<meta_data_body>] } ]? [,"aggregations" : { [<sub_aggregation>]+ } ]? } [,"<aggregation_name_2>" : { ... } ]*}


3、Mapping


1)、字段類型


地理類型(Geo)



特定類型



2)、映射
Mapping (映射) Mapping 是用來定義一個(gè)文檔(document),以及它所包含的屬性(field)是如何存儲(chǔ)和索引的。比如,使用mapping來定義:






PUT /my-index{ "mappings": {//映射規(guī)則 "properties": { "age": { "type": "integer" }, "email": { "type": "keyword" },//keyword不會(huì)進(jìn)行全文檢索 "name": { "type": "text" }//text保存的時(shí)候進(jìn)行分詞,搜索的時(shí)候進(jìn)行全文檢索 } }}3)、新版本改變
ES7 及以上移除了 type 的概念。


Elasticsearch 7.x:


Elasticsearch 8.x:


解決: 1)、將索引從多類型遷移到單類型,每種類型文檔一個(gè)獨(dú)立索引 2)、將已存在的索引下的類型數(shù)據(jù),全部遷移到指定位置即可。詳見數(shù)據(jù)遷移

關(guān)鍵詞:實(shí)戰(zhàn),入門

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉