Lucene全文检索基本原理

来源:互联网 发布:网络用语处pc什么意思 编辑:程序博客网 时间:2024/05/21 23:37

Lucene是一个高效,基于Java的全文检索库

使用Lucene时之前使用过一个基于Lucene的变种搜索引擎——Indri

Indri是支持文档索引的基于C和C++的全文检索引擎系统,特点是跨平台,API接口支持Java,PHP,C++等,效果非常不错。

今年再做另一个项目的时候又到了需要全文搜索引擎的时候,这次选择了Lucene。一是因为Lucene的开发语言是Java,本身学习Java时间比较长相对熟悉,另外是Lucene也是业界最良心的开源搜索引擎之一了,提供了完整的查询引擎和索引引擎,对英文等一些外语支持效果非常好。唯一的缺陷是对中文分词还得自己去找另外的一些分词器去实现。但是整体还是非常不错的一款搜索引擎。

Lucene官网:http://lucene/apache.org/

今天主要想深入了解一下Lucene的全文检索基本原理

首先我们先了解一下什么是全文检索。这得从数据说起。

生活中的数据主要分为两类:结构化数据和非结构化数据

结构化数据:固定格式或有限长度的数据,例如数据库,元数据等等
非结构化数据:不定长或没有固定格式的数据,例如邮件,word等

另外还有一类HTML和XML为代表的半结构化数据,这些可以根据实际需要即可按照结构化数据处理也可以按照非结构化数据抽取文本处理

按照数据分类,搜索分为两类:

对结构化数据的搜索:如对数据库搜索等等,用SQL语句。如对元数据搜索,如利用windows搜索为文件名,类型,修改时间进行搜索等
对非结构化的数据:如利用windows的搜索可以搜索文件内容,Linux下的grep命令,再如用Google和百度搜索内容等

对非结构化的数据搜索一般也叫全文索引,主要有以下两种方式:

一是顺序扫描法:顾名思义,就是例如我们要找一个包含字符串的文件,就一个一个文件从头开始扫描检索,如果这个文档包含我们要找的,则这个文档就是我们要找的文件。

最明显的,windows的搜索相信大家都用过,每次windows搜索就是一个一个检索,虽然很慢,但是有效。Linux命令下的grep命令也是同样的效果。这对于小数据量的文件还是比较容易实现的,但是对于大量的文件,这种方法就需要考量了。

这时候有人就会说对于非结构化的数据扫描慢,但是对于结构化的数据扫描却很快,这是因为结构化的数据有一定的结构可以采取一定的搜索算法加速我们的检索。那么我们可不可以直接将非结构化的数据提取出来,重新组织,使其变得有一定结构,然后再去进行索引从而加速我们的检索效果呢?

这种想法诞生了全文索引最基本的思路。 即将非结构化数据中的一部分提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据我们进行搜索,从而达到了搜索相对较快的目的。

这部分我们从非结构化数据中提取然后重新组织的信息,我们称为索引。
就好像字典的拼音表和首字母查询表就相当于字典的索引。每个字的解释很多,但是我们可以将字中的某些信息比如拼音,笔画等等提取出来进行结构化,我们需要搜索时按照结构化拼音搜索从而找到我们的非结构化数据。
这种先建立索引,再对索引进行搜索的过程就叫做全文索引(Full-Text Search)

下图来自《Lucene in action》,但是不仅仅描述了Lucene,而是描述了全文检索的一般过程。
全文检索一般过程

那么我们知道了,全文检索分为两个模块:索引创建(Indexing)和搜索索引(Search)

索引创建即将结构化和非结构化的数据提取信息,创建索引的过程
搜索索引即得到用户查询请求,搜索创建的索引,然后返回的过程

有了这个命题作为基础,我们就知道了我们要研究的方向是什么,主要的问题是什么?

1 索引里面到底存放什么?
2 如何创建索引
3 如何对索引检索

首先看第一个问题,索引存放着什么?

我们想为什么顺序扫描比较慢,是因为想要搜索的信息和非结构化数据中存储的信息不一致造成的,那么如果我们将非结构化的文档中内容提取出来进行结构化的组合和排列,然后检索的时候从这些文件中进行检索不就可以了吗
由字符串到文件的映射是文件到字符串映射的方向过程,于是保存这种信息的索引我们称之为反向索引。因此保存的实际上就是各个名词在文档中的出现次数以及排序。就像建立目录一样。

这也是建立索引的好处之一,一次建立,多次使用。每当库中增加一条文章时,只要对索引的内容进行一点微调就可以达到预期的效果。
第二和第三个问题我想放到一起来说,首先我们来看下面这张图:

全文检索全过程

过程大致如下:
1. 索引过程:
1) 有一系列被索引文件
2) 被索引文件经过语法分析和语言处理形成一系列词(Term)。
3) 经过索引创建形成词典和反向索引表。
4) 通过索引存储将索引写入硬盘。
2. 搜索过程:
a) 用户输入查询语句。
b) 对查询语句经过语法分析和语言分析得到一系列词(Term)。
c) 通过语法分析得到一个查询树。
d) 通过索引存储将索引读入到内存。
e) 利用查询树搜索索引,从而得到每个词(Term)的文档链表,对文档链表进行交,差,并得到结果文档。
f) 将搜索到的结果文档对查询的相关性进行排序。
g) 返回查询结果给用户。

以上就是全文检索的基本原理,Lucene正是基于这种基本原理在每一步进行深入的研发和创造的。当然中间很多步骤还有提升和值得讨论的空间。但是在这里我们只是给大家介绍一下全文检索的基本原理因此具体的细节不去讨论,首先让大家明白全文检索的基本原理。

参考资料:
《Lucene的原理与代码分析》刘超觉先 第一章