Lucene 6.5.1

建立一个Lucene示例

数据写入

public class Writer {private static final String PATH = "";public static void main(String[] args) throws Exception {String doc1 = "hello world";// 创建IndexWriterDirectory d = FSDirectory.open(Paths.get(PATH));IndexWriterConfig conf = new IndexWriterConfig(new SimpleAnalyzer());IndexWriter indexWriter = new IndexWriter(d, conf);// 把要创建的索引的文本数据放入Document中Document ducument1 = new Document();ducument1.add(new TextField("id", "1", Field.Store.YES));ducument1.add(new TextField("title", "doc1", Field.Store.YES));ducument1.add(new TextField("content", doc1, Field.Store.YES));// 通过IndexWriter把Document写入indexWriter.addDocument(ducument1);indexWriter.commit();indexWriter.close();}
}

这里的** Path**便是我们索引文件的存储路径。在上面的示例中生成的索引文件如下:

nvd&&nvm

nvd&&nvm用来存储域的标准化值(normalization values),这两个索引文件记录了每一篇文档中每一种域的标准化值跟索引信息。

pos&&pay

position在Lucene中描述的是一个term在一篇文档中的位置,并且存在一个或多个position。

doc

索引文件.doc中按块(block)的方式存放了每一个term的文档号、词频,并且保存skip data来实现块之间的快速跳转。

payload是一个自定义的元数据(mete data)来描述term的某个属性,term在一篇文章中的多个位置可以一一对应多个payload,也可以只有部分位置带有payload。

offset是一对整数值(a pair of integers),即startOffset跟endOffset,它们分别描述了term的第一个字符跟最后一个在文档中的位置。

每一个term在所有文档中的position、payload、offset信息在IndexWriter.addDocument()的过程中计算出来,在内存中生成一张倒排表,最终持久化到磁盘时,通过读取倒排表,将position信息写入到.pos文件中,将payload、offset信息写入到.pay文件中。

tim&&tip

.tim(TermDictionary)文件中存放了每一个term的TermStats,TermStats记录了包含该term的文档数量,term在这些文档中的词频总和;另外还存放了term的TermMetadata,TermMetadata记录了该term在.doc、.pos、.pay文件中的信息,这些信息即term在这些文件中的起始位置,即保存了指向这些文档的索引;还存放了term的Suffix,对于有部分相同前缀值的term,只需存放这些term不相同的后缀值,即Suffix。

.tip文件中存放了指向tim文件的索引来实现随机访问tim文件中的信息,并且.tip文件还能用来快速判断某个term是否存在。

dim&&dii

从Lucene6.0开始出现点数据(Point Value)的概念,通过将多维度的点数据生成KD-tree结构,来实现快速的单维度的范围查询(比如 IntPoint.newRangeQuery)以及N dimesional shape intersection filtering。

liv

索引文件.liv只有在一个segment中包含被删除的文档时才会生成,它记录了当前段中没有被删除的文档号。

tvx&&tvd

当设置了TermVector的域生成了倒排表以后,将文档的词向量信息写到.tvx(vector_index)跟.tvd(vector_data)文件中。

fdx&&fdt

当STORE.YES的域生成了倒排表以后,将文档的域值信息写入到.fdt(field data)、.fdx(field index)文件中。

si

当生成一个新的segment时(执行flush、commit、merge、addIndexes(facet)),会生成一个描述段文件信息(segmentInfo)的.si索引文件。

fnm

索引文件.fnm用来描述域信息(FieldInfo)

segments_N

当IndexWriter执行commit()操作后,会生成一个segments_N文件,该文件描述了当前索引目录中所有有效的段信息文件(active segment info),即之前文章介绍的segmentInfo文件,仅仅通过flush()生成的段成为无效的段信息文件。

索引目录中可能存在多个Segments_N文件,每个Segment_N文件代表某次commit()时的索引状态,其中N值最大的Segments_N文件代表最新的一次提交,它包含当前索引目录中所有的索引信息。

cfs&&cfe

索引文件.cfs、.cfe被称为复合(compound)索引文件,在IndexWriterConfig可以配置是否生成复合索引文件,默认开启。

索引的层次结构

索引(Index)

Lucene中每个索引都是放在同一个文件夹中,文件夹中的所有文件构成一个索引。

段(Segment)

如图中的Segment_8,该文件保存的段的元数据信息,每个索引包含了多个段,在段的数据过多时会发生合并。这里还有一个比较重要的文件Segment.gen文件,该文件存在的目的是当存在多个segment_N时如何选择打开哪一个。Lucene会选择generation最大的。

The active segments in the index are stored in the segment info file, segments_N. There may be one or more segments_N files in the index; however, the one with the largest generation is the active one
(when older segments_N files are present it’s because they temporarily cannot be deleted, or a custom {@link IndexDeletionPolicy} is in use). This file lists each segment by name and has details about the codec and generation of deletes.

Lucene索引有至少1个Segment组成,每个seg又包含多个索引文件。位于同一个Seg的文件具有相同的前缀和不同的后缀。在上图中包含了一个Segments_8,这是如果indexriter有写入修改请求时会对Segment_9进行操作。

增量索引(Incremental Indexing)

Lucene采用的增量索引的模式写入文件,即每次索引新的文件都会放在一个新的段中,然后周期性的对以前的段进行合并。

文档(Document)

