Lucene作为一个快速的检索框架,为中小型公司提供了一个快速接入搜索引擎的途径。其从创立之初,得到了开源社区的快速发展。其突出优势为快速的数据处理能力和TF-IDF的快速排序算法。本文从Lucene的打分原理、具体的实现和数据存储结构三个方面讲解,力争将Lucene的核心原理层层剖开。
1、Lucene的打分原理
Lucene的打分原理采用了SVM的理论1,计算相似度。即通过计算查询向量和文档向量的夹角,计算查询向量和文档向量之间的相似度。文档向量的维度即为检索词,其度量为文档出现的词频。其计算公式如下:
d2代表文档词频向量,q代表查询词频向量。|d2|代表文档向量的模,|q|代表查询向量的模。
虽然一些词出现的频率较高,但是在其他文档中也有较高的频率出现,我们称之为区分度较低的词。Lucene针对此种问题,采用了TF-IDF的理论,即不仅考虑词在文档中的频率,也考虑词在整个文档中的区分度。其公式如下:
D代表所有的文档数量,d’代表含有当前词的文档数。
此模型能够区分不同文档的相似度,并且能够实现连续化的排序,所以能够快速的实现文档的排序。由于文档向量仅适用词频作为维度度量给排序带来一定的劣势,例如:查询词在文档中的位置不能考虑,但是词序往往影响词的意思,甚至意思会截然相反。
2、具体的实现
Lucene在SVM理论的基础之上,从实用性和质量的角度进行了改进,具体因素如下:
1) 标准化V(d)减少了文档长度带来的干扰。其解决多段重复的文档带来的干扰。
2) 由于文档的内容不同,需要考虑不同文档的重要性。
3) 用户检索时,不同关键词的权重不同。
考虑以上因素之后的公式如下:
其中,
1) query(q,d)在检索的时候设定特定查询词的权重
2) doc-len-norm(d)和doc-boost(d)在构建索引的时候创建.
3) V(d)的计算需要通过具体的词频实现,计算过程中需要考虑词频的重要性,计算公式如下:
|
Lucene相似度的计算是语言处理模型的一种集成,理论上集成了SVM模型、语言处理理论、信息检索等多种模型。作者针对具体的应用场景对每种理论模型进行了适当的调整,以便更加适应计算机运算,可以说Lucene是一种理论和时间的双层突破。
3、数据存储结构
为了便于快速查询和使用,Lucene提供了内存和文件的双重模式,本文仅限文本格式的索引,其文件格式及功能介绍如下:
名称 | 后缀 | 简介 |
段文件集 | Segments_n | 存储提交点信息 |
锁文件 | Write.lock | 防止多个indexWrite往一个文件写入 |
段文件 | .si | 存储段元数据 |
合并文件 | .cfs .cfe | 由其他索引文件组合成的虚拟文件 |
域文件集 | .fnm | 存储所有域的信息 |
域索引 | .fdx | 存储执行域数据的指针 |
域数据 | .fdt | 存储文档的域数据 |
词字典 | .tim | 存储词的字典 |
词索引 | .tip | 存储指向词字典的索引 |
词频 | .doc | 存储文档中的次频数 |
位置 | .pos | 记录词在索引中的位置 |
有效载荷 | .pay | 记录用户的负载或者单词的偏移量 |
标准化数据 | .nvd .nvm | 文档或者域的标准化数据 |
文档的值 | .dvd .dvm | 记录每个文档的权重等信息 |
词向量索引 | .tvx | 记录文档数据的偏移 |
词向量数据 | .tvd | 记录词向量数据 |
活跃文档 | .liv | 记录当前活跃文档 |
关键点值 | .div .dim | 记录索引关键点 |
通过以上文件的分析,不难发现:1)lucene的存储结构分为段、文档、域和词四级结构 2)其存储结构采用两级索引结构加快查询速度 3)其数据结构与其算法相吻合4)每种文件的职责相对单一,有效解决高并发存储和运维问题。
参考文献
1、https://en.wikipedia.org/wiki/Vector_space_model
2http://lucene.apache.org/core/7_0_0/core/org/apache/lucene/search/similarities/TFIDFSimilarity.html