LUCENE
Lucene
如何在一篇文章中,查找一个单词?
答:顺序查找,全文遍历查找。
如果数据量很大怎么办?全文遍历查找很慢。
答:结构数据,可以创建索引(比如:mysql B+树)。
非结构化数据,如何建立索引机制?
答:没有结构,提取结构。没有索引,创建索引。
1. 可以录入文章到lucene。(文档录入)
2. 将原文档传递给分词器(Tokenizer),分词器提取一个一个的单词,将标点符号去掉,去除停词(stop the world,比如:the、this),即:得到词元。(词元提取)
3. 语言处理组件进一步处理,大写变小写、单词缩减(cars -> car)、词根转换(drove -> drive)。
4. 将得到的词传递给索引组件,创建索引字典,相同字典词进行合并,词出现在几个文档,链表(值为:文档id,出现次数)就有几个节点,同时包含一些定义信息。
5. 最终,完成倒排索引。Lucene的IndexWriter是线程安全的,它支持多线程索引。每个IndexChain都有一个独立的索引内存空间,每一个 indexChain是互不干扰的各负责各自部分,索引效率很高。(分治并行思想)
6. 在写入内存阶段, Lucene通过IndexChain把document分解并把相关信息存储到内存中,等到满足flush条件(内存容量或者文档个数积累到临界值),就通过IndexChain把内存中的数据flush到硬盘。
lucene索引结构是如何存储的?
答: 索引:一个目录一个索引,同一个文件夹所有文件构成一个lucene索引。
段:一个索引可以包含多个段,段与段之间是独立的,添加新文档可以生成新的段,不同的段可以合并。
文档:文档是我们建索引的基本单位,不同的文档是保存在不同的段中的,一个段可以包含多篇文档。
域:一篇文档包含不同类型的信息,可以分开索引,比如标题,时间,正文,作者等,都可以保存在不同的域里。不同域的索引方式可以不同。
词:词是索引的最小单位,是经过词法分析和语言处理后的字符串。
正向信息与反向信息?
答:
正向信息:按层次保存了从索引,一直到词的包含关系:索引(Index) –> 段(segment) –> 文档(Document) –> 域(Field) –> 词(Term)。
反向信息:保存了词典到倒排表的映射:词(Term) –> 文档(Document)。
为什么要有段的概念?(批量写入的思想)
答: 批量刷盘同步,是性能的考虑。
在建立索引的时候对性能影响最大的地方就是在将索引写入文件的时候, 所以在具体应用的时候就需要对此加以控制:
Lucene默认情况是每加入10份文档(Document)就从内存往index文件写入并生成一个段(Segment) ,然后每10个段(Segment)就合并成一个索引(Index)写入磁盘。
搜索流程是什么样子的?
答:
1. 基于词法和语法分析(and、or、not等)。
2. 语法分析主要是根据查询语句的语法规则来形成一棵语法树。
3. 语言处理同索引过程中的语言处理几乎相同(如learned变成learn)。
4. 搜索索引,得到符合语法树的文档。反向查找包含语法树中的每个词的文档链接,同时按照逻辑运算对文档链接进行合并。
5. 对于查询结果应该按照与查询语句的相关性进行排序,越相关者越靠前。
如何计算相关性呢?
答:我们把查询语句看作一片短小的文档,对文档与文档之间的相关性(relevance)进行打分(scoring),分数高的相关性好,就应该排在前面。
那么又怎么对文档之间的关系进行打分呢?
答:找出词(Term) 对文档的重要性的过程称为计算词的权重(Term weight) 的过程。(此文档出现的多,所有文档出现的少,则重要。)
计算词的权重(term weight)有两个参数,第一个是词(Term),第二个是文档(Document)。词的权重(Term weight)表示此词(Term)在此文档中的重要程度,越重要的词(Term)有越大的权重(Term weight),因而在计算文档之间的相关性中将发挥更大的作用。
判断词(Term)之间的关系从而得到文档相关性的过程应用一种叫做向量空间模型的算法(Vector Space Model) 。
优化?
答:有,比如压缩算法。为了减小索引文件的大小,Lucene对索引还使用了压缩技术。
首先,对词典文件中的关键词进行了压缩,关键词压缩为<前缀长度,后缀>,例如:当前词为“阿拉伯语”,上一个词为“阿拉伯”,那么“阿拉伯语”压缩为<3,语>。
其次大量用到的是对数字的压缩,数字只保存与上一个值的差值(这样可以减小数字的长度,进而减少保存该数字需要的字节数)。例如当前文章号是16389(不压缩要用3个字节保存),上一文章号是16382,压缩后保存7(只用一个字节)。
性能?
答:毫秒级。
- Lucene小结:文档录入->提取词元(去除无用词the等、大小写统一、相同词映射drove到drive等)->排序并建立倒排索引->刷盘。
- 检索,语法树解析,倒排索引文档地址,文档地址合并,词的重要性(当前文档出现频率、所有文档出现频率),逻辑关联性分析(判断词,空间向量模型)。
- Lucene对Key的索引没有用到B+树,而是按字典序进行排列,而有增量进来时,通过mergeSort(归并排序)进行索引的合并,形成新的索引文件,保存在磁盘中。
相关应用:Solr、ElasticSearch、Ha3、Tis3
Reference
- https://www.jianshu.com/p/0cfe042412a2(lucene全文检索原理和流程)
- https://www.cnblogs.com/forfuture1978/p/3940965.html(倒排索引实现与原理)
- https://blog.csdn.net/dingjue6870/article/details/101900112(es的replica&shard的机制)