【读书笔记】Lucene分析与应用

来源:互联网 发布:node解决跨域问题 编辑:程序博客网 时间:2024/04/30 01:24

文本分析

Document-文档,field-域,term-项,term是一个二元组<FieldName, Text>,field也可以表示为一个二元组<Name, Value>,document是field的集合,field是term的集合。

Lucene 的文本分析过程

文档à空格à停用词à词或词组à词干à标引

token的构造并不复杂,包括起始字符位置和结束字符位置,保存单词的字符值。

StandardAnalyzer标准解析器依靠标准分词器(StandardTokenizer)将输入的文本解析为token流。

创建索引内存中创建索引

Lucene选用段索引和倒排索引结构来完成标引(Indexing)过程。每添加一个Document,就创建一个segment索引。

Lucene索引的保存常用类:DirectoryIndexOutputIndexInput,它们在Lucene中分为针对硬盘的FS*类和针对内存的RAM*类。

Lucene有几个重要的写入类:IndexWriterDocumentWriterFieldWriterTermInfoWriter,它们的主要方法是addDocument,通过这个方法它们相互调用,添加documentFieldterm各个层面索引信息。

Lucene创建索引分为两步:在内存中创建索引,合并索引到磁盘中。

创建Document层面索引:document类的属性有两个:vector来存储fieldfloat类型来保存boost数值。postingTable保存了termdocument内频率信息(某个document包含这个term的个数),DocumentWriterIndexWriter的构建类似,也需要分词器,索引保存目录等约束条件。

写入field信息FieldInfos是容器类,添加记录是通过add方法调用addInternal方法将Field信息加入的。FieldInfo保存field的特性信息。

文件倒排à由DocumentWriterinvertDocument方法来完成。建立document的倒排,需要知道如下信息:

1)       某个term对应的document的编号

2)       term的频率信息:tf – 某个document包含该term的个数,docFreq –问集中包含该termdocument个数。

document的倒排过程可以认为是记录term位置信息的过程。

填写postingTableàaddPosition方法

postingTable的排序àDocumentWriter在写入索引前,按照字典顺序对term排序:快速排序

写入field的名字文件à FieldInfoswrite方法

写入field信息文件àFieldWriteraddDocument方法

写入频率与位置文件à

TermVector方式写入索引àTermVectorsWriter构造函数, addTerm, addTermInternal, closeDocument,

字典文件(.tis.tii文件)àTermInfosWriter

写入规格化文件àNormsWriter

索引合并索引合并

IndexWriteraddDocument调用maybeFlushRamSegments将内存中的索引合并保存到磁盘中。

document层面的合并:IndexWritermergeSegments方法,会调用SegmentMerger中的方法

fieldterm的合并:SegmentMergermergeFieldsmergeTerm

合并norm信息:SegmentMergermergeNorms方法

Lucene索引的压缩算法

Ø  front coding(端部编码):若相邻的term包含共同字符,则后面一个term只保存不同的字符与相同字符的长度

Ø  variable-byte coding(变长字节编码):对正整数变长字节的编码方式采用这种压缩,被编码的数值从低到高取出7位填写入一个byte中,若被编码的数值没有取尽,便在这个字节的第8位填写1,表明会再有8bit来表示,如此反复直到数值全部表达结束。若在取7位的过程中,已经将数值取尽,字节的最高位为0

Ø  delta-codingdelta-encoding:差分压缩

查询过程查询模型与引擎预热

查询模型

Ø  向量模型相似度,余弦值

Ø  布尔模型集合论与布尔代数

Ø  Lucene的评分(score)方式查询词汇的逻辑设置上采用布尔模型,在评估查询语句与Document之间的符合程度时用向量模型

查询简单事例

Ø  引擎预热,找到索引文件,打开索引,调整索引指针的位置

Ø  构建查询器

Ø  构建与标引时相同的文本解析器

Ø  构建查询解析器

Ø  解析查询语句,判断查询语句逻辑结构(语法树)

Ø  查询过程,找到Query term在索引中保存的频率,计算documentquery的相似度,取top K

引擎预热

Ø  获得索引文件名前缀读取segment_Nsegment.gen文件

n  indexReaderopen方法,FSDirectory中的getDirectory方法

n  SegmentInfosrun方法是获取Segment信息的过程

n  SegmentInfosgetCurrentSegmentGeneration方法和generationFromSegmentsFileName:从segment_N得到segment的创建次数

n  FindSegmentsFiledoBody方法:对索引加载IndexReader

n  SegmentInfosread方法:获得segment层面的索引信息

n  FSDirectoryopenInput打开索引

Ø  获得field名称与field特性读取.fnm文件

n  FieldInfosread方法

Ø  得到字典文件结构与分组点term信息(.tii)读取到内存读取.tis文件头部信息

n  TermInfosReader:获得term信息

n  SegmentTermEnum:读取字典文件信息

Ø  得到频率信息计算相似度,位置信息在结果展示中高亮显示查询term –得到.prx.frq文件句柄

查询过程查询解析与语法

构建查询解析器

Lucene没有构建自己的词法分析器,而是借助JavaCC完成了对查询语句的解析

查询语法

Ø  项(Term)查询:用户的查询条件会被分解成“项Term”和“操作符”两大类,Term又分成单一的词和短语

Ø  域(Field):可以指定要查询某一个Field的内容(field:term),也可以不指定,则默认。

Ø  词条查询(Term Modifier

n  通配符查询:?, *

n  模糊查询:Lucene采用Levenshtein DistanceEdit Distance实现了模糊查询的功能,用户只要在查询条件的最后使用~即可

n  间距查询:支持词与词之间指定间隔距离的查询

n  范围查询

n  权重查询

布尔表达式:OR, AND, NOT

组合查询:使用圆括号来组合不同的子查询语句

针对field的组合查询

转义字符(Escaping Special Character

查询语法树的构建过程

Ø  过程分析:对用户的查询语句进行解析,返回一个Query对象。Lucene提供QueryParser类依照语法树完成对查询语句的解析,Query方法

n  构建clause容器

n  返回查询对象

n  term之间的逻辑关系

n  构建clause子句

n  把构建的clause子句放入clause容器

n  对查询内容进行循环解析匹配

n  判断当前的term是什么类型,如果term为空,就提取下一个term的标识号

n  如果遇到查询关键字,就不处理

原创粉丝点击