轉載:https://blog.csdn.net/ghj1976/article/details/5586329
lucene的檢索算法屬於索引檢索,即用空間來換取時間,對需要檢索的文件、字符流進行全文索引,在檢索的時候對索引進行快速的檢索,得到檢索位置,這個位置記錄檢索詞出現的文件路徑或者某個關鍵詞。
lucene 在存儲它的全文索引結構時,是有層次結構的,這涉及到5個層次:索引(Index);段(Segment);文檔(Document);域(Field);詞(Term),他們的關系如下圖所示:(lucene 索引存儲結構概念圖)
下圖是Lucene生成的索引的一個實例,右邊是對這5個層次的描述:
Lucene的索引結構中,即保存了正向信息,也保存了反向信息。
所謂正向信息:
- 按層次保存了從索引,一直到詞的包含關系:索引(Index) –> 段(segment) –> 文檔(Document) –> 域(Field) –> 詞(Term)
- 也即此索引包含了那些段,每個段包含了那些文檔,每個文檔包含了那些域,每個域包含了那些詞。
- 既然是層次結構,則每個層次都保存了本層次的信息以及下一層次的元信息,也即屬性信息,比如一本介紹中國地理的書,應該首先介紹中國地理的概況,以及中國包含多少個省,每個省介紹本省的基本概況及包含多少個市,每個市介紹本市的基本概況及包含多少個縣,每個縣具體介紹每個縣的具體情況。
- 如上圖,包含正向信息的文件有:
- segments_N保存了此索引包含多少個段,每個段包含多少篇文檔。
- XXX.fnm保存了此段包含了多少個域,每個域的名稱及索引方式。
- XXX.fdx,XXX.fdt保存了此段包含的所有文檔,每篇文檔包含了多少域,每個域保存了那些信息。
- XXX.tvx,XXX.tvd,XXX.tvf保存了此段包含多少文檔,每篇文檔包含了多少域,每個域包含了多少詞,每個詞的字符串,位置等信息。
所謂反向信息:
- 保存了詞典到倒排表的映射:詞(Term) –> 文檔(Document)
- 如上圖,包含反向信息的文件有:
- XXX.tis,XXX.tii保存了詞典(Term Dictionary),也即此段包含的所有的詞按字典順序的排序。
- XXX.frq保存了倒排表,也即包含每個詞的文檔ID列表。
- XXX.prx保存了倒排表中每個詞在包含此詞的文檔中的位置。
段(Segment) 的控制策略
在建立索引的時候對性能影響最大的地方就是在將索引寫入文件的時候, 所以在具體應用的時候就需要對此加以控制:
Lucene默認情況是每加入10份文檔(Document)就從內存往index文件寫入並生成一個段(Segment) ,然后每10個段(Segment)就合並成一個段(Segment). 這些控制的變量如下:
IndexWriter屬性 | 默認值 | 描述 |
MergeFactory | 10 | 控制segment合並的頻率和大小 |
MaxMergeDocs | Int32.MaxValue | 限制每個segment中包含的文檔數 |
MinMergeDocs | 10 | 當內存中的文檔達到多少的時候再寫入segment |
MaxMergeDocs用於控制一個segment文件中最多包含的Document數.比如限制為100的話,即使當前有10個segment也不會合並,因為合並后的segment將包含1000個文檔,超過了限制。
MinMergeDocs用於確定一個當內存中文檔達到多少的時候才寫入文件,該項對segment的數量和大小不會有什么影響,它僅僅影響內存的使用,進一步影響寫索引的效率。