lucene的索引文件2

Lucene保存了从Index到Segment到Document到Field一直到Term的正向信息,也包括了从Term到Document映射的反向信息,还有其他一些Lucene特有的信息。下面对这三种信息一一介绍。

正向信息:

index-->segments(segment,.gen,segment_N)-->Field(fnm,fdx,fdt)-->Term(tvx,tvd,tvf)segments.gen和segments_N保存的是段(segment)的元数据信息(metadata),其实是每个Index一个的,而段的真正的数据信息,是保存在域(Field)和词(Term)中的.

段的元数据信息(segment_N):

我们要打开一个索引的时候,我们必须要选择一个来打开,那如何选择哪个segments_N呢?

Lucene采取以下过程:

  • 其一,在所有的segments_N中选择N最大的一个。基本逻辑参照SegmentInfos.getCurrentSegmentGeneration(File[] files),其基本思路就是在所有以segments开头,并且不是segments.gen的文件中,选择N最大的一个作为genA。
  • 其二,打开segments.gen,其中保存了当前的N值。其格式如下,读出版本号(Version),然后再读出两个N,如果两者相等,则作为genB。

如下图是segments_N的具体格式:

  • Format:
  1. 索引文件格式的版本号
  2. 由于Lucene是在不断的开发中,因而不同的版本的lucene,其索引文件的格式也不尽相同,于是规定一个版本号。
  3. lucene2.1该值为-3,lucene2.9该值为-9.
  4. 当用某个版本号的indexReader读取了另一个版本号生成的索引的时候,会因为值不同而报错。
  • Version
  1. 索引的版本号,记录了indexWriter将修改提交到索引文件中的次数。
  2. 其初始值大多数情况下从索引文件里面读出,仅仅在索引开始创建的时候,被赋予当前的时间,已取得一个唯一值。
  3. 其职改变在indexWriter.commit-->indexWriter.startCommit-->segmentinfos.prepareCommit-->segmentinfos.write-->writeLong(++version)
  4. 其初始值之所最初一个时间,因为我们不关心indexwriter将修改提交到索引的具体次数,而更关心到底那个是最新的(最后被修改的)。indexwriter中常比较自己的version和索引文件中的version是否相同来判断此indexReader被打开后,还有没有被indexWriter更新。
  • NameCount
  1. 是下一个新段(segment)的段名。
  2. 所有属于同一个段的索引文件都以段名作为文件名,一般为_0.xxx,_0.yyy......
  3. 新生成的段的段名一般为原有最打断名+1.
  4. 如下索引,nameCount读出来的是2,说明是新的段位_2.xxx,_2.yyy.

  • segCount
  1. 段的个数。
  2. 如上图,segcount=2
  • segCount个段的元数据信息
  1. segName:段名,所有属于同一个段的文件都有以段名作为文件名。eg:上图第一个段名为“_0”,第二个段名为“_1”
  2. segSize:此段中包含的文档数;a,然而此文档数十包括已经被删除又没有optimize的文档,因为在optimize之前,lucene的断中包含了所有被索引的文档,而被删除的文档是保存在.del文件中。在搜索过程中读到了被删除的文档,然后再用.del中的标志,将这篇文档进行过滤。
  3. 下面的代码生成了上面的索引图,可以看出索引了两篇文档形成了_0段,然后又删除了其中的一篇形成了_0_1.del,又索引了两篇文档形成了_1段,

形成了_1_1.del,因而在两个断中,此值都为2。