  • 索引的基本单位
  • 新添加的文档都是单独保存在一个新生成的段中。
    要索引的数据记录、文档在lucene中的表示,是索引、搜索的基本单元。一个Document由多个字段Field构成。IndexWriter按加入的顺序为Document指定一个递增的id(从0开始),称为文档id。反向索引中存储的是这个id,文档存储中正向索引也是这个id。 业务数据的主键id只是文档的一个字段。

Document主要由一组IndexableFields构成,除了提供添加和删除的接口外,在Doc内部提供了各种API用于获取Doc内部的Fields。

Class IndexableField

其为一个接口,包含了字段名,字段值,字段类型。

public interface IndexableField {// field名字String name();// 字段类型IndexableFieldType fieldType();// 下面的API都是获取各种字段值的接口。TokenStream tokenStream(Analyzer var1, TokenStream var2);/** @deprecated */@Deprecatedfloat boost();BytesRef binaryValue();String stringValue();Reader readerValue();Number numericValue();
}

其中字段类型主要有以下几个内容:

  • stored:是否存储
  • tokenized:是否分词。
  • omitNorms:是否忽略标准化。
  • indexOptions:如何索引。
  • storeTermVectors:是否存储词项向量。
  • storeTermVectorOffset: 词项向量中是否存储偏移量。
  • storeTermVectorPositions: 词项向量中是否存储偏位置。
  • storeTermVectorPaykoads: 词项向量中是否存储偏附加信息。

域(Field)

  • 一篇文档包含不同类型的信息,可以分开索引,比如标题,时间,正文,作者等,
    都可以保存在不同的域里。
  • 对于同一个Field来说,也会有不同的索引方式。比如说在ElasticSearch中,对一个double[]的属性进行存储,这时候的默认索引成两种形式,其中一种是DoublePoint另一种是SortedNumiecDocValue。

Lucene预定义的字段字类

  • TextField:会自动被索引和分词的字段。一般被用在文章的正文部分。
  • StringField:会被索引,但是不会被分词,即会被当作一个完整的token处理,一般用在“国家”或者“ID”。
  • IntPoint/LongPoint/FloatPoint/DoublePoint:范围查询,ES默认数字的类型包含数组都会保存一份该类型的存储。
  • SortedDocValuesField:通常用于排序,ES的数组默认也会保存一份DocValue的存储,本义是在一个文档中存在同一个field的多值情况,但是我们通过DocValue来获取该field数据时,其顺序相对于输入时改变的,且无法获取原始次序。
  • SortedSetDocValuesField:同上
  • NumericDocValuesField:针对field的只存在单值的情况。
  • SortedNumericDocValuesField:同上的上
  • SortedField: 一个默认会被存储的Field:这是行存的结构,默认是不开启的,且这中存储方式的效率比较低。

示例

public final class StringField extends Field {/** Indexed, not tokenized, omits norms, indexes*  DOCS_ONLY, not stored. */public static final FieldType TYPE_NOT_STORED = new FieldType();/** Indexed, not tokenized, omits norms, indexes*  DOCS_ONLY, stored */public static final FieldType TYPE_STORED = new FieldType();static {TYPE_NOT_STORED.setOmitNorms(true);TYPE_NOT_STORED.setIndexOptions(IndexOptions.DOCS);TYPE_NOT_STORED.setTokenized(false);TYPE_NOT_STORED.freeze();TYPE_STORED.setOmitNorms(true);TYPE_STORED.setIndexOptions(IndexOptions.DOCS);TYPE_STORED.setStored(true);TYPE_STORED.setTokenized(false);TYPE_STORED.freeze();}/*************************************/}

以上的StringField的源码,在static中定义了作为field的相关的属性。

词(Term)

词是索引的最小单位,是经过词法分析和语言处理后的字符串。主要包含了两个成员:field也就是域名,另一个就是所对应的域值,在lucene中文本值都是以ByteRef的形式存储的

 String field;BytesRef bytes;

索引信息

在Lucene中不仅保存了正向信息也保存了反向信息。

