ES倒排索引基本原理

索引(index)可以分為正序索引(Forward Indexes)和倒排索引(Inverted Index)兩種。在關係型資料庫中使用索引可以避免資料檢索走全表掃描,將檢索的時間複雜度從O(n)降到了O(logn)。例如,一本字典在開篇幾頁記錄了每個字和所在頁碼的對映關係,當我們需要查閱某個字的時候不需要從每一頁開始搜尋,通過這個對映關係就能快速找到需要搜尋的詞項。假設現在有三個文件:doc1, doc2, doc3

doc1: Welcome to Hotel California

doc2: Welcome to the heaven

doc3: the dog is very cute

在關係型資料庫中儲存這三個文件並且建立索引,文件在資料庫中的儲存結構大概如下所示

Doc ID Doc Content
1 Welcome to Hotel California
2 Welcome to the heaven
3 the dog is very cute

通過建立這種文件id與文件內容的對映關係,在關係型資料庫中可以快速查詢到文件的具體位置,但是如果需要對文件中某些詞項進行檢索,則需要進行全表掃描,這個時候正序索引就失效了。

倒排索引的思想是建立文件中每個詞項與文件的的對映關係,如下所示

Term Doc Id
welcome Doc1, Doc2
to Doc1,Doc2
the Doc2,Doc3
dog Doc3
heaven Doc2
.... ...

可以看出通過倒排索引,搜尋任意一個詞項都能快速定位到所在位置。通過上述例子可以看出順序索引是文件ID與文件內容和單詞的關聯,倒排索引是單詞到文件ID的對映關係。

倒排索引核心組成

倒排索引主要包括兩部分:單詞詞典和倒排列表。

  • 單詞詞典:記錄所有文件的單詞,記錄單詞和倒排列表的關聯關係
  • 倒排列表:記錄單詞與對應文件集合,由倒排索引項組成
    • 倒排索引項:主要由文件ID,詞頻TF(單詞在文件中出現的次數,用於相關性評分),位置(Position,單詞在文件中分詞的位置,用於語句搜尋) ,偏移(Offset,記錄單詞的開始結束位置,用於實現高亮顯示)

Elaticsearch的JSON文件中每個欄位都有自己的倒排索引,可以對文件中不需要搜尋的欄位不做索引,這樣可以節省儲存空間