核心概念
-
索引
一個(gè)索引就是一個(gè)擁有幾分相似特征的文檔的集合。
Eg:一個(gè)客戶數(shù)據(jù)的索引,另一個(gè)產(chǎn)品目錄的索引,還有一個(gè)訂單數(shù)據(jù)的索引。
能搜索的數(shù)據(jù)必須索引,這樣的好處是可以提高查詢速度
-
類型
一個(gè)類型是你的索引的一個(gè)邏輯上的分類/分區(qū),其語義完全由你來定。
ES6.x之后一個(gè)索引只能有一個(gè)type
-
文檔
一個(gè)文檔是一個(gè)可被索引的基礎(chǔ)信息單元,也就是一條數(shù)據(jù)
文檔以 JSON(Javascript Object Notation)格式來表示,而 JSON 是一個(gè)到處存在的互聯(lián)網(wǎng)數(shù)據(jù)交互格式。
-
字段
相當(dāng)于是數(shù)據(jù)表的字段,對(duì)文檔數(shù)據(jù)根據(jù)不同屬性進(jìn)行的分類標(biāo)識(shí)。
-
映射
mapping 是處理數(shù)據(jù)的方式和規(guī)則方面做一些限制,如:某個(gè)字段的數(shù)據(jù)類型、默認(rèn)值、分析器、是否被索引等等。
-
分片
應(yīng)用場(chǎng)景:一個(gè)索引可以存儲(chǔ)超出單個(gè)節(jié)點(diǎn)硬件限制的大量數(shù)據(jù)。
分片很重要,主要有兩方面的原因:
1)允許你水平分割 / 擴(kuò)展你的內(nèi)容容量。
2)允許你在分片之上進(jìn)行分布式的、并行的操作,進(jìn)而提高性能/吞吐量。
-
副本(復(fù)制分片)
Elasticsearch 允許你創(chuàng)建分片的一份或多份拷貝,這些拷貝叫做復(fù)制分片(副本)。
復(fù)制分片主要原因:
- 在分片/節(jié)點(diǎn)失敗的情況下,提供了高可用;so不能把復(fù)制分片與原分片置于用一個(gè)節(jié)點(diǎn)上
- 擴(kuò)展你的搜索量/吞吐量,因?yàn)樗阉骺梢栽谒械母北旧喜⑿羞\(yùn)行。
默認(rèn)情況下,Elasticsearch 中的每個(gè)索引被分片 1 個(gè)主分片和 1 個(gè)復(fù)制,這意味著,如果你的集群中至少有兩個(gè)節(jié)點(diǎn),你的索引將會(huì)有 1 個(gè)主分片和另外 1 個(gè)復(fù)制分片(1 個(gè)完全拷貝),這樣的話每個(gè)索引總共就有 2 個(gè)分片,我們需要根據(jù)索引需要確定分片個(gè)數(shù)。
-
分配
將分片分配給某個(gè)節(jié)點(diǎn)的過程,包括分配主分片或者副本。如果是副本,還包含從主分片復(fù)制數(shù)據(jù)的過程。這個(gè)過程是由 master 節(jié)點(diǎn)完成的。
系統(tǒng)架構(gòu)