IndexWriter writer = new IndexWriter(FSDirectory.open(INDEX_DIR), new StandardAnalyzer(Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED); 
writer.setUseCompoundFile(false); 
indexDocs(writer, docDir);//docDir中只有两篇文档

//文档一为:Students should be allowed to go out with their friends, but not allowed to drink beer.

//文档二为:My friend Jerry went to school to see his students but found them drunk which is not allowed.

writer.commit();//提交两篇文档,形成_0段。

writer.deleteDocuments(new Term("contents", "school"));//删除文档二 
writer.commit();//提交删除,形成_0_1.del 
indexDocs(writer, docDir);//再次索引两篇文档,Lucene不能判别文档与文档的不同,因而算两篇新的文档。 
writer.commit();//提交两篇文档,形成_1段 
writer.deleteDocuments(new Term("contents", "school"));//删除第二次添加的文档二 
writer.close();//提交删除,形成_1_1.del

  • DelGen
  1. .del文件的版本号
  2. 在lucene中,在optimize之前,删除的文档是保存在.del文件中的。
  3. 使用indexReader和indexWriter进行删除文档:IndexReader.deleteDocuments(Term term)是用IndexReader删除包含此词(Term)的文档。使用indexWriter底层也是使用indexReader实现的。IndexWriter.deleteDocument(Term t)...
  4. DelGen是每当indexWriter向索引文件中提交删除操作的时候,+1,并生成新的.del文件。

IndexWriter.commit()

-> IndexWriter.applyDeletes()

-> IndexWriter$ReaderPool.release(SegmentReader)

-> SegmentReader(IndexReader).commit()

-> SegmentReader.doCommit(Map)

-> SegmentInfo.advanceDelGen()

-> if (delGen == NO) { 
                              delGen = YES; 
                           } else { 
                              delGen++; 
                           }

生成新的.del文件:

  • 域的元数据信息

一个段(Segment)包含多个域,每个域都有一些元数据信息,保存在.fnm文件中,.fnm文件的格式如下:

  • FNMVersion

    • 是fnm文件的版本号,对于Lucene 2.9为-2
  • FieldsCount
    • 域的数目
  • 一个数组的域(Fields)
    • FieldName:域名,如"title","modified","content"等。
    • FieldBits:一系列标志位,表明对此域的索引方式
      • 最低位:1表示此域被索引,0则不被索引。所谓被索引,也即放到倒排表中去。

        • 仅仅被索引的域才能够被搜到。
        • Field.Index.NO则表示不被索引。
        • Field.Index.ANALYZED则表示不但被索引,而且被分词,比如索引"hello world"后,无论是搜"hello",还是搜"world"都能够被搜到。
        • Field.Index.NOT_ANALYZED表示虽然被索引,但是不分词,比如索引"hello world"后,仅当搜"hello world"时,能够搜到,搜"hello"和搜"world"都搜不到。
        • 一个域出了能够被索引,还能够被存储,仅仅被存储的域是搜索不到的,但是能通过文档号查到,多用于不想被搜索到,但是在通过其它域能够搜索到的情况下,能够随着文档号返回给用户的域。
        • Field.Store.Yes则表示存储此域,Field.Store.NO则表示不存储此域。
      • 倒数第二位:1表示保存词向量,0为不保存词向量。
        • Field.TermVector.YES表示保存词向量。
        • Field.TermVector.NO表示不保存词向量。
      • 倒数第三位:1表示在词向量中保存位置信息。
        • Field.TermVector.WITH_POSITIONS
      • 倒数第四位:1表示在词向量中保存偏移量信息。
        • Field.TermVector.WITH_OFFSETS
      • 倒数第五位:1表示不保存标准化因子
        • Field.Index.ANALYZED_NO_NORMS
        • Field.Index.NOT_ANALYZED_NO_NORMS
      • 倒数第六位:是否保存payload
时间: 2024-10-10 13:43:48

lucene的索引文件2的相关文章

Solr4.8.0源码分析(10)之Lucene的索引文件(3)

Solr4.8.0源码分析(10)之Lucene的索引文件(3) 1. .si文件 .si文件存储了段的元数据,主要涉及SegmentInfoFormat.java和Segmentinfo.java这两个文件.由于本文介绍的Solr4.8.0,所以对应的是SegmentInfoFormat的子类Lucene46SegmentInfoFormat. 首先来看下.si文件的格式 头部(header) 版本(SegVersion) doc个数(SegSize) 是否符合文档格式(IsCompoundF

Solr4.8.0源码分析(12)之Lucene的索引文件(5)

Solr4.8.0源码分析(12)之Lucene的索引文件(5) 1. 存储域数据文件(.fdt和.fdx) Solr4.8.0里面使用的fdt和fdx的格式是lucene4.1的.为了提升压缩比,StoredFieldsFormat以16KB为单位对文档进行压缩,使用的压缩算法是LZ4,由于它更着眼于速度而不是压缩比,所以它能快速压缩以及解压. 1.1 存储域数据文件(.fdt) 真正保存存储域(stored field)信息的是fdt文件,该文件存放了压缩后的文档,按16kb或者更大的模块大

Solr4.8.0源码分析(11)之Lucene的索引文件(4)

Solr4.8.0源码分析(11)之Lucene的索引文件(4) 1. .dvd和.dvm文件 .dvm是存放了DocValue域的元数据,比如DocValue偏移量. .dvd则存放了DocValue的数据. 在Solr4.8.0中,dvd以及dvm用到的Lucene编码格式是Lucene45DocValuesFormat.跟之前的文件格式类似,它分别包含Lucene45DocValuesProducer 和Lucene45DocValuesConsumer来实现该文件的读和写. 1 @Ove

Solr4.8.0源码分析(8)之Lucene的索引文件(1)

Solr4.8.0源码分析(8)之Lucene的索引文件(1) 题记:最近有幸看到觉先大神的Lucene的博客,感觉自己之前学习的以及工作的太为肤浅,所以决定先跟随觉先大神的博客学习下Lucene的原理.由于觉先大神主要介绍的是Lucene3.X系的,那我就根据源码以及结合觉先大神的来学习下4.X系的.内容可能会有些变化,且加入下我个人的理解. http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623597.html 一. 基本类型

Solr4.8.0源码分析(9)之Lucene的索引文件(2)

Solr4.8.0源码分析(9)之Lucene的索引文件(2) 一. Segments_N文件 一个索引对应一个目录,索引文件都存放在目录里面.Solr的索引文件存放在Solr/Home下的core/data/index目录中,一个core对应一个索引. Segments_N例举了索引所有有效的segments信息以及删除的具体信息,一个索引可以有多个Segments_N,但是有效的往往总是N最大的那个,为什么会出现多个segments_N,主要是由于暂时无法删除它们或者有indexwriter

lucene的搜索过程(索引文件)

---恢复内容开始--- 搜索的过程总的来说就是将词典及倒排表信息从索引中读出来,根据用户的查询语句合并倒排表,得到结果文档集并对文档进行打分的过程. 如图: 总共包含以下几个过程: index打开索引文件,读取并打开指向索引文件的流. 用户输入查询语句. 将查询语句转为查询对象Query对象树.(从luke中可以看出来) 构造weight对象树,用于计算词的权重,也即计算打分公司中与搜索语句有关,与文档无关的部分(红色部分). 构造Score对象树,用于计算打分. 在构造score对象树的过程

利用Lucene测试索引生成的segment.fnm文件所包含的内容(详解)

/* * * 这段代码用来测试文件segment.fnm文件所包含的内容 * .fnm包含了Document中的所有field名称  * */ 生成的索引文件.fnm中所包含了Document的所有Field名称. 如图就是生成索引,打开所显示的文件. package segment; import java.io.IOException; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache

Lucene实现索引和查询

0引言 随着万维网的发展和大数据时代的到来,每天都有大量的数字化信息在生产.存储.传递和转化,如何从大量的信息中以一定的方式找到满足自己需求的信息,使之有序化并加以利用成为一大难题.全文检索技术是现如今最普遍的信息查询应用,生活中利用搜索引擎,在博客论坛中查找信息,这些搜索的核心原理就是本文要实现的全文检索技术.随着文档信息数字化的实现,将信息有效存储并及时准确的提取是每一个公司.企业和单位要做好的基础.针对英文的全文检索已经有很多成熟的理论和方法,开放源代码的全文检索引擎Lucene 是Apa

lucene创建索引以及索引文件合并

1 package test; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.nio.file.Path; 6 import java.util.ArrayList; 7 import java.util.List; 8 import java.util.Map; 9 10 import org.apache.lucene.analysis.standard.StandardAnalyzer; 11 im