ElasticSearch關於倒排索引

2021-10-05 23:06:27 字數 2385 閱讀 6522

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

在說倒排索引之前我們先說說什麼是正排索引。正排索引也稱為"前向索引",它是建立倒排索引的基礎。

這種組織方法在建立索引的時候結構比較簡單,建立比較方便且易於維護;因為索引是基於文件建立的,若是有新的文件加入,直接為該文件建立乙個新的索引塊,掛接在原來索引檔案的後面。若是有文件刪除,則直接找到該文件號文件對應的索引資訊,將其直接刪除。

他適合根據文件id來查詢對應的內容。但是在查詢乙個keyword在哪些文件裡包含的時候需對所有的文件進行掃瞄以確保沒有遺漏,這樣就使得檢索時間大大延長,檢索效率低下。

比如有幾個文件及裡面的內容,他正排索引構建的結果如下圖:

優點工作原理非常的簡單。

缺點檢索效率太低,只能在一起簡單的場景下使用。

通過文章,獲取裡面的單詞,此謂「正向索引」,forward index.

後來,我們希望能夠輸入乙個單詞,找到含有這個單詞,或者和這個單詞有關係的文章:

word -> to -> documents倒排索引,也是索引。索引,初衷都是為了快速檢索到你要的資料。

每種資料庫都有自己要解決的問題(或者說擅長的領域),對應的就有自己的資料結構,而不同的使用場景和資料結構,需要用不同的索引,才能起到最大化加快查詢的目的。

對 mysql 來說,是 b+ 樹,對 elasticsearch/lucene 來說,是倒排索引。

elasticsearch 是建立在全文搜尋引擎庫 lucene 基礎上的搜尋引擎,它隱藏了 lucene 的複雜性,取而代之的提供一套簡單一致的 restful api,不過掩蓋不了它底層也是 lucene 的事實。elasticsearch 的倒排索引,其實就是 lucene 的倒排索引。

倒排索引主要由單詞詞典(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值可能會一樣),那麼就需要遍歷這個鍊錶然後再對比返回結果。這種方式最大的缺點就是如果有範圍查詢的時候就很難做到。

樹型結構:

關於elasticsearch在系統架構中的位置

最近由於專案的原因,開始接觸到es。在使用和學習的過程中,不斷的產生著各種疑問讓我略顯迷茫。所以開始撰寫這篇部落格來記錄和推進自己對elasticsearch的學習。就現在而言,題目可能起的有點過於大。對於還並不算合格的程式設計師的我來說,談架構還為時尚早。但我希望在這篇文章終結的時候,自己能夠成長...

關於ElasticSearch搜尋效果的問題分析

如何聚合多個節點或分片的資料生成返回結果?es是如何將相關度高的內容能放在前面的?在對mysql進行分庫分表的時候,經常會遇到乙個問題 如果查詢的資料分散在多張表中,因為涉及到組合多種表的資料,將會非常麻煩 對於有些分頁場景,更是乙個災難,所以對mysql分庫分表的時候經常會基於查詢維度來盡量避免跨...

關於ElasticSearch的一些膚淺的思考

1.文章背景 初次研究elasticsearch,關於其中的 集群 節點 主分片 從分片 索引 型別 文件 字段 這幾個概念,分析它們之間的主從關係。通過閱讀文件以及檢視例項,有了一點自己的心得體會。現在此做一下描述,如有不確之處,歡迎批評指正。2.本文不做討論的內容 本文僅對於 集群 節點 主分片...