1.lucene整体结构如下图:
2.正向信息
2.1段的元数据信息segments_N
segments_N的具体格式如下图:
1) Format:
(1)索引文件格式的版本号。
(2) 由于 Lucene 是在不断开发过程中的,因而不同版本的 Lucene,其索引文件格式也不尽相同,于是规定一个版本号。
(3)Lucene 2.1 此值-3,Lucene 2.9时,此值为-9。
(4)当用某个版本号的 IndexReader读取另一个版本号生成的索引的时候,会因为此值不同而报错。
2)Version:
(1) 索引的版本号,记录了 IndexWriter 将修改提交到索引文件中的次数。
(2)其初始值大多数情况下从索引文件里面读出,仅仅在索引开始创建的时候,被赋予当前的时间,已取得一个唯一值。
(3)其值改变在
IndexWriter.commit->IndexWriter.startCommit->SegmentInfos.prepareCommit->SegmentInfos.wr
ite->writeLong(++version)
(4)其初始值之所最初取一个时间,是因为我们并不关心 IndexWriter 将修改提交到索引的具体次数,而更关心到底哪个是最新的。IndexReader 中常比较自己的 version
和索引文件中的 version 是否相同来判断此 IndexReader 被打开后,还有没有被IndexWriter 更新。
3) NameCount
(1) 是下一个新段(Segment)的段名。
(2)所有属于同一个段的索引文件都以段名作为文件名,一般为_0.xxx, _0.yyy, _1.xxx, _1.yyy ……
(3) 新生成的段的段名一般为原有最大段名加一。
(4) 如同的索引,NameCount读出来是2,说明新的段为_2.xxx, _2.yyy
4)SegCount
段(Segment)的个数。
5)SegCount个段的元数据信息:
(1)SegName
((1)段名,所有属于同一个段的文件都有以段名作为文件名。 第一个段的段名为"_0",第二个段的段名为"_1"
(2)SegSize
((1)此段中包含的文档数
((2) 然而此文档数是包括已经删除,又没有 optimize 的文档的,因为在 optimize之前, Lucene的段中包含了所有被索引过的文档,而被删除的文档是保存在.del
文件中的,在搜索的过程中,是先从段中读到了被删除的文档,然后再用.del中的标志,将这篇文档过滤掉。
(3)DelGen
((1).del文件的版本号
((2)Lucene中,在 optimize 之前,删除的文档是保存在.del文件中的。
((3)在 Lucene 2.9中,文档删除有以下几种方式:
IndexReader.deleteDocument(int docID)是用 IndexReader 按文档号删除。
IndexReader.deleteDocuments(Term term)是用 IndexReader 删除包含此词(Term)的文档。
IndexWriter.deleteDocuments(Term term)是用 IndexWriter 删除包含此词(Term)的文档。
IndexWriter.deleteDocuments(Term[] terms)是用 IndexWriter 删除包含这些词(Term)的文档。
IndexWriter.deleteDocuments(Query query)是用 IndexWriter 删除能满足此查询(Query)的文档。
IndexWriter.deleteDocuments(Query[] queries)是用 IndexWriter 删除能满足这些查询(Query)的文档。
原来的版本中Lucene的删除一直是由IndexReader来完成的,在Lucene 2.9中虽可以用IndexWriter来删除,但是其实真正的实现是在IndexWriter中,保存了 readerpool,当 IndexWriter 向索引文件提交删除的时候,仍然是从readerpool中得到相应的 IndexReader,并用 IndexReader来进行删除的。
((4)DelGen 是每当 IndexWriter 向索引文件中提交删除操作的时候,加 1,并生成新的.del 文件。
(4)DocStoreOffset
(5)DocStoreSegment
(6)DocStoreIsCompoundFile
((1)对于域(Stored Field)和词向量(Term Vector)的存储可以有不同的方式,即可以每个段(Segment)单独存储自己的域和词向量信息,也可以多个段共享域和词向
量,把它们存储到一个段中去。
((2)如果 DocStoreOffset 为-1,则此段单独存储自己的域和词向量,从存储文件上来看,如果此段段名为XXX,则此段有自己的XXX.fdt, XXX.fdx, XXX.tvf, XXX.tvd,
XXX.tvx文件。DocStoreSegment和 DocStoreIsCompoundFile 在此处不被保存。
((3) 如果 DocStoreOffset 不为-1,则 DocStoreSegment 保存了共享的段的名字,比如为 YYY,DocStoreOffset 则为此段的域及词向量信息在共享段中的偏移量。
则此段没有自己的 XXX.fdt,XXX.fdx,XXX.tvf,XXX.tvd,XXX.tvx 文件,而是将信息存放在共享段的 YYY.fdt,YYY.fdx,YYY.tvf,YYY.tvd,YYY.tvx 文件中。
(7)HasSingleNormFile
在搜索的过程中,标准化因子(Normalization Factor)会影响文档最后的评分。
不同的文档重要性不同,不同的域重要性也不同。因而每个文档的每个域都可以有自己的标准化因子。
如果HasSingleNormFile 为1,则所有的标准化因子都是存在.nrm文件中的。
如果HasSingleNormFile 不是 1,则每个域都有自己的标准化因子文件.fN
(8)NumField
域的数量
(9)NormGen
如果每个域有自己的标准化因子文件,则此数组描述了每个标准化因子文件的版本号,也即.fN 的N。
(10)IsCompoundFile
((1)是否保存为复合文件,也即把同一个段中的文件按照一定格式,保存在一个文件当中,这样可以减少每次打开文件的个数。
((2) 是否为复合文件,由接口 IndexWriter.setUseCompoundFile(boolean)设定。
6)User map data
保存了用户从字符串到字符串的映射 Map<String,String>
7)CheckSum
此文件 segment_N 的校验和。