Lucene原理详解(万字图文解析)

Lucene原理详解(万字图文解析)-mikechen

Lucene是一个高效的基于Java的全文检索库,理解Lucene原理更容易掌握好Lucene搜索,下面我详解Lucene原理。

全文检索原理

Lucene是一个高效的基于Java的全文检索库,所以在了解Lucene之前要费一番工夫了解一下全文检索,这是Lucene原理的核心。

全文检索它的工作原理:就是是计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置。

当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式,这就是全文检索。

举一个例子:就拿新华字典做比喻,假设字典没有索引页,你要找一个字的解释你就得一页一页翻,直到找到为止,这效率可想而知。

现在有了索引页,就可以根据拼音首字母,或偏旁部首快速定位到目标字在哪一页,这个索引页,就是全文检索核心。

全文索引搜索支持非结构化数据的搜索,可以更好地快速搜索大量存在的任何单词或单词组的非结构化文本。

全文检索大体分三个过程,索引创建、索引存储、以及搜索索引。

 

索引创建

将现实世界中所有的结构化和非结构化数据提取信息,这个信息提取的过程,就是索引创建。

结构化和非结构化数据

1.结构化数据

结构化数据:指具有固定格式,或有限长度的数据,如数据库,元数据等。

对于结构化数据,我们一般都是可以通过关系型数据库,比如:mysql,oracle等表 的方式存储和搜索,也可以建立索引。

2.非结构化数据

非结构化数据:指不定长。或无固定格式的数据,比如:邮件,word 、pdf文档、HTML这类具有一定规则的非结构化数据。

在非结构化数据中,将一部分结构化信息抽取出来,重新组织,然后针对这部分有结构的数据,进行索引建立从而达到加速查询的目的。

比如最典型的代表,就是:Google、百度等搜索引擎按照词为单位,把HTML网页存入索引库,然后用户查询词,就会从索引库获取到想要的结果。

这种方式就构成了全文检索的基本思路,这部分从非结构化数据,比如:按照网页为单位中提取出网页标题的关键词,然后重新组织的信息,我们称之索引。

 

倒排索引

上面谈了全文检索技术的原理,下面谈谈全文检索技术的具体实现,绝大多数都基于倒排索引来做,所以要理解Lucene原理,需要掌握倒排索引。

要了解倒排索引,先看一下什么是正排索引。

1.正排索引

所谓正排索引,就是以文档对象的唯一 ID 作为索引,以文档内容作为记录,和我们人脑的记忆更加贴合的一种数据结构。

举一个生活中的例子:记忆古诗,当别人问我们《静夜思》这首诗的时候,我们很容易就能够背出完整的诗句。

但是如果有人问我们哪一首诗里面,包含有霜这个字的时候,我们就很难想到《静夜思》这首诗了,因为我们的大脑在记忆古诗的时候是建立了一个正排索引。

正排索引就是:输入静夜思,然后出现“窗前明月光,疑是地上霜,举头望明月,低头思故乡”,大脑记忆古诗的这个顺序,这就是正排索引。

 

2.倒排索引

而倒排索引是与这样的数据结构相反的,有一个从古代流传至今的游戏,叫做《飞花令》,规则就是要能够说出含有“花”的诗句,谁能够说的多谁就获胜。

倒排索引就是当用户在搜索引擎搜索框中输入关键词的时候,搜索引擎就会把和关键词有关的页面展现给用户,而这个过程就叫做倒排索引,这个与上面诗句的例子类似。

倒排索引是将文档内容中的单词作为索引,将包含该词的文档 ID 作为记录。

如下图所示:

Lucene原理详解(万字图文解析)-mikechen

举一个例子,手机查询,原始数据如下:

doc_id

name

desc

匹配数(在分词表中出现)

1

华为手机

中国第一品牌

2

2

华为荣耀手机

年轻人用的手机

3

3

荣耀手机

…..

2

4

青春版手机

…..

1

5

P40手机

…..

1

然后,通过分词产生倒排索引表,如下所示:

分词

doc_ids

华为

[1,2]

手机

[1,2,3,4,5]

荣耀

[2,3]

青春版

[4]

P40

[5]

倒排索引进行分组,根据’华为’、’荣耀’、’手机’分组,这就是倒排索引。

 

倒排索引和正排索引的区别

正排索引是通过文档找单词,既key找value,倒排索引是通过单词找文档,既value找key,这就是两者最大的区别。

倒排索引到此也就讲清楚了,你只要理解了倒排索引这个过程,对搜索引擎就有一个整体的了解了。

 

索引存储

索引创建好后,下一步就是索引存储。

以 Lucene为例,Lucene 的存储结构,如下图所示:

Lucene原理详解(万字图文解析)-mikechen

从大到小是:Index -> Segment -> Doc -> Field -> Term,类比 MySQL 为 Database -> Table -> Record -> Field -> Value。

 

搜索索引

理解了索引的创建过程,最后一步就是搜索索引的查询。

查询索引做了哪些事情?

查询索引主要分为如下4大步骤:

第一步:对查询内容进行词法分析

举个例子,用户输入语句:lucene AND learned NOT hadoop,说明用户想找一个包含lucene和learned,然而不包括hadoop的文档。

这里的AND以及NOT这些分析,这就是词法和语法分析,类似关系数据库oracle、mysql中sql的意义。

 

第二步:搜索索引

搜索索引:就是去索引库中找到满足查询条件的索引列表。

这里大致分为如下3步:

首先:在反向索引表中,分别找出包含lucene,learn,hadoop的文档链表。

其次:对包含lucene,learn的链表进行合并操作,得到既包含lucene又包含learn的文档链表。

最后:将此链表与hadoop的文档链表进行差操作,去除包含hadoop的文档,从而得到既包含lucene又包含learn而且不包含hadoop的文档链表。

 

第三步:内容排序

计算权重对返回内容排序,影响一个词(Term)在一篇文档中的重要性主要有两个因素:

Term Frequency (tf):即此Term在此文档中出现了多少次,tf 越大说明越重要。

Document Frequency (df):即有多少文档包含次Term,df 越大说明越不重要。

 

Lucene原理总结

最后配一张图来加强下对创建索引和查询索引的理解:

Lucene原理详解(万字图文解析)-mikechen

首先通过分词,通过词法分析索引创建,然后索引存储,最后搜索索引查询,这就是Lucene原理。

陈睿mikechen

10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注「mikechen」公众号,获取更多技术干货!

后台回复面试即可获取《史上最全阿里Java面试题总结》,后台回复架构,即可获取《阿里架构师进阶专题全部合集

评论交流
    说说你的看法