Lucene笔记
-
Lucene是什么
- Lucene是一个开源的全文检索引擎工具包, 但它不是一个完整的全文检索引擎, 而是一个全文检索引擎的架构, 提供了完整的查询引擎和搜索引擎以及部分文本分析引擎。可以把它理解成一个信息检索程序库, 而不是应用产品, 具体的功能需要使用者自己去以代码实现。
-
Lucene的功能
- 本质:
- 输入若干个字符串, 然后Lucene为使用者提供了一个全文搜索服务, 最后告诉使用者要搜索的关键词在哪里。
- 搜索引擎
- 本质:
-
Lucene速度测试
- 测试一:250万记录,300M左右文本,生成索引380M左右,800线程下平均处理时间300ms。
- 测试二:37000记录,索引数据库中的两个varchar字段,索引文件2.6M,800线程下平均处理时间1.5ms。
-
Lucene核心
-
倒排索引
-
根据属性的值来查找记录。索引表中的每一项都包括一个属性值和具有该属性值的各记录的抵地址
-
由于不是由记录来确定属性值, 而是由属性值来确定记录的位置, 因此被被称为倒排索引(invertedindex)
# import(输入) 1.Alex works in Facebook for three years. 2.John is a professional data-science analyzer. 3.Ronnie is just a noob in data-excavating field. 4.IceFrog works in valve for serveral years. # split (分词) Alex, works, in, Facebook, for, three, years John, is, a, professional, data-science, analyzer Ronnie, is, just, a, noob, in, data-excavating, field IceFrog, works, in, valve, for, serveral, years # statistic (处理后的统计结果) KeyWords(关键词) Article Number[Frequency]{position}(文章号[出现频率]{位置}) Alex 1[1]{0} Facebook 1[1]{3} IceFrog 4[1]{0} John 2[1]{0} Ronnie 3[1]{0} a 2[1]{2}, 3[1]{3} analyzer 2[1]{5} data-excavating 3[1]{6} data-science 2[1]{4} three 1[1]{5} field 3[1]{7} for 1[1]{4}, 4[1]{4} in 1[1]{2}, 3[1]{4}, 4[1]{2} is 2[1]{1}, 3[1]{1} just 3[1]{2} noob 3[1]{4} professional 2[1]{3} serveral 4[1]{5} works 1[1]{1}, 4[1]{1} valve 4[1]{3} years 1[1]{6}, 4[1]{6}
Lucene整体使用图:
-
-
压缩算法
-
为了节省空间,lucene在行存储和列存储中存放的都是压缩数据。对于行存储,lucene提供了两种压缩选项:
BEST_SPEED
和BEST_COMPRESSION
,对应速度优先和空间优先的不同策略。 -
Cardinality:
Cardinality
是指集合中不同值的个数。按照一般的做法,我们需要遍历集合,将不同的值保存到一个Map中,完成遍历后,map的size就是cardinality。可是这种处理方法不适合大集合,会消耗太多内存。
Lucene采用了另外的方法来统计cardinality,该方法不能够得到精确计算结果,但是能够得到一个近似值。方法的名称为:
HyperLogLog++
,计算过程如下:-
计算字段的hash值;
-
统计hash值末尾开始的连续0的个数,记为m;
-
记录m的最大值;
-
\[Cardinality = 2^m \]
我们来看个例子:
原始值 hash值 末尾连续0的个数 12345 11001011111101011010 1 3456 10001101001100111000 3 948 01000111110100110100 2 在上面的3个值中,我们观察到末尾连续0的个数最大为3,根据公式,cadinality等于
\[2^3 = 8 \]
-
-
二元搜索: 即二分查找算法
-
-
工作方式
- 写入流程
- 源字符串先经过analyzer处理, 包括: 分词, 分成一个个单词 (可选是否去除stopword)
- 将源中需要的信息加入Document的各个Field(信息域)中, 并把需要索引的Field索引起来, 把需要存储的Field存储起来。
- 将索引写入存储器, 存储器可以是内存或磁盘
- 读出流程
- 用户提供搜索关键词, 经过analyzer处理
- 对处理后的关键词搜索它的索引, 找出对应的Document
- 用户根据需要从找到的Document中提取需要的Field
- 写入流程
-
Document
- 用户提供的源是一条条记录,它们可以是文本文件、字符串或者数据库表的一条记录等等。一条记录经过索引之后,就是以一个Document的形式存储在索引文件中的。用户进行搜索,也是以Document列表的形式返回。
-
Field
- 一个Document可以包含多个信息域,例如一篇文章可以包含“标题”、“正文”、“最后修改时间”等信息域,这些信息域就是通过Field在Document中存储的。 Field有两个属性可选:存储和索引。通过存储属性你可以控制是否对这个Field进行存储;通过索引属性你可以控制是否对该Field进行索引。这看起来似乎有些废话,事实上对这两个属性的正确组合很重要。
-
Java 11 大分词器
- word分词器
- Ansj分词器
- Stanford分词器
- FudanNLP分词器
- Jieba分词器
- Jcseg分词器
- MMseg4j分词器
- IKAnalyzer分词器
- Paoding分词器
- smartcn分词器
- HanLP分词器