說明
- 這三個(gè)節(jié)點(diǎn)擁有相同的cluster.name配置,所以他們組成一個(gè)集群共同承擔(dān)數(shù)據(jù)和負(fù)載的壓力。
- 如圖所示:node1節(jié)點(diǎn)被選舉成為主節(jié)點(diǎn),將負(fù)責(zé)管理集群范圍內(nèi)的所有的變更,文檔的增刪、節(jié)點(diǎn)的增刪等
- 當(dāng)一個(gè)主節(jié)點(diǎn)確定后,會(huì)將主節(jié)點(diǎn)的分片進(jìn)行備份,也即是保存副本
分布式集群
單節(jié)點(diǎn)集群
我們?cè)诎粋€(gè)空節(jié)點(diǎn)的集群內(nèi)創(chuàng)建名為users的索引,為了演示目的,我們將分配3個(gè)主分片和一份副本(每個(gè)主分片擁有一個(gè)副本分片)
-
請(qǐng)求方式
向 ES 服務(wù)器發(fā) GET 請(qǐng)求 :http://127.0.0.1:1001/users
-
請(qǐng)求體
{ "settings": { "number_of_shards": 3, "number_of_replicas": 1 // 這個(gè)number_of_replicas參數(shù)控制著一個(gè)主節(jié)點(diǎn)下有幾份副本 } }
-
通過 elasticsearch-head 插件查看集群情況
- node-1(綠色的):表示3個(gè)主分片正常
- unassigned:表示三個(gè)副本分片沒有被分配到任何節(jié)點(diǎn),原因是:同一個(gè)節(jié)點(diǎn)既保存原始數(shù)據(jù)又保存副本毫無意義
故障轉(zhuǎn)移
啟動(dòng)第二臺(tái)節(jié)點(diǎn)機(jī)器(擁有同樣cluster.name配置的機(jī)器)
- 同一臺(tái)機(jī)器上啟動(dòng)第二個(gè)節(jié)點(diǎn),會(huì)自動(dòng)發(fā)現(xiàn)集群并加入其中(同一臺(tái)機(jī)器上會(huì)自動(dòng)加入)
- 不同的機(jī)器上啟動(dòng)節(jié)點(diǎn)時(shí),為了加入到同一個(gè)集群,需要配置一個(gè)可連接到的單播主機(jī)列表,之所以配置是為了使用單播發(fā)現(xiàn),以防止節(jié)點(diǎn)無意中加入集群。
-
通過 elasticsearch-head 插件查看集群情況
- node-1節(jié)點(diǎn):表示三個(gè)主分片(P1、P2、P3)
- node-2節(jié)點(diǎn):當(dāng)?shù)诙€(gè)節(jié)點(diǎn)加入到集群后,3 個(gè)副本分片將會(huì)分配到這個(gè)節(jié)點(diǎn)上——每個(gè)主分片對(duì)應(yīng)一個(gè)副本分片。這意味著當(dāng)集群內(nèi)任何一個(gè)節(jié)點(diǎn)出現(xiàn)問題時(shí),我們的數(shù)據(jù)都完好無損。所有新近被索引的文檔都將會(huì)保存在主分片上,然后被并行的復(fù)制到對(duì)應(yīng)的副本分片上。這就保證了我們既可以從主分片又可以從副本分片上獲得文檔。
水平擴(kuò)容
啟動(dòng)第三臺(tái)節(jié)點(diǎn)機(jī)器:為了分散負(fù)載而對(duì)分片進(jìn)行重新分配(原分片不全丟在同一個(gè)籃子里了)

-
通過 elasticsearch-head 插件查看集群情況
- 可以看到node-1、node-2上各有一個(gè)分片被遷移到新的node-3節(jié)點(diǎn)上,現(xiàn)在每個(gè)節(jié)點(diǎn)上由開始的三個(gè)分片下降到兩個(gè)分片,即硬件資源被更少的分片所共享,提升性能
-
副本擴(kuò)容到6個(gè)分片
即一個(gè)原分片被復(fù)制2份,更安全,搜索的時(shí)候在任一節(jié)點(diǎn)上都能找到所有的分片信息,按照下面的節(jié)點(diǎn)配置,我們可以在失去 2 個(gè)節(jié)點(diǎn)的情況下不丟失任何數(shù)據(jù)。
當(dāng)然,如果只是在相同節(jié)點(diǎn)數(shù)目的集群上增加更多的副本分片并不能提高性能,因?yàn)槊總€(gè)分片從節(jié)點(diǎn)上獲得的資源會(huì)變少。
在運(yùn)行中的集群上是可以動(dòng)態(tài)調(diào)整副本分片數(shù)目的,我們可以按需伸縮集群。
-
請(qǐng)求頭
向 ES 服務(wù)器發(fā) PUT 請(qǐng)求 :http://127.0.0.1:1001/users/_settings
-
請(qǐng)求體
``` { "number_of_replicas": 2 } ```
-
通過 elasticsearch-head 插件查看集群情況
-
-
應(yīng)對(duì)故障
Node-1(主節(jié)點(diǎn))異常關(guān)閉
前置條件:集群必須擁有一個(gè)主節(jié)點(diǎn)來保證正常工作
-
ES內(nèi)部處理機(jī)制
- 選舉一個(gè)新的主節(jié)點(diǎn): Node-3 。
- 將Node-3身上的副本提升至主分片。
-
通過 elasticsearch-head 插件查看集群情況
-
關(guān)于集群狀態(tài)說明
按理說,當(dāng)前node-3擁有所有的主分片,夢(mèng)回之前兩個(gè)節(jié)點(diǎn)的情況,相差無二
但是,之前我們?cè)O(shè)置了number_of_replicas為2,這時(shí)插件就會(huì)查詢到每個(gè)主分片應(yīng)當(dāng)對(duì)應(yīng)兩份副本,而此時(shí)只有一份,so,報(bào)yellow狀態(tài)
-
重啟原主節(jié)點(diǎn)
- 與當(dāng)前主分片對(duì)比,復(fù)制發(fā)生修改的數(shù)據(jù)文件到自己這
- master節(jié)點(diǎn)不會(huì)動(dòng),原master節(jié)點(diǎn)回來也只能當(dāng)從節(jié)點(diǎn),與redis類似
路由計(jì)算(確定哪個(gè)主分片)
都知道,文檔要被儲(chǔ)存到主分片中,但是主分片有很多啊,Elasticsearch 如何知道一個(gè)文檔應(yīng)該存放到哪個(gè)分片中呢?
首先這肯定不會(huì)是隨機(jī)的,否則將來要獲取文檔的時(shí)候我們就不知道從何處尋找了。實(shí)際上,這個(gè)過程是根據(jù)下面這個(gè)公式?jīng)Q定的:
shard = hash(routing) % 每個(gè)主分片的副本分片數(shù)量(number_of_primary_shards) -> [0,1,2] -> [P0, P1, P2]
- routing 是一個(gè)可變值,默認(rèn)是文檔的 _id ,也可以設(shè)置成一個(gè)自定義的值。
- 從公式中不難看出,創(chuàng)建索引的時(shí)候,每個(gè)主分片的副本分片數(shù)量(number_of_primary_shards)這個(gè)值一旦確定,就不能改變,一旦改變,之前的路由的值全都無效了,文檔就找不到了。
- 概念澄清:
number_of_primary_shards
定義了每個(gè)主分片的副本數(shù)量number_of_replicas
定義了每個(gè)主分片的復(fù)制數(shù)量。

