Lucene原理

Download Report

Transcript Lucene原理

最关心的一些问题:
1. Lucene是一个怎样的系统
2. Lucene可以干嘛
3. Lucene的原理
谭望达
Lucene具有类似于XML的文件格式
Document
Field1
Token
Field2
Token
Token
Token
<Title>
蜗居
</Title>
<Abstract>
反映了房价居高不下, 官商勾结,
与年轻人买房难的一些故事
</Abstract >
<Content>
...
</Content>
Lucene解析器的优势:
1. 扩展性好, 可以随意定制, 可以解析任意格式文档
2. Lucene自带的包中已经有很多现成的解析器了
Jode IS a dog
Analyzer
jode \ dog
Jode \ IS \ a \ dog
Tokenizer
TokenFilter
我们需要做的就是把原类继承, 实现其方法即可
Lucene的基本类型
 Byte: 是最基本的类型,长8位(bit)。
 UInt32:由4个Byte组成。
 UInt64:由8个Byte组成。
 VInt: 变长的整形
 Chars: 是UTF-8编码的一系列Byte。
 Strings: 一个字符串首先是一个VInt来表示此
字符串包含的字符的个数,接着便是UTF-8编
码的字符序列Chars

前缀-后缀规则(Prefix+Suffix)

差值规则

或然跟随规则(A, B?)

跳跃表规则



一个词典(比如四库全书)如果太大, 怎么办呢?
一部电视剧(比如西游记)如果太长怎么办呢?
一部游戏(魔兽世界)如果太好玩怎么办呢?

那么一个索引如果太复杂怎么办呢?
对了, 这就是段索引,所有的段索引组成
了一个完整的索引!
Fields
.Fnm文件
.Fdx文件
.Fdt文件
指针
Lucene索
引文件结
构
Postings
字典
.tis文件
频率
.frq文件
位置
.prx文件
规则化
.f(n)文件
Segments
.segments文件
指针
.tii文件


Lucene的索引合并是Lucene的一个非常经
典的内容
常见的合并索引的方式:
 1. 每加入一篇文章就重新生成索引 (代价好高!)
 2. 或者增量索引, 也就是每加入一篇文章就对索
引进行修改, (代价也不小!)

可以说, 评价一个搜索引擎的好坏, 可以看
看他对增加删除文档的支持程度如何

Lucene的索引宏观合并过程如下
一篇文档
一篇文档
一篇文档
………
在内存中
到达了一个阈值, Lucene默认为10
内存中生成索引
并写入磁盘(段索引)
重复这个过程…
一段索引
一段索引
一段索引
………
在磁盘中

Lucene的索引宏观合并过程如下(续)
一段索引
一段索引
一段索引
………
在磁盘中
到达了一个阈值, Lucene默认为10
启动合并过程

Lucene的索引微观合并过程如下
启动合并过程
合并前的准备
合并Field
…
tis
fnm
fdx
再Hash, 重新完成
合并Posting
归并排序, 重构跳跃表

Lucene的索引合并创新之处
大部分的搜索引擎(数
据库)都是使用B树来维
护索引结构.
索引的更新会导致大
量的IO操作
Lucene使用内存与
磁盘作为缓存, 进行批量
和增量的索引操作, 把小
的索引合并到大的索引
中
在不影响检索效率的
前提下, 提高了索引的效
率
查询模型
 向量模型
 Lucene在评估查询语句与Document之间的符合程度时用了向
量模型.
 布尔模型
 Lucene在词汇的逻辑设置中使用了布尔模型.
评分方式
协调函数, 当某个Document中包含的query数量多, 就返回较高的
权重数值
是query的规范化函数, 这个函数不影响document的评价, 因为所有
的document都会乘上这个规格化因子的数值, 这个函数只是对
query起作用.
是查询的时候增加的权重, 完全凭个人喜好添加
是文档的标准化因子, 参见后面的内容
获得索引文件名前缀
获得Field名称及特性
读取字典文件到内存中
得到频率和位置信息









