Lucene核心數據結構——FST存詞典,跳表存倒排或者roarning bitmap 見另外一個文章


Lucene實現倒排表沒有使用bitmap,為了效率,lucene使用了一些策略,具體如下:
1. 使用FST保存詞典,FST可以實現快速的Seek,這種結構在當查詢可以表達成自動機時(PrefixQuery、FuzzyQuery、RegexpQuery等)效率很高。(可以理解成自動機取交集)
此種場景主要用在對Query進行rewrite的時候。
2. FST可以表達出Term倒排表所在的文件偏移。
3. 倒排表使用SkipList結構。從上面的討論可知,求倒排表的交集、並集、差集需要各種SeekTo(docId),SkipList能對Seek進行加速。

 

skiplist備忘

   如今大部分工具使用的倒排鏈已經不是簡單的鏈表了。一個常用,比如lucene中用的,叫skiplist,是一種高效的鏈表結構,在查詢、添加、刪除的時間復雜度上做到O(logN)。數據結構如下圖:

查詢的過程很簡單,從頂層開始,往后查詢遇到節點的next()比待查的大或者到NIL了,節點不變下移一層繼續向后查詢,如此反復,直到到了底層還沒查到。skiplist的資料也比較多,這里就不贅述了。

 

鏈表集合操作

   直接引用轉述這篇博文:http://www.cnblogs.com/forfuture1978/archive/2010/04/04/1704258.html  。作者很細致地把過程都列出來了,真是方便了大家啊,建議順着讀一邊。

    鏈表集合求交 

      lucene中用的是ConjunctionScorer ,大致過程是每條倒排鏈不斷的推進到小於等於當前最大節點的位置。當然實現細節還是很豐富的,作者很細心的把過程都列出來了,建議順着讀一邊。這里摘抄部分:

首先把倒排鏈按第一個next排序:

    

查看0~7的倒排鏈的第一個和最后一個是否相同,不同就開始找;取最后一個倒排的第一個元素8作為終點, 第一個鏈表開始找8

第0個鏈表 跳過1到了10,那么8也不用找了都去找10就行了

第1根鏈表找到了11,那么10也不用找了,找11,之后都這么做

......

之后遇到11,本次交集操作找到一個11,

  后續的計算也是同理,當然整個代碼實現會比較復雜和討巧。基本思路就是每條倒排鏈能根據當前文檔迅速跳過不符合的docid,由於倒排鏈可以用skiplist查詢,因此即使很長的倒排鏈,如果交集的數量很少,整個求解過程可以很快跳過不需要比較的節點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM