ElasticSearch關於倒排索引

在我們說倒排索引的時候讓我們先去了解一下什麼叫做正排索引

什麼是正排索引

在說倒排索引之前我們先說說什麼是正排索引。正排索引也稱爲"前向索引",它是創建倒排索引的基礎。
這種組織方法在建立索引的時候結構比較簡單,建立比較方便且易於維護;因爲索引是基於文檔建立的,若是有新的文檔加入,直接爲該文檔建立一個新的索引塊,掛接在原來索引文件的後面。若是有文檔刪除,則直接找到該文檔號文檔對應的索引信息,將其直接刪除。
他適合根據文檔ID來查詢對應的內容。但是在查詢一個keyword在哪些文檔裏包含的時候需對所有的文檔進行掃描以確保沒有遺漏,這樣就使得檢索時間大大延長,檢索效率低下。
比如有幾個文檔及裏面的內容,他正排索引構建的結果如下圖:
在這裏插入圖片描述
**優點:**工作原理非常的簡單。
**缺點:**檢索效率太低,只能在一起簡單的場景下使用。

什麼是倒排索引

在沒有搜索引擎時,我們是直接輸入一個網址,然後獲取網站內容,這時我們的行爲是:
document -> to -> words
通過文章,獲取裏面的單詞,此謂「正向索引」,forward index.
後來,我們希望能夠輸入一個單詞,找到含有這個單詞,或者和這個單詞有關係的文章:
word -> to -> documents
於是我們把這種索引,成爲inverted index,直譯過來,應該叫「反向索引」,國內翻譯成「倒排索引」,有點委婉了。
根據字面意思可以知道他和正序索引是反的。在搜索引擎中每個文件都對應一個文件ID,文件內容被表示爲一系列關鍵詞的集合(文檔要除去一些無用的詞,比如’的’這些,剩下的詞就是關鍵詞,每個關鍵詞都有自己的ID)。例如“文檔1”經過分詞,提取了3個關鍵詞,每個關鍵詞都會記錄它所在在文檔中的出現頻率及出現位置。
那麼上面的文檔及內容構建的倒排索引結果會如下圖(注:這個圖裏沒有記錄展示該詞在出現在哪個文檔的具體位置):
在這裏插入圖片描述

爲什麼需要倒排索引呢

倒排索引,也是索引。索引,初衷都是爲了快速檢索到你要的數據。
每種數據庫都有自己要解決的問題(或者說擅長的領域),對應的就有自己的數據結構,而不同的使用場景和數據結構,需要用不同的索引,才能起到最大化加快查詢的目的。
對 Mysql 來說,是 B+ 樹,對 Elasticsearch/Lucene 來說,是倒排索引。
Elasticsearch 是建立在全文搜索引擎庫 Lucene 基礎上的搜索引擎,它隱藏了 Lucene 的複雜性,取而代之的提供一套簡單一致的 RESTful API,不過掩蓋不了它底層也是 Lucene 的事實。Elasticsearch 的倒排索引,其實就是 Lucene 的倒排索引。

如何使用倒排索引

比如我們要查詢‘搜索引擎’這個關鍵詞在哪些文檔中出現過。首先我們通過倒排索引可以查詢到該關鍵詞出現的文檔位置是在1和3中;然後再通過正排索引查詢到文檔1和3的內容並返回結果。

倒排索引組成

倒排索引主要由單詞詞典(Term Dictionary)和倒排列表(Posting List)及倒排文件(Inverted File)組成。
他們三者的關係如下圖:
在這裏插入圖片描述

單詞詞典(Term Dictionary):搜索引擎的通常索引單位是單詞,單詞詞典是由文檔集合中出現過的所有單詞構成的字符串集合,單詞詞典內每條索引項記載單詞本身的一些信息以及指向“倒排列表”的指針。
倒排列表(PostingList):倒排列表記載了出現過某個單詞的所有文檔的文檔列表及單詞在該文檔中出現的位置信息及頻率(作關聯性算分),每條記錄稱爲一個倒排項(Posting)。根據倒排列表,即可獲知哪些文檔包含某個單詞。
倒排文件(Inverted File):所有單詞的倒排列表往往順序地存儲在磁盤的某個文件裏,這個文件即被稱之爲倒排文件,倒排文件是存儲倒排索引的物理文件。
在這裏插入圖片描述

單詞詞典查詢定位問題

對於一些規模很大的文檔集合來講,他裏面可能包括了上百萬的關鍵單詞(term),能否快速定位到具體單詞(term),這會直接影響到響應速度。
假設我們有很多個 term,比如:

Carla,Sara,Elin,Ada,Patty,Kate,Selena

如果按照這樣的順序排列,找出某個特定的 term 一定很慢,因爲 term 沒有排序,需要全部過濾一遍才能找出特定的 term。排序之後就變成了:

Ada,Carla,Elin,Kate,Patty,Sara,Selena

這樣我們可以用二分查找的方式,比全遍歷更快地找出目標的 term。這個就是 term dictionary。有了 term dictionary 之後,可以用 logN 次磁盤查找得到目標。但是磁盤的隨機讀操作仍然是非常昂貴的(一次 random access 大概需要 10ms 的時間)。所以儘量少的讀磁盤,有必要把一些數據緩存到內存裏。但是整個 term dictionary 本身又太大了,無法完整地放到內存裏。於是就有了 term index。term index 有點像一本字典的大的章節表。

目前常用的方式是通過hash加鏈表結構和樹型結構(b樹或者b+)。

hash加鏈表:

這是很常用的一種數據結構。這種方式就可以快速計算單詞的hash值從而定位到他所有在的hash表中,如果該表是又是一個鏈表結構(兩個單詞的hash值可能會一樣),那麼就需要遍歷這個鏈表然後再對比返回結果。這種方式最大的缺點就是如果有範圍查詢的時候就很難做到。

樹型結構:

B樹(或者B+樹)是另外一種高效查找結構,下圖是一個 B樹結構示意圖。B樹與哈希方式查找不同,需要字典項能夠按照大小排序(數字或者字符序),而哈希方式則無須數據滿足此項要求。
B樹形成了層級查找結構,中間節點用於指出一定順序範圍的詞典項目存儲在哪個子樹中,起到根據詞典項比較大小進行導航的作用,最底層的葉子節點存儲單詞的地址信息,根據這個地址就可以提取出單詞字符串。
在這裏插入圖片描述
這是我得微信公衆號:程序猿微刊 更多文章請關注微信公衆號
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章