分片控制(確定哪個(gè)節(jié)點(diǎn))
創(chuàng)建個(gè)集群
創(chuàng)建一個(gè)索引:emps,集群由三個(gè)節(jié)點(diǎn)組成,有兩個(gè)主分片,每個(gè)主分片擁有兩個(gè)副本
向 ES 服務(wù)器發(fā) PUT 請(qǐng)求 :http://127.0.0.1:1001/emps
-
請(qǐng)求體
{ "settings": { "number_of_shards": 2, "number_of_replicas": 2 } }
-
通過插件查看集群情況
如何查看數(shù)據(jù)呢?
這時(shí)候我們對(duì)集群的任一節(jié)點(diǎn)發(fā)送查詢請(qǐng)求,每個(gè)節(jié)點(diǎn)都有能力處理這些請(qǐng)求。
每個(gè)節(jié)點(diǎn)都知道集群中任一文檔位置,所以可以直接將請(qǐng)求轉(zhuǎn)發(fā)到需要的節(jié)點(diǎn)上。
當(dāng)發(fā)送請(qǐng)求的時(shí)候, 為了擴(kuò)展負(fù)載,更好的做法是輪詢集群中所有的節(jié)點(diǎn)。
寫流程

-
客戶端向 Node 2 發(fā)送新建、索引或者刪除請(qǐng)求。
-
節(jié)點(diǎn)使用文檔的 _id 確定文檔屬于分片 0 。請(qǐng)求會(huì)被轉(zhuǎn)發(fā)到 Node 1,因?yàn)榉制?0 的主分片目前被分配在 Node 1 上。
-
Node 1 在主分片上面執(zhí)行請(qǐng)求。如果成功了,它將請(qǐng)求并行轉(zhuǎn)發(fā)到 Node 2 的副本分片上。一旦所有的副本分片都報(bào)告成功, Node 1 將向協(xié)調(diào)節(jié)點(diǎn)報(bào)告成功,協(xié)調(diào)節(jié)點(diǎn)向客戶端報(bào)告成功。
關(guān)于第三步,提升性能的方式:犧牲數(shù)據(jù)安全這個(gè)代價(jià),即不需要等所有的副本分片都OK,協(xié)調(diào)節(jié)點(diǎn)才向客戶端報(bào)告OK
參數(shù) 含義 consistency consistency,即一致性。在默認(rèn)設(shè)置下,即使僅僅是在試圖執(zhí)行一個(gè)寫操作之前,主分片都會(huì)要求必須要有規(guī)定數(shù)量(quorum)(或者換種說法,也即必須要有大多數(shù))的分片副本處于活躍可用狀態(tài),才會(huì)去執(zhí)行 寫操作(其中分片副本可以是主分片或者副本分片)。這是為了避免在發(fā)生網(wǎng)絡(luò)分區(qū)故障(networkpartition)的時(shí)候進(jìn)行寫操作,進(jìn)而導(dǎo)致數(shù)據(jù)不一致。
規(guī)定數(shù)量 即:int( (primary + number of replicas) / 2 ) + 1
consistency 參數(shù)的值可以設(shè)為 one (只要主分片狀態(tài) ok 就允許執(zhí)行 寫 操作),all (必須要主分片和所有副本分片的狀態(tài)沒問題才允許執(zhí)行 寫 操作),或quorum 。默認(rèn)值為 quorum,即大多數(shù)的分片副本狀態(tài)沒問題就允許執(zhí)行_寫操作。注意,規(guī)定數(shù)量 的計(jì)算公式中 number of replicas 指的是在索引設(shè)置中的設(shè)定副本分片數(shù),而不是指當(dāng)前處理活動(dòng)狀態(tài)的副本分片數(shù)。如果你的索引設(shè)置中指定了當(dāng)前索引擁有三個(gè)副本分片,那規(guī)定數(shù)量的計(jì)算結(jié)果即:
int( (primary + 3 replicas) / 2 ) + 1 = 3
如果此時(shí)你只啟動(dòng)兩個(gè)節(jié)點(diǎn),那么處于活躍狀態(tài)的分片副本數(shù)量就達(dá)不到規(guī)定數(shù)量,也因此您將無法索引和刪除任何文檔。timeout 如果沒有足夠的副本分片會(huì)發(fā)生什么? Elasticsearch 會(huì)等待,希望更多的分片出現(xiàn)。默認(rèn)情況下,它最多等待 1 分鐘。 如果你需要,你可以使用 timeout 參數(shù)使它更早終止: 100表示100 毫秒,30s 是 30 秒。
讀流程

