Lucene - 核心原理、特点、以及架构详解
一、基本介绍
1,Lucene 介绍
(1)Lucene 是 Java 家族中最为出名的一个开源搜索引擎,在 Java 世界中属于标准的全文检索程序,在传统 IT 领域的全文检素中占据着重要地位。
(2)Lucene 提供了两大核心引擎:索引引擎和搜索引擎。通过这两个引擎可以实现对数据建立索引,并且可以根据用户的复杂查询请求快速返回满足条件的结果数据。
- 索引引擎:给文本数据创建索引。
- 搜索引擎:根据用户的查询请求,搜索创建的索引并返回结果。
2,Lucene 的特点
(1)Lucene 具有如下优点:
- 有足够的定制和优化空间。
- 索引文件格式独立于应用平台,跨平台的应用可以共享同一份素引文件。
- 提供了一套强大的查询引擎,默认实现了布尔操作、模糊查询、分组查询等。
(2)Lucene 存在如下缺点:
- 不支持分布式,无法扩展,在海量数据下会存在瓶颈。
- 提供的都是低级 API,使用烦琐。
- 没有提供 Web 界面,不便于运维和管理。
二、架构分析
1,整体架构
Lucene 的整体架构如下图所示,具体包含 Lucene 建立索引和查询索引这两个过程。

2,建立索引
(1)Lucene 中核心的内容是索引(Index)。建立索引和查询索引都需要操作索引库。Lucene 可以提供多条件快速复杂查询就是因为这个索引库。在索引库中包含的是词语和文档数据之间的映射关系,一般我们会把这个映射关系称为倒排索引。
(2)假设现在有一批文档数据,数据中有两个字段:文档编号和文档内容,具体如下下表所示:
文档编号 | 文档内容 |
1 | 我们爱中国国歌 |
2 | 我们是中国人 |
3 | 中国是世界上人口最多的发展中国家 |
4 | 中国是世界上历史最悠久的国家之一 |
5 | 中国位于亚洲东部 |
(3)对于上表中的文档数据,在 Lucene 中执行建立素引操作后,最终在索引库中存储的倒排索引格式大致如下表所示。注意该表中只列出来了产生的部分倒排索引内容。
- 词语 ID:记录每个词语的编号。
- 词语:从文档数据中拆分出来的文字。
- 文档频率:文档集合中有多少个文档中包含某个词语。
- 倒排列表:包含词语 ID 及其他必要信息。
- DoclD:词语所在的文档 ID。
- TF:词语在某个文档中出现的次数。
- POS:词语在文档中出现的位置。
词语 ID | 词语 | 文档频率 | 倒排列表(DocID;TF;<POS>) |
1 | 我们 | 2 | (1,1,<1>),(2,1,<1>) |
2 | 中国 | 5 | ((1,1,<3>),(2,1,<2>),(3,2,<1;6>),(4,1,<1>),(5,1,<1>)) |
3 | 国歌 | 1 | {(1,1,<4>)} |
4 | 世界 | 2 | (3,1,<2>),(4,1,<2>) |
5 | 国家 | 2 | {(3,1,<7>),(4,1,<5>)} |
...... | ...... | ...... | ...... |
(4)以词语“我们”为例,其词语编号为 1,文档频率为 2,代表整个文档集合中有 2 个文档包含这个词语。对应的倒排列表为 {(1,1,<1>),(2,1<1>)},含义是:在文档 1 和文档 2 中出现过这个词语,在每个文档中都只出现过 1 次,词语“我们”在第 1 个文档的 POS(位置)是 1,即文档的第 1 个词语是“我们”,其他的类似。
提示:以“我们爱中国国歌”为例,默认情况下会产生“我们”“爱”“中国”“国歌”这 4 个词语。这里会用到中文分词器,不同的分词器分出来的词语可能会有差异。
3,查询索引
(1)假设现在我们查找既包含“我们”又包含“国歌”的文档数据,大致流程如下。首先到索引库里面找到词语“我们”对应的倒排列表:
词语 ID | 词语 | 文档频率 | 倒排列表(DocID;TF;<POS>) |
1 | 我们 | 2 | (1,1,<1>),(2,1,<1>) |
(2)接着到索引库里面找到单词“国歌”对应的倒排列表:
词语 ID | 词语 | 文档频率 | 倒排列表(DocID;TF;<POS>) |
3 | 国歌 | 1 | {(1,1,<4>)} |
(3)最后合并倒排列表信息,找出既包含“我们”又包含“国歌”的文档 ID,这样就可以找到满足条件的文档数据了:
