ElasticSearch 倒排索引(Inverted Index)| 什麼是倒排索引?

Moshow鄭鍇發表於2020-04-07

什麼是倒排索引?

ElasticSearch中一個重要的概念 : 倒排索引(Inverted Index)也叫反向索引,有反向索引必有正向索引。通俗地來講,正向索引是通過key找value,反向索引則是通過value找key
在這裡插入圖片描述
首先弄懂幾個概念,如果類比現代漢語詞典的話,那麼Term就相當於詞語Term Dictionary相當於漢語詞典本身Term Index相當於詞典的目錄索引Posting List相當於詞語在字典的頁數集合

  • Term(單詞):一段文字經過分析器分析以後就會輸出一串單詞,這一個一個的就叫做Term(直譯為:單詞)
  • Term Dictionary(單詞字典):顧名思義,它裡面維護的是Term,可以理解為Term的集合
  • Term Index(單詞索引):為了更快的找到某個單詞,我們為單詞建立索引。B-Tree通過減少磁碟尋道次數來提高查詢效能,Elasticsearch也是採用同樣的思路,直接通過記憶體查詢term,不讀磁碟,但是如果term太多,term dictionary也會很大,放記憶體不現實,於是有了Term Index,就像字典裡的索引頁一樣,A開頭的有哪些term,分別在哪頁,可以理解term index是一顆樹:在這裡插入圖片描述
  • Posting List(倒排列表):倒排列表記錄了出現過某個單詞的所有文件的文件列表及單詞在該文件中出現的位置資訊,每條記錄稱為一個倒排項(Posting)。根據倒排列表,即可獲知哪些文件包含某個單詞。(PS:實際的倒排列表中並不只是存了文件ID這麼簡單,還有一些其它的資訊,比如:詞頻(Term出現的次數)、偏移量(offset)等,可以想象成是Python中的元組,或者Java中的物件)

倒排DEMO

{"doc_id"="1","hospitalName":"北京大學第三附屬醫院"}
{"doc_id"="2","hospitalName":"北京協和醫院"}
{"doc_id"="3","hospitalName":"解放軍總醫院第一附屬醫院"}
{"doc_id"="4","hospitalName":"Peking University Third Hospital"}
{"doc_id"="5","hospitalName":"Peking Union Medical College Hospital"}

*.<?>部分等你一邊思考一邊補充:

Term ID / 單詞ID Term / 單詞 Posting List /倒排列表(出現的id:位置:次數)
1 醫院 (1:<8>:1),(2:<4>:1),(3:<4>:2)
2 北京 (1:<0>:1),(2:<0>:1)
3 北京大學 (1:<0>:1)
4 第三 (1:<4>:1)
5 附屬 (1:<6>:1),(3:<8>:1)
6 協和 (2:<?>:1)
7 解放軍 (3:<?>:1)
8 第一 (3:<?>:1)
9 (3:<?>:1)

標準化規則(normalization)&命中率問題

為解決詞條檢索時詞條命中率,ES在建立倒排索引時運用標準化規則即針對儲存的索引詞條進行一些相關預處理再作為索引進行儲存。

例如:通常情況下,在搜尋 ThirdHospital 這兩個單詞時候,文件4兩個單詞都出現了,計數為2;文件5只有 Hospital 這個單詞出現了,計數為1,所以Total之後,文件4命中率高,排名靠前。

Term doc_id=4 doc_id=5
Third 1 0
Hospital 1 1
Peking 1 1
Total 3 2

但是這樣搜尋就會存在下列問題:

  1. Thirdthird 使用者認為是相同單詞,但是首字母小寫可能搜不到內容。
  2. hospitalshospital 有相同的詞根,如果儲存了 hospitals ,那麼 hospital 可能檢索不到 。
  3. pikingbeijing 為相同意思的詞,如果儲存了 pikingbeijing 可能檢索不到。

基於以上問題,ES在建立倒排索引時,會對拆分的各個單詞進行相應處理,以提升後面搜尋的時候能夠搜尋到相關聯的文件的概率,這就是標準化規則轉換,主要包括:時態的轉換(例如liked轉換為like)、單複數的轉換(hospitals轉換為hospitals)、同義詞的轉換(small轉換為little)、大小寫的轉換(預設轉換為小寫)。

標準分詞器standard analyzer

standard analyzer 標準分詞器中做的操作,跟標準化規則有一定關聯:

  • standard tokenizer:以單詞邊界進行切分
  • standard token filter:什麼都不做
  • lowercase token filter:將所有字母轉換為小寫(by normalization)
  • stop token filer(預設被禁用):移除停用詞,比如a the it等等

相關度分數score的計算

當利用ES進行查詢時,查詢結果都會返回一個對應詞條的相關度分數(score)。相關度分數的計算基於TF/IDF演算法(Term Frequence&Inverse Doucument Frequency),翻譯大意為:詞條在文件中出現的頻率及在倒排索引中出現的頻率。

  1. Term Frequence ,TF(t in f):我們查詢的詞條在文字中出現多少次,出現次數越多,相關度越高。例如:前面所列醫院資訊文件中,“醫院”,“北京大學”這兩個單詞,在第1文件中都出現了,但是第2和第3個文件只出現了“醫院”,所以第1個相關度分數高。
  2. Inverse Doucument Frequency,IDF(t in all-f):查詢詞條在所有文字中出現的次數,出現次數越高,相關度越低。例如:“醫院”在3個文件中出現4次,而“北京大學”出現1次,所以“醫院”這個單詞的相關度越低。
  3. Field-length(欄位長度規約):欄位的長度越長,相關度越低。例如:“北京大學第三附屬醫院”長度大於“北京協和醫院”,那麼在檢索“醫院”這個單詞時,第二個文件中分數要大於第一個文件的分數。

So,ES相關度分數計算結果直接影響搜尋排名順序,對使用者檢索命中率有極大的影響。

相關文章