-
客戶端向 Node 1 發(fā)送獲取請(qǐng)求。
-
節(jié)點(diǎn)使用文檔的 _id 來確定文檔屬于分片 0 。分片 0 的副本分片存在于所有的三個(gè)節(jié)點(diǎn)上。 在這種情況下,它將請(qǐng)求轉(zhuǎn)發(fā)到 Node 2 。
-
Node 2 將文檔返回給 Node 1 ,然后將文檔返回給客戶端。
更新流程
高并發(fā)的情況下,容易出現(xiàn)問題

-
客戶端向 Node 2 發(fā)送更新請(qǐng)求。
-
它將請(qǐng)求轉(zhuǎn)發(fā)到主分片所在的 Node 1 。
-
Node 1 從主分片檢索文檔,修改 _source 字段中的 JSON ,并且嘗試重新索引主分片的文檔。如果文檔已經(jīng)被另一個(gè)進(jìn)程修改,它會(huì)重試步驟 3 ,超過 retry_on_conflict 次后放棄。
-
如果 Node 1 成功地更新文檔,它將新版本的文檔并行轉(zhuǎn)發(fā)到 Node 2 的副本分片,重新建立索引。一旦所有副本分片都返回成功, Node 1 向協(xié)調(diào)節(jié)點(diǎn)也返回成功,協(xié)調(diào)節(jié)點(diǎn)向客戶端返回成功。
分片原理
分片是 Elasticsearch 最小的工作單元。
倒序索引
傳統(tǒng)的數(shù)據(jù)庫每個(gè)字段存儲(chǔ)單個(gè)值,但這對(duì)全文檢索并不夠。文本字段中的每個(gè)單詞需要被搜索,對(duì)數(shù)據(jù)庫意味著需要單個(gè)字段有索引多值的能力。最好的支持是一個(gè)字段多個(gè)值需求的數(shù)據(jù)結(jié)構(gòu)是倒排索引。
所謂的正向索引,就是搜索引擎會(huì)將待搜索的文件都對(duì)應(yīng)一個(gè)文件 ID,搜索時(shí)將這個(gè)ID 和搜索關(guān)鍵字進(jìn)行對(duì)應(yīng),形成 K-V 對(duì),然后對(duì)關(guān)鍵字進(jìn)行統(tǒng)計(jì)計(jì)數(shù)
-
舉個(gè)例子
建兩個(gè)文檔
- The quick brown fox jumped over the lazy dog
- Quick brown foxes leap over lazy dogs in summer
搜索quick、brown
分析:
兩個(gè)文檔都匹配,但是第一個(gè)文檔比第二個(gè)匹配度更高。如果我們使用僅計(jì)算匹配詞條數(shù)量的簡單相似性算法,那么我們可以說,對(duì)于我們查詢的相關(guān)性來講,第一個(gè)文檔比第二個(gè)文檔更佳。
-
引入新問題
- Quick 和 quick 以獨(dú)立的詞條出現(xiàn),然而用戶可能認(rèn)為它們是相同的詞。
- fox 和 foxes 非常相似, 就像 dog 和 dogs ;他們有相同的詞根。
- jumped 和 leap, 盡管沒有相同的詞根,但他們的意思很相近。他們是同義詞。
文檔搜索
早期的全文檢索會(huì)為整個(gè)文檔集合建立一個(gè)很大的倒排索引并將其寫入到磁盤。 一旦新的索引就緒,舊的就會(huì)被其替換,這樣最近的變化便可以被檢索到。
倒排索引被寫入磁盤后是 不可改變的,它永遠(yuǎn)不會(huì)修改。
-
不變的好處
- 不需要鎖。如果你從來不更新索引,你就不需要擔(dān)心多進(jìn)程同時(shí)修改數(shù)據(jù)的問題。
- 一旦索引被讀入內(nèi)核的文件系統(tǒng)緩存,便會(huì)留在哪里,由于其不變性。只要文件系統(tǒng)緩存中還有足夠的空間,那么大部分讀請(qǐng)求會(huì)直接請(qǐng)求內(nèi)存,而不會(huì)命中磁盤。這提供了很大的性能提升。
- 其它緩存(像 filter 緩存),在索引的生命周期內(nèi)始終有效。它們不需要在每次數(shù)據(jù)改變時(shí)被重建,因?yàn)閿?shù)據(jù)不會(huì)變化。
- 寫入單個(gè)大的倒排索引允許數(shù)據(jù)被壓縮,減少磁盤 I/O 和 需要被緩存到內(nèi)存的索引的使用量。
-
不變的壞處
主要事實(shí)是它是不可變的! 你不能修改它。如果你需要讓一個(gè)新的文檔 可被搜索,你需要重建整個(gè)索引。這要么對(duì)一個(gè)索引所能包含的數(shù)據(jù)量造成了很大的限制,要么對(duì)索引可被更新的頻率造成了很大的限制。
動(dòng)態(tài)更新索引
保留不變性的前提下,實(shí)現(xiàn)倒排索引的更新
- 用更多的索引。通過增加新的補(bǔ)充索引來反映新近的修改,而不是直接重寫整個(gè)倒排索引。每一個(gè)倒排索引都會(huì)被輪流查詢到,從最早的開始查詢完后再對(duì)結(jié)果進(jìn)行合并。
持久化變更

