5分鐘瞭解lucene全文索引

 

1、Lucene介紹及應用

Apache Lucene是當下最爲流行的開源全文檢索工具包,基於JAVA語言編寫。算法

目前基於此工具包開源的搜索引擎,成熟且廣爲人知的有Solr和Elasticsearch。2010年後Lucene和Solr兩個項目由同一個Apache軟件基金會的開發團隊製做,因此一般咱們看到的版本都是同步的。兩者的區別是Lucene是工具包,而Solr是基於Lucene製做的企業級搜索應用。另外,咱們經常使用的Eclipse,幫助系統的搜索功能也是基於Lucene實現的。數據庫

2、Lucene的兩項工做

在咱們的生活物品中,漢語字典與全文索引是很類似的。咱們拿拼音查字法舉例,首先咱們經過拼音找到咱們要查字的頁數,而後翻到該頁,閱讀這個字的詳細解釋。工具

在上面的例子中,咱們提到了兩個要素:一個是字典,另外一個是查字的過程。對應到Lucene的功能上,一個是咱們要創建一個字典,這個過程叫作創建索引,另外一個是根據搜索詞基於索引進行查詢。ui

2.1 創建索引

1)文檔的準備(Document)搜索引擎

文檔就是指咱們要去搜索的原文。設計

2)分詞組件(Tokenizer)blog

將第一步的文檔進行詞語切割,去除標點,去除無用詞,好比「是」,「的」等。經常使用的開源中文分詞組件有MMSEG4J、IKAnalyzer等。切割後的詞語咱們稱爲詞元(Token)。排序

3)語言處理(Linguistic Processor)索引

將上一步的得到的詞元進行處理,好比英文的大寫轉小寫,複數變單數,過去時分詞轉原形等。此時獲得的結果,被稱做詞(Term)ip

4)索引組件

索引組件將上步獲得的詞,生成索引和詞典,存儲到磁盤上。索引組件先將Term變成字典,而後對字典進行排序,排序後對相同的詞進行合併,造成倒排列表。每一個詞在列表中存儲了對應的文檔Id(Document Frequency)以及這個詞在這個文檔中出現了幾回(Term Frequency)。

2.2 搜索

1)輸入查詢詞

2)詞法分析及語言處理

對輸入的詞進行拆分,關鍵字識別(AND,NOT)等。對拆分的詞元進行語言處理,與創建字典時語言處理的過程相同。由關鍵字與處理後的詞生成語法樹。

3)搜索索引,得到符合語法樹的文檔

如A and B not C造成的語法樹,則會搜索包含A B C的文檔列表,而後用A和B的文檔列表作交集,結果集與C作差集,獲得的結果,就是符合搜索條件的文檔列表

4)根據相關性,對搜索結果排序

經過向量空間模型的算法,獲得結果的相關性。比較簡單的實現描述以下:在創建索引的時候,咱們獲得了Document Frequency和Term Frequency,Term Frequency越高,說明文檔的相關性越高;Document Frequency越高,說明相關性越弱。這個算法能夠本身進行實現。

5)根據上面的排序結果,返回文檔。

3、索引結構

Lucene的索引結構是有層次結構的。咱們如下圖爲例

3.1 索引(Index)

若是拿數據庫作類比,索引相似於數據庫的表。

在Lucene中一個索引是放在一個文件夾中的。因此能夠理解索引爲整個文件夾的內容。

3.2 段(Segment)

若是拿數據庫作類比,段相似於表的分區。

索引下面引入了Segment 的概念,一個索引下能夠多個段。當flush或者commit時生成段文件。截圖中有0,1兩個段。segments.gen和segments_5是段的元數據文件,它們保存了段的屬性信息。其餘的文件對應的就是各段的文件,稍後會詳細說明各文件的用處。

索引的寫入是順序的,只能被追加,不能被修改。當索引要刪除時,在.del文件中寫入對應的docId。查詢的時候會過濾到此docId。另外索引的修改,是對Document進行刪除後作的追加。這種設計保證了高吞吐量。

分段的設計能保證查詢的高效,當段太大時,查詢會產生很大的IO消耗。段過小,則須要查詢的段太多。因此lucene對段進行了合併,另外刪除的數據也是在合併過程當中過濾掉的。4.0以前的默認的合併策略爲LogMergePolicy,這個策略會合並小於指定值的相鄰段,若是兩個相鄰段,一個大小爲1G,一個大小爲1k,則會重寫1G的文件會佔用很大資源。4.0以後默認策略改成了TieredMergePolicy,這個策略會先按分段大小進行排序,對段進行刪除比計算,優先合併小的分段。當系統閒暇的時候,纔對大分段進行合併。

3.3 文檔(Document)

若是拿數據庫作類比,文檔相似於數據的一行。

Document是索引的基本單位。一個段能夠有多個Document

3.4 域(Field)

若是拿數據庫作類比,域至關於表的字段。

Doument裏能夠有多個Field。Lucene提供多種不一樣類型的Field,例如StringField、TextField、LongFiled或NumericDocValuesField等。

3.5 詞(Term)

Term是索引的最小單位。Term是由Field通過Analyzer(分詞)產生。

4、段的文件說明

第三章節詳細描述了段的設計和合並策略,如下詳細講解一些段文件的內容。

segments_N保存了此索引包含多少個段,每一個段包含多少篇文檔。

*.fnm

保存了此段包含了多少個域,每一個域的名稱及索引方式。

*.fdx,*.fdt

保存了此段包含的全部文檔,每篇文檔包含了多少域,每一個域保存了那些信息。

*.tvx,*.tvd,*.tvf

保存了此段包含多少文檔,每篇文檔包含了多少域,每一個域包含了多少詞,每一個詞的字符串,位置等信息。

*.tis,*.tii

保存了詞典(Term Dictionary),也即此段包含的全部的詞按字典順序的排序。

*.frq

保存了倒排表,也即包含每一個詞的文檔ID列表。

*.prx

保存了倒排表中每一個詞在包含此詞的文檔中的位置

*.del

前面講段的時候有提到,用來是存儲刪掉文檔id的。

做者:田梁

來源:宜信技術學院

相關文章
相關標籤/搜索