  • 正向信息:索引(Index) –> 段(segment) –> 文档(Document) –> 域(Field) –> 词(Term), 比如说StoredValue这种就是正向信息查询的。
  • 反向信息:词(Term) –> 文档(Document),也就是Lucene的核心倒排索引。

Lucene随笔-Lucene的索引文件格式相关推荐

  1. lucene索引文件格式

    学习lucene索引文件格式的目的是通过对lucene数据结构的理解,从而为lucene索引实现打下基础. 索引文件的整体结构 如下图,这是整个索引文件的整体结构,可以看到,实际上lucene索引保存 ...

  2. Lucene学习总结之三:Lucene的索引文件格式(1)

    Lucene的索引里面存了些什么,如何存放的,也即Lucene的索引文件格式,是读懂Lucene源代码的一把钥匙. 当我们真正进入到Lucene源代码之中的时候,我们会发现: Lucene的索引过程, ...

  3. Lucene学习总结之三:Lucene的索引文件格式(2)

    2019独角兽企业重金招聘Python工程师标准>>> 四.具体格式 上面曾经交代过,Lucene保存了从Index到Segment到Document到Field一直到Term的正向 ...

  4. Lucene源代码之信息索引

    索引是什么?索引是一种数据存储和组织结构. 逆常人之思维,lucene索引采用倒排文件索引构造索引系统.具体实现原理举例说明: 假设有3篇文章,file1,file2,file3,文件内容如下: fi ...

  5. Lucene 02 - Lucene的入门程序(Java API的简单使用)

    目录 1 准备环境 2 准备数据 3 创建工程 3.1 创建Maven Project(打包方式选jar即可) 3.2 配置pom.xml, 导入依赖 4 编写基础代码 4.1 编写图书POJO 4. ...

  6. 【Lucene】Lucene的使用和优化

    从程序的实现层面上来学习Lucene的使用和优化 前提: Lucene使用时有7个包需要导入:analysis,document,index,queryParser,search,store,util ...

  7. 【Lucene】Lucene的工作原理

    Lucene是一个高性能的java全文检索工具包,它使用的是倒排文件索引结构.该结构及相应的生成算法如下: 0)设有两篇文章1和2 文章1的内容为:Tom lives in Guangzhou,I l ...

  8. Apache Lucene与Lucene.Net——全文检索服务器

    lucene学习教程 1.1 什么是lucene Lucene是一个全文搜索框架,而不是应用产品.因此它并不像www.baidu.com 或者google Desktop那么拿来就能用,它只是提供了一 ...

  9. u-boot移植随笔:System.map文件格式

    u-boot移植随笔:System.map文件格式 背景:正在努力看u-boot代码,已经研究了两三天,内容太多,一时难理清头绪.不过有一定的linux基础,也懂点gnu扩展,elf格式,连接器还没有 ...

最新文章

  1. 20172304 《程序设计与数据结构》第九周学习总结
  2. 为什么说python是世界上最好的语言-Python才是世界上最好的语言
  3. shell的学习和命令使用入门
  4. php ip 合法,什么是合法ip地址
  5. java comparator内部类_java - Java Comparator使用.reverseOrder()但内部类 - 堆栈内存溢出...
  6. 操作系统之进程管理:2、进程的状态以及状态转化
  7. 5G多输入多输出技术,到底是个啥东东?
  8. Redmi K40系统截图曝光:配备顶级2K屏幕+骁龙870移动平台
  9. 蓝桥杯2015 C语言大学B组 C/C++
  10. Sublime Text3插件管理
  11. Python中图像标题生成的注意机制实战教程
  12. iphone开发每日一练【2011-10-06】
  13. 对梯度概念的直观理解
  14. 计算机游戏设计师要学什么软件,从事游戏设计工作需要学什么专业
  15. python工程师工资一般多少-Python工程师的薪资到底有多高
  16. 数据分享|多变量多元多项式曲线回归线性模型分析母亲吸烟对新生婴儿体重影响可视化...
  17. latex 行内公式和行间公式高亮问题、多行高亮问题
  18. Seatunnel提交任务到Flink集群源码解析
  19. 【java初学】面向对象了解
  20. 显著性物体检测与分割

热门文章

  1. J2EE与javaweb的区别
  2. 利用thinkphp创建一个简单的站点
  3. 在不同的paste网站上搜索泄漏的凭据Scavenger
  4. (4.2.12.3)浅谈第三方推送[bug查询]:百度推送、小米推送、华为推送
  5. FreeCAD-0.19源码编译教程
  6. 快消供应链管理解决方案
  7. Time Out“全球超酷街区”榜单新鲜出炉
  8. 网络爬虫-破解顶象滑块验证码
  9. ios12完美深色模式插件_看了微信的暗黑模式后,我也适配了一波安卓!
  10. python学习日记(2)——变量|字符串|数字布尔类型