文檔分析
分析包含下面的過程:
- 將一塊文本分成適合于倒排索引的獨(dú)立的詞條
- 字符過濾器:他們的任務(wù)是在分詞前整理字符串。一個(gè)字符過濾器可以用來去掉 HTML,或者將 & 轉(zhuǎn)化成 and。
- 分詞器:一個(gè)簡單的分詞器遇到空格和標(biāo)點(diǎn)的時(shí)候,可能會(huì)將文本拆分成詞條。
- 將這些詞條統(tǒng)一化為標(biāo)準(zhǔn)格式以提高它們的“可搜索性”,或者 recall
- Token 過濾器:這個(gè)過程可能會(huì)改變?cè)~條(例如,小寫化Quick ),刪除詞條(例如, 像 a, and, the 等無用詞),或者增加詞條(例如,像 jump 和 leap 這種同義詞)。
內(nèi)置分析器
下面幾種分析其都會(huì)針對(duì)"Set the shape to semi-transparent by calling set_trans(5)"進(jìn)行分詞
-
標(biāo)準(zhǔn)分析器
-
原理
它根據(jù) Unicode 聯(lián)盟 定義的 單詞邊界 劃分文本。刪除絕大部分標(biāo)點(diǎn)。最后,將詞條小寫。
-
結(jié)果
set, the, shape, to, semi, transparent, by, calling, set_trans, 5
-
-
簡單分析器
-
原理
在任何不是字母的地方分隔文本,將詞條小寫。
-
結(jié)果
set, the, shape, to, semi, transparent, by, calling, set, trans
-
-
空格分析器
-
原理
在空格的地方劃分文本。
-
結(jié)果
Set, the, shape, to, semi-transparent, by, calling, set_trans(5)
-
-
語言分析器
-
原理
特定語言分析器可用于 很多語言。它們可以考慮指定語言的特點(diǎn)。例如, 英語 分析器附帶了一組英語無用詞(常用單詞,例如 and 或者 the ,它們對(duì)相關(guān)性沒有多少影響),它們會(huì)被刪除。 由于理解英語語法的規(guī)則,這個(gè)分詞器可以提取英語單詞的 詞干 。
-
結(jié)果
set, shape, semi, transpar, call, set_tran, 5
- transparent->transpar(詞根)
- calling->call(詞根)
- set_trans->set_tran(詞根)
-
分析器使用場(chǎng)景
當(dāng)我們 索引 一個(gè)文檔,它的全文域被分析成詞條以用來創(chuàng)建倒排索引。
但是,當(dāng)我們?cè)谌挠蛩阉鞯臅r(shí)候,我們需要將查詢字符串通過相同的分析過程,以保證我們搜索的詞條格式與索引中的詞條格式一致。
- 當(dāng)你查詢一個(gè)全文域時(shí), 會(huì)對(duì)查詢字符串應(yīng)用相同的分析器,以產(chǎn)生正確的搜索詞條列表
- 當(dāng)你查詢一個(gè)精確值域時(shí),不會(huì)分析查詢字符串,而是搜索你指定的精確值。
測(cè)試分析器
向 ES 服務(wù)器發(fā) GET 請(qǐng)求 :http://localhost:9200/_analyze
-
請(qǐng)求
{ "analyzer": "standard", "text": "Text to analyze" }
-
響應(yīng)
{ "tokens": [ { "token": "text", "start_offset": 0, "end_offset": 4, "type": "<ALPHANUM>", "position": 1 }, { "token": "to", "start_offset": 5, "end_offset": 7, "type": "<ALPHANUM>", "position": 2 }, { "token": "analyze", "start_offset": 8, "end_offset": 15, "type": "<ALPHANUM>", "position": 3 } ] }
- token 是實(shí)際存儲(chǔ)到索引中的詞條。
- position 指明詞條在原始文本中出現(xiàn)的位置。
- start_offset 和 end_offset 指明字符在原始字符串中的位置。
IK分詞器
ES 的默認(rèn)分詞器無法識(shí)別中文中測(cè)試、單詞這樣的詞匯,而是簡單的將每個(gè)字拆完分為一個(gè)詞。這樣的結(jié)果顯然不符合我們的使用要求,所以我們需要下載 ES 對(duì)應(yīng)版本的中文分詞器。
-
下載
github下載地址:https://github.com/medcl/elasticsearch-analysis-ik
-
使用
將解壓后的后的文件夾放入 ES 根目錄下的 plugins 目錄下,重啟 ES 即可使用。
-
驗(yàn)證
GET http://localhost:9200/_analyze
-
請(qǐng)求
{ "text":"測(cè)試單詞", "analyzer":"ik_max_word" }
- ik_max_word:會(huì)將文本做最細(xì)粒度的拆分
- ik_smart:會(huì)將文本做最粗粒度的拆分
-
響應(yīng)
{ "tokens": [ { "token": "測(cè)試", "start_offset": 0, "end_offset": 2, "type": "CN_WORD", "position": 0 }, { "token": "單詞", "start_offset": 2, "end_offset": 4, "type": "CN_WORD", "position": 1 } ] }
-
-
自定義拓展詞匯
-
進(jìn)入 ES 根目錄中的 plugins 文件夾下的 ik 文件夾,進(jìn)入 config 目錄,創(chuàng)建 custom.dic文件,寫入{自定義拓展詞匯}。
-
打開 IKAnalyzer.cfg.xml 文件,將新建的 custom.dic 配置其中,重啟 ES 服務(wù)器。
-
自定義分析器
一個(gè)分析器就是在一個(gè)包里面組合了三種函數(shù)的一個(gè)包裝器, 三種函數(shù)按照順序被執(zhí)行:
-
字符過濾器
字符過濾器 用來 整理 一個(gè)尚未被分詞的字符串。例如,如果我們的文本是 HTML 格式的,它會(huì)包含像
<p>
或者<div>
這樣的 HTML 標(biāo)簽,這些標(biāo)簽是我們不想索引的。我們可以使用 html 清除 字符過濾器 來移除掉所有的 HTML 標(biāo)簽,并且像把 á 轉(zhuǎn)換為相對(duì)應(yīng)的 Unicode 字符 á 這樣,轉(zhuǎn)換 HTML 實(shí)體。一個(gè)分析器可能有 0 個(gè)或者多個(gè)字符過濾器。 -
分詞器
一個(gè)分析器 必須有一個(gè)唯一的分詞器。 分詞器把字符串分解成單個(gè)詞條或者詞匯單元。 標(biāo)準(zhǔn) 分析器里使用的 標(biāo)準(zhǔn) 分詞器 把一個(gè)字符串根據(jù)單詞邊界分解成單個(gè)詞條,并且移除掉大部分的標(biāo)點(diǎn)符號(hào),然而還有其他不同行為的分詞器存在。 例如,關(guān)鍵詞分詞器完整地輸出 接收到的同樣的字符串,并不做任何分詞。 空格分詞器只根據(jù)空格分割文本。正則分詞器根據(jù)匹配正則表達(dá)式來分割文本。
-
詞單元過濾器
經(jīng)過分詞,作為結(jié)果的詞單元流 會(huì)按照指定的順序通過指定的詞單元過濾器。詞單元過濾器可以修改、添加或者移除詞單元。我們已經(jīng)提到過lowercase和stop詞過濾器,但是在Elasticsearch里面還有很多可供選擇的詞單元過濾器。詞干過濾器 把單詞遏制為詞干。ascii_folding 過濾器移除變音符,把一個(gè)像"très"這樣的詞轉(zhuǎn)換為"tres"。ngram和edge_ngram 詞單元過濾器 可以產(chǎn)生適合用于部分匹配或者自動(dòng)補(bǔ)全的詞單元。
-
自定義的分析器
創(chuàng)建索引 PUT http://localhost:9200/my_index
-
請(qǐng)求
{ "settings": { "analysis": { "char_filter": { "&_to_and": { "type": "mapping", "mappings": [ "&=> and " ] } }, "filter": { "my_stopwords": { "type": "stop", "stopwords": [ "the", "a" ] } }, "analyzer": { "my_analyzer": { "type": "custom", "char_filter": [ "html_strip", "&_to_and" ], "tokenizer": "standard", "filter": [ "lowercase", "my_stopwords" ] } } } } }
使用analyze API來測(cè)試這個(gè)新的分析器 GET http://127.0.0.1:9200/my_index/_analyze
-
請(qǐng)求
{ "text":"The quick & brown fox", "analyzer": "my_analyzer" }
-
部分響應(yīng)
{ "tokens": [ { "token": "quick", "start_offset": 4, "end_offset": 9, "type": "<ALPHANUM>", "position": 1 }, { "token": "and", "start_offset": 10, "end_offset": 11, "type": "<ALPHANUM>", "position": 2 }, ... ] }
-
文檔處理
文檔沖突(為上述的更新流程案例)
當(dāng)我們使用 index API更新文檔,可以一次性讀取原始文檔,做我們的修改,然后重新索引整個(gè)文檔。最近的索引請(qǐng)求將獲勝:無論最后哪一個(gè)文檔被索引,都將被唯一存儲(chǔ)在Elasticsearch中。如果其他人同時(shí)更改這個(gè)文檔,他們的更改將丟失。
解決方式:加鎖
-
悲觀并發(fā)控制
這種方法被關(guān)系型數(shù)據(jù)庫廣泛使用,它假定有變更沖突可能發(fā)生,因此阻塞訪問資源以防止沖突。 一個(gè)典型的例子是讀取一行數(shù)據(jù)之前先將其鎖住,確保只有放置鎖的線程能夠?qū)@行數(shù)據(jù)進(jìn)行修改。
-
樂觀并發(fā)控制
Elasticsearch 中使用的這種方法假定沖突是不可能發(fā)生的,并且不會(huì)阻塞正在嘗試的操作。 然而,如果源數(shù)據(jù)在讀寫當(dāng)中被修改,更新將會(huì)失敗。應(yīng)用程序接下來將決定該如何解決沖突。 例如,可以重試更新、使用新的數(shù)據(jù)、或者將相關(guān)情況報(bào)告給用戶。
樂觀并發(fā)控制
當(dāng)我們之前討論 index ,GET 和 delete 請(qǐng)求時(shí),我們指出每個(gè)文檔都有一個(gè) _version (版本)號(hào),當(dāng)文檔被修改時(shí)版本號(hào)遞增。 Elasticsearch 使用這個(gè) version 號(hào)來確保變更以正確順序得到執(zhí)行。如果舊版本的文檔在新版本之后到達(dá),它可以被簡單的忽略。
我們可以利用 version 號(hào)來確保 應(yīng)用中相互沖突的變更不會(huì)導(dǎo)致數(shù)據(jù)丟失。我們通過指定想要修改文檔的 version 號(hào)來達(dá)到這個(gè)目的。 如果該版本不是當(dāng)前版本號(hào),我們的請(qǐng)求將會(huì)失敗。文章來源:http://www.zghlxwxcb.cn/news/detail-431208.html
老的版本 es 使用 version,但是新版本不支持了,會(huì)報(bào)下面的錯(cuò)誤,提示我們用 if_seq_no 和 if_primary_term文章來源地址http://www.zghlxwxcb.cn/news/detail-431208.html
到了這里,關(guān)于【Elasticsearch】幾點(diǎn)核心概念的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!