倒排索引基礎

1.單詞-文檔矩陣

       通常檢索的場景是:給定幾個關鍵詞,找出包含關鍵詞的文檔。
      怎麼快速找到包含某個關鍵詞的文檔就成爲搜索的關鍵。這裏我們藉助單詞-文檔矩陣模型,通過這個模型我們可以很方便知道某篇文檔包含哪些單詞,某個單詞被哪些文檔所包含。

       搜索引擎的索引其實就是實現單詞-文檔矩陣的具體數據結構,具體可以包括:倒排索引、簽名文件、後綴樹等。常見的當然就是倒排索引了,lucene也是基於倒排索引實現的。

2.倒排索引

2.1.倒排索引的組成

         倒排索引通常有詞彙表和記錄表組成。
       詞彙表:文檔集合中所包含的不同單詞的集合。
       記錄表:對於詞彙表中的每一個單詞,包含這個單詞的文檔編號構成的一個列表(有可能還會保存些其他信息,例如單詞在文檔中的位置信息)。

2.2.使用倒排索引(檢索)

          這樣的結構怎麼用於檢索?
         通常我們將詞彙表和記錄表分開存儲,詞彙表文件中包含每個單詞指向記錄表文件的指針。先在詞彙表中找到需要檢索的單詞,然後取出對應的記錄表。如果查詢中只有一個單詞,取出記錄表即可,如果查詢中包含多個單詞,取出多個記錄表還需要做合併(交集或者並集)。
          死做結果肯定可以出來,但是這裏效率必須強調。怎麼快速的找到單詞然後獲取記錄表內容呢?如果你的詞表不是很大(主存可以容納得下),那麼排序數組、b樹、trie樹、散列都是可選的數據結構,散列速度肯定毋庸置疑,b樹、trie樹可以處理前綴查詢和範圍查詢。lucene中不考慮將整個詞表存入主存,他的詞表文件分成兩個,類似兩層跳躍表,中間採用二分查找。

2.3.建立索引

一般分成三種方式:

2.3.1.兩遍文檔遍歷方法(2-Pass In-Memory Inversion)

         這種方式完全是依賴內存的。第一遍掃描所有文檔,計算每個單詞的tf,然後計算所有單詞tf的總和,這個總和值直接關係到最終索引所需的內存大小。在內存中,建立有序數組用來存儲單詞,建立一塊連續的存儲空間(由tf總和控制)用來存儲倒排索引,並且每個單詞通過“指針”指向其對應的倒排列表其實位置。第二遍掃描就是建立每個單詞的倒排列表信息。當所有文檔掃面結束後,再以某種方式存儲起來。
        這種方式的缺點是:1)兩遍掃描,效率低下;2)完全依賴內存,對規模大點的文檔集無能爲力;3)不支持動態更新索引。

2.3.2.排序法(Sort-based Inversion)

        爲了解決兩遍文檔遍歷方法的缺陷,排序法只在內存中開闢固定大小的空間用來建立索引,當空間消耗光時將其寫入磁盤,然後清空內存空間對其他文檔進行索引,直至索引完全部文檔。排序法將單詞全部存儲在內存中,並且不停收集倒排項(倒排項包括:單詞id,文檔id,單詞頻率等信息),當空間消耗光時,對所有的倒排項按照單詞id、文檔id進行排序,排序好後將其寫入臨時文件。此時清空倒排項所佔用的內存空間,然後重複上述工作。注意單詞id是事先排好序的。在一開始,我們不會將全部的單詞加載進入內存,是在遍歷的過程中文檔中出現了才加入內存。因此隨着遍歷,單詞所佔用的空間越來越大,倒排項所佔用的空間越來越小,也就是說越到後面一次遍歷的文檔數量就越少,臨時文件也就越小。
       當遍歷完整個文檔集後,我們便得到了一堆的臨時文件(存儲了倒排項),接下來就要將這些文件進行“整合”。由於這些倒排項都排好序了,因此這個工作相對簡單,就是將同一個單詞的倒排項進行合併。

2.3.3.歸併法(Merge-based Inversion)

        排序法最致命的一個問題就是將全部單詞放到內存裏,如果單詞量特別大,以至於內存放不下那就望塵莫及了!歸併法可以很好的解決這個問題,歸併法也在內存中開闢一塊固定大小的空間,對於一篇文檔就將其轉換成標準的內存倒排索引結構,假設在內存空間的限制下,將n篇文檔建立好了單獨的內存倒排索引結構,然後進行合併形成一個索引段,寫入磁盤,清空內存。這裏的內存索引、索引段只是在文檔數量規模上有所區別,結構上完全一致。在這個過程中同樣需要對單詞進行排序,方便後期的合併。
        當遍歷完整個文檔集合後,我們同樣得到了一堆臨時文件(索引段),和排序法類似,我們將同一單詞的倒排列表進行合併即可。
        lucene採用的就是這種方式。

2.4.動態索引

       索引建立完成後,如果後期不需要對其進行調整(增、刪),那麼稱之爲靜態索引,反之爲動態索引。
       動態索引又將牽涉到實時索引(實時檢索)等問題,這裏不展開描述實時的問題。
       動態索引包含三個部分:磁盤索引文件、內存臨時索引、已刪除文檔列表。
       內存臨時索引和歸併法中的內存索引一個意思,將新加的文檔臨時放在內存中。以刪除文檔列表記錄刪除文檔的id。檢索時同時查詢磁盤索引文件和內存臨時索引,然後通過已刪除文檔列表進行過濾。當內存臨時索引達到一定閾值時將其合併到磁盤索引文件。

2.5.索引更新策略

     索引更新主要包括完全重新更新(Complete Re-build)和增量更新(再合併策略Re-Merge、原地更新策略In-Place)。lucene中使用的是Re-Merge策略。


重點:
1.詞彙表的存儲和查詢(數據結構)
排序數組、b樹、trie樹、散列



轉自:http://www.cnblogs.com/huangfox/archive/2012/07/18/2597603.html

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