在前兩篇,我們介紹了Lucene的存儲文件目錄中的各個文件的大致關系。比如以層次規則保存的正向信息:
索引–>段–>文檔–>域–>詞目錄–>segment_N–>.fdx,.fdt–>.fnm–>.tvx,.tvd,.tvf當然,除了正向信息之外,還包括反向信息,以及和Lucene系統相關的一些特定的信息,現在,我們來一一了解。
其實上述文件的關系相對而言嚴格來說是不準確的,因為segment文件其實存儲的是段的元數據信息,是每個Index一個,但是段的真正的內容被存儲在域和詞之中。
段的元數據信息: 一個索引可以內存儲在多個不同的segment中,然而,當我們要打開索引的時候,則必須要打開一個索引文件,并且只能選擇一個,那么我們要如何去選擇呢?
Lucene的解決方案是這個樣子的:
在所有的segment_N的文件中選擇N最大的文件打開,基本思路是參照SegmentInfos.getCurrentSegmentGeneration(File[] files), 其基本思路是在所有的以segment為前綴的文件中選擇N最大的文件作為genA,當然,這里排除了segments.gen文件;第二,打開segments.gen,其中保存了當前的N值,其格式如下,讀出版本號(version),然后再讀出兩個N,如果相等,則作為genB.其三,對比genA和genB,選擇其中N大的那個,然后打開對應的segments_N;| Version | gen0 | gen1 |
|---|
代碼:
IndexInput getInput = directory.openInput(IndexFileName.SEGMENTS_GEN);int version = genInput.readInt();if (version == FORMAT_LOCKLESS) { long gen0 = genInput.readLong(); long gen1 = genInput.readLong(); if (gen0 == gen1) { genB = gen0; }} Format 索引文件版本號,隨著Lucene開發的不斷進行而不斷變大,當IndexReader是由A版本創建,但是卻讀取B版本的索引時,其會出錯;Version 索引的版本號,記錄了IndexWriter的修改提交次數,初始值一般從索引文件中讀出,被賦予一個初始時間,隨后每一次對索引的修改都會導致此版本號變更,在Lucene中,一般用此來判斷當前是否為最新的修改后的索引;IndexReader被創建后,當再次讀的時候一般會對此進行比較,當IndexReader自己保存的version和當前索引的Version相同時,表示當前索引沒有被修改過,是最新的,直接讀取不會出錯。NameCount 是下一個新段的段名,所有屬于同一個段的索引文件都以段名作為文件名,新生成的段名一般是當前最大段名加一。SegCount個段的元數據信息: SegName 段名,所有屬于同一個段的文件都以段名來命名文件SegSize 此段中包含的文檔數,包含已被刪除,但又沒有optimize的文檔;DelGen .del文件版本號,在重新optimize之前,被刪除的文件都被包含在.del文件中;每次IndexWriter對索引進行刪除之后,該值都會自增1,并且會生成一個新的.del文件;……未完待續
新聞熱點
疑難解答