【Elasticsearch 7 探索之路】(三)倒排索引
上一篇,我們介紹了 ES 文件的基本 CURE 和批量操作。我們都知道倒排索引是搜尋引擎非常重要的一種資料結構,什麼是倒排索引,倒排索引的原理是什麼。
1 索引過程
在講解倒排索引前,我們先了解索引建立,下圖是 Elasticsearch 中資料索引過程的流程。
從上圖可以看到,文件未在 ES 中進行索引,而是 由 Analyzer 元件對其執行一些操作並將其拆分為 token/term。然後將這些術語作為倒排索引儲存在磁碟中。假設我們有兩個名為 name 和 age 欄位,當要將文件索引到 ES 時,Analyzers 元件 以某些定界符(有預設定界符,例如空格,句號等)將它們分割開獲取 token,再對每個 token 應用特定的過濾器。經過分析的這些標記稱為 term。然後將這些 term 針對該欄位)儲存在倒排列表中。
2 倒排索引
2.1 正排與倒排索引
一般在我們閱讀圖書,我們會根據目錄快速定位想要閱讀的章節,過了一段時間,你想要的回顧之前某一個知識點,你發現從目錄難以查詢到對應的地方,這時你可能就會從索引頁從去查詢對應內容索引,從而找到頁碼。
搜尋引擎其實跟我們的使用圖書很相似,下面我來對圖書和搜尋引擎進行一個簡單的類比,來看一下搜素引擎中正排和倒排索引。
- 圖書
- 正排索引-目錄頁
- 倒排索引-索引頁
- 搜尋引擎
- 正排索引-文件 Id 到文件內容和單詞的關聯
- 倒排索引-單詞到文件 Id 的關係
2.2 倒排索引的核心組成
舉個例子,假設我們有 3 個文件:
Doc 1:breakthrough drug for schizophrenia Doc 2:new schizophrenia drug Doc 3:new approach for treatment of schizophrenia
經過分析,檔案中的術語如下
文件 | 分詞結果 |
---|---|
Doc 1 | breakthrough,drug,for,schizophrenia |
Doc 2 | new,schizophrenia,drug |
Doc 3 | new,approach,for,treatment,of |
倒排列表的元資料結構:
(DocID;TF;<POS>)
其中:
DocID:出現某單詞的文件ID
TF(詞頻):單詞在該文件中出現的次數
POS:單詞在文件中的位置
則它們生成的倒排索引
單詞 | 逆向文件頻率 | 倒排列表(DocID;TF; |
---|---|---|
breakthrough | 1 | (1;1;<1>) |
drug | 2 | (1;1;<2>),(2;1;<3>) |
for | 2 | (1;1;<3>),(3;1;<3>) |
schizophrenia | 2 | (1;1;<4>),(2;1;<2>) |
new | 2 | (2;1;<1>),(3;1;<1>) |
approach | 1 | (3;1;<2>) |
treatment | 1 | (3;1;<4>) |
of | 1 | (3;1;<5>) |
ES 倒排索引包含兩個部分
- 單詞詞典 (Term Dictionary),索引最小單位,記錄所有文件的單詞,記錄單詞到倒排列表的關聯關係
- 單詞詞典一般都會非常多,通過 B+ 樹或 Hash 表方式以滿足高效能的插入與查詢
- 倒排列表(Posting List)-由倒排索引項(Posting)組成
- 文件 ID
- 詞頻 TF,該單詞在文件中出現的次數,用於相關性評分
- 位置(Position),單詞在文件中分詞的位置。用於語句搜尋(phrase query)
- 偏移(Offset),記錄單詞的開始結束位置,實現高亮顯示
- 單詞詞典 (Term Dictionary),索引最小單位,記錄所有文件的單詞,記錄單詞到倒排列表的關聯關係
ES 也可以指定對某些欄位不做索引
- 優點:節省儲存空間
- 缺點:欄位無法被搜尋
3 總結
在之前文章說了 ES 的文件是基於 JSON 格式,在我們建立索引的時候,對每一個文件記錄對應索引相關的資訊。在對倒排索引進行搜尋時,查詢單詞是否在單詞字典,獲取單詞在倒排列表的指標,獲取有該單詞單詞的文件 Id 列表,通過 ES 的倒排索引,我們輕易對全文進行快速搜素