Lucene的查询分析器为我们提供了丰富的
查询语法, 整合了JavaCC的词法分析器
项查询: let it be “hello world”
域查询: title:”The A” And Text:go
词条查询: te?t te*t
模糊查询: roam~ roam~0.8
间距查询: “jakarta apache” ~10
范围查询: title : {Aida TO Carmen}
权重查询: jakarta^4 apache
布尔查询: jakarta OR apache
布尔
词条
模糊
Query
对文档的
相似度计算(见下页)
Scorer
对应的打分器
打分, 获取Top K
的文档指针
取得搜索结果

假设有这样的一个查询:
 魔兽 dota 英雄

有下面几篇文档:
 (doc 1) dota里面的英雄都是来自魔兽
 (doc 2)黄继光是一个英雄
 (doc 3)我最爱的魔兽 英雄是恶魔猎手

整理出一个倒排表(仅保留查询关键字):
Doc ID
魔兽
Dota
英雄
1
1
1
1
2
NULL
NULL
1
3
1
NULL
1

计算:
 DocFreq(单词在所有文档中的出现次数), 全局
 TF(单词在某篇文档中的出现次数), 局部(需要重新计算)
 IDF, 单词的稀有程度, 局部

把表格补充完整:
Doc ID
魔兽
Dota
英雄
1
1
1
1
2
NULL
NULL
1
3
1
NULL
1
DocFreq
2
1
3
IDF
0.18
0.47
0

第一种方法:
 遍历每一篇文档, 然后把得分加起来, 保留Top K


时间复杂度 --- O(文档总数)
空间复杂度 --- O(1), 文档不读入内存, 在磁盘中
读取

第二种方法:
 遍历查询单词, 然后遍历倒排表中该单词对应的全部文
档,完成这个步骤后再对文档排序


时间复杂度 --- O(文档总数(最坏情况))
空间复杂度 --- O(文档总数(最坏情况))

并发合并

块处理

标准化因子部分(1):
 不同的文档重要性不同。有的文档重要些,有的文档相对不重要,
比如对于做软件的,在索引书籍的时候,我想让计算机方面的书
更容易搜到,而文学方面的书籍搜索时排名靠后。
 不同的域重要性不同。有的域重要一些,如关键字,如标题,有
的域不重要一些,如附件等。同样一个词(Term),出现在关键字
中应该比出现在附件中打分要高。
 根据词(Term)在文档中出现的绝对次数来决定此词对文档的重要
性,有不合理的地方。比如长的文档词在文档中出现的次数相对
较多,这样短的文档比较吃亏。比如一个词在一本砖头书中出现
了10次,在另外一篇不足100字的文章中出现了9次,就说明砖头
书应该排在前面码?不应该,显然此词在不足100字的文章中能出
现9次,可见其对此文章的重要性。

标准化因子部分(2):
由于以上原因,Lucene在计算Term Weight时,都会乘上
一个标准化因子(Normalization Factor),来减少上面三个
问题的影响。
标准化因子(Normalization Factor)是会影响随后打分
(score)的计算的,Lucene的打分计算一部分发生在索引
过程中,一般是与查询语句无关的参数如标准化因子.

标准化因子部分(3):

Hadoop + Lucene构建分布式引擎
参考资料: http://lucene.apache.org/hadoop/

Nutch – 基于Lucene的开源搜索引擎
参考资料: lucene.apache.org/nutch/



Lucene是一个面向对象程序设计的典范, 所
有问题都是通过一个额外的抽象层来方便
以后的扩展和重用(Strategy模式)
简单的应用入口来调用一系列底层代码
(example代码非常简单)
除了灵活的接口设计, 还提供了一系列可以
直接使用的Analyzer, 方便使用



车东的Lucene站点
http://www.chedong.com/tech/lucene.html
Lucene学习总结
http://forfuture1978.javaeye.com/blog/54682
4
<Lucene分析与应用>
机械工业出版社, 吴众欣 等