ElasticSearch 學習筆記

簡介

ES是一款基于Lucene實現(xiàn)的一款分布式搜索引擎,它有以下優(yōu)點

  • Restful API,接入不需要編程語言支持
  • 數(shù)據(jù)安全(主從)
  • 功能豐富
  • 接近實施的更新

Lucene

Lucene是一個由Java實現(xiàn)的搜索引擎,接下來簡要介紹下它的原理

1.倒排索引

倒排索引是搜索引擎常用的一種索引方式。
它十分簡單,首先將需要索引的語句進行分詞,然后以每個詞為key,需要索引的語句為value放入一個"MAP"中.
這里MAP之所以打引號,是因為我們不去限制這個MAP的實現(xiàn)方法,他可以用任意實現(xiàn),比如紅黑樹,hash或者之后會介紹的FST。

舉個例子:
需要索引的句子:

1.ElasticSearch 學習筆記
2.ElasticSearch 牛逼

倒排索引:

"ElasticSearch" : [1,2],
"學習" :[1]
"筆記" : [1]
"牛逼" : [2]

通過倒排索引,我們就能通過單個當詞語查詢到句子。

2.FST

FST全稱是Finite State Transducer,
單從字面上看它類似于有限自動機,但實際可以把它看作一個壓縮過但字典樹,
字典樹會對詞語對前綴進行合并,而FST還會對詞語對后綴進行合并。
我們以mon,thurs,tues三個詞為例,
FST和字典樹的結(jié)構(gòu)分別如下:


字典樹

FST

優(yōu)點:內(nèi)存占用率低,壓縮率一般在3倍~20倍之間、模糊查詢支持好、查詢快
缺點:結(jié)構(gòu)復雜、輸入要求有序、更新不易

如何構(gòu)建一個FST?
  1. 將所有的句子按照字典序進行排序
  2. 將句子先按照字典樹的方式插入
  3. 如果確定有相同的后綴,則進行鏈接。
    具體原理可參考:https://www.shenyanchao.cn/blog/2018/12/04/lucene-fst/

3.怎么存儲倒排索引?(猜的)

一部分緩存在內(nèi)存,一部分存在硬盤。
當FST當一個前綴有超過一定數(shù)量當后綴則放到內(nèi)存中,否則存入磁盤。
真的是這樣??

ES 與 Lucene 當關系

ES 的結(jié)構(gòu)

ES是一個分布式服務,它由n個分片和m個備份構(gòu)成,分片(P)和備份(R)被分配在不同的機器(Node)上,


ES
分片

一個分片里指存儲了部分集群信息,具體存哪些則根據(jù)文檔的routing字段決定(默認就是_id)
而一個分片上包含以下結(jié)構(gòu):

  • 多個段(你可以把段理解為倒排索引)
  • commit point,用于找到多個段
  • In-memory buffer,用來收集更新信息
  • transLog,類似與mysql的binLog,用于記錄更新操作
分片
為什么要有多個段?

一個段相當于一個Lucene,那為什么要有多個段?
因為Lucene的倒排索引采用FST實現(xiàn),F(xiàn)ST雖然高效,并且內(nèi)存利用率高,但是更新困難。因此與其每次花大代價去更新原來的段,不如每次都新建一個段,之后索引時,遍歷所有的段,并得出搜索結(jié)果。

但是這樣做有兩個問題:

  1. 隨著段越來越多,搜索的效率會大大降低。
  2. 寫入一個新的段需要IO操作,因此如果頻繁寫入,那么效率底下。

為了解決問題1,ES啟動了一個后臺的合并任務,他會在空閑時把這些段合并成一個大段。(類似于LevelDB的level合并機制)
為了解決問題2,ES使用In-memory buffer在內(nèi)存中緩存新接受的更新請求。隔一段時間將這些請求整理成一個段,再將這個段放入系統(tǒng)段文件緩存中(注意不立即寫入磁盤)。同時將每一個更新操作寫入Translog當中,保證數(shù)據(jù)的持久性。當文件緩存中當段真正被寫入磁盤后,清除Translog即可。

怎樣把一個句子存入ES

首先我們得有一個句子,比如 "ES是=_=世界上最牛逼的搜索引擎",
ES通過句子的_id找到需要被存儲的分片位置,將該句子發(fā)送過去,
之后這個句子會被解析器進行解析。(在ES中有許多解析器,你可以根據(jù)需求定義字段對應的解析器)

  1. 首先這個句子首先經(jīng)過剔除特殊字符的解析器:

變成 => "ES是世界上最牛逼的搜索引擎"

  1. 經(jīng)過剔除無用字的解析器:

變成 => "ES世界牛逼搜索引擎"

3.經(jīng)過分詞的解析器

變成 => ['ES','世界','牛逼','搜索','引擎']

4.經(jīng)過同義詞添加的解析器

變成 => ['ES','ElasticSearch','世界','牛逼','厲害','狠','搜索','查找','引擎']

ES將經(jīng)解析的詞和句子做成倒排索引,然后通過上一節(jié)所講的方式存入磁盤。

如何進行搜索(match)

這個問題看起來很難,實則很簡單。

  1. 首先ES會將輸入的句子,通過上一節(jié)講的解析器,分解成多個詞。
  2. 將每個詞通過倒排索引找到包含的句子
  3. 將這些包含關鍵詞的句子收集起來,通過詞語命中次數(shù),命中種類,詞頻,詞權(quán)重等進行打分(ES提供了多種打分方法,但是常用的方法是詞頻/逆向文檔頻率(term frequency/inverse document frequency)
  4. 將打好分的句子,通過分數(shù)排序,然后取前N個返回給用戶。

以上講解的是對于match方法背后的步驟,當然實際并非這么簡單,了解原理就好。
當然term搜索也是ES中常用的一種搜索方式,它與match不同,他必須精確匹配。ES優(yōu)化term操作,為它添加了緩存,具體方法就是通過一個稀疏的數(shù)組來存儲命中的term節(jié)點,在將這個數(shù)組存入緩存中

中文分詞

IK 分詞器,
1、詞典樹Tire Tree的構(gòu)建,即將現(xiàn)在的詞典加載到一個內(nèi)存結(jié)構(gòu)中去
2、詞的匹配查找,就是切詞
3、歧義判斷,即對不同切分方式的判定,哪種應是更合理的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容