Lucene是一个基于Java的全文检索库,它高效、开源。为什么叫它全文检索库呢?这得从人们生活中的数据结构来说起。
人们在使用各种软件服务的时候会产生各种的数据,这些数据会被相关软件服务提供商按照不同的规则存储起来,当人们需要的时候再取出来。由于不同的软件服务提供商所使用的技术不同,这些数据被以各种不同的方式存储在不同的地方,即便是同一个软件服务提供商,它的数据可能也被存储在不同的服务器甚至根据不同的业务存储在不同的数据库中。这样一来,一个用户的相关数据可能一部分存储在关系型数据库A库、B库中,另一部分被存储在非关系型数据库的数据库中,用户的这些数据被分散在各个不同的地方,导致这些数据呈现出非结构化的状态。当用户需要把这些不同的数据按一定规则排列展示出来的时候,由于数据存储地方的不同,如果按照传统的技术方案来实现的话会使得系统非常复杂。而全文检索则把这些分部在不同地方的数据按照一定的规则抽取出来,组合成一个结构化的数据,这就可以非常方便地使用一些算法来快速地定位找到相关数据。而从这些散乱分部的数据中提取并重新组织出的信息,被称之为索引。
文章图片
Lucene的全文检索过程
全文检索大体分两个过程,索引创建和搜索索引。
索引创建:把所有的分部在不同地方的信息提取并重新组织起来,创建索引;
搜索索引:将用户的查询请求按一定规则转换为特定的查询条件,搜索索引中的结构化数据,然后返回结果;
全文检索存在三个重要问题:
索引里究竟存在些什么?
如何创建索引?
如何对索引进行搜索?
后面我们会对这三个问题进行逐一研究与讨论。
第一:索引里究竟存些什么?
首先,由于数据的分散式存储,导致我们不能直接去一次性查询所有的数据;即便所有的数据都存放在一起,我们可以在一个地方去查询数据,也会由于所有用户的数据都放在一起,导致查询的数据过于庞大而搜索速度非常缓慢。
这些非结构化的数据所存储的信息是每个文件包含哪些字符串,也即已知文件,欲求字符换相关容易,就是从文件到字符串的映射。而我们想搜索的信息是哪些文件包含此字符串,也即已知字符串,欲求文件,即从字符串到文件的映射,则会大大提高搜索速度。
由于从字符串到文件的映射是从文件到字符串映射的反向过程,于是保存这种信息的索引称为反向索引。
反向索引中存储的信息如下:
假设我的文档集合里面有100篇文档,为了方便表示,我们将其表示为1-100,其结构如下:
文章图片
反向索引存储结构
左边的一系列字符串被称为词典。
每个字符串都指向包含此字符串的文档链表,此文档链表称为倒排表。
当索引建立之后,我们就可以非常快速地搜索到想要得到的文档。
【Lucene初探】有人说,建立索引,然后再查询,两者的速度不一定比直接进行顺序扫描快。的确,加上索引创建的过程,全文检索不一定比直接的全文顺序扫描快多少,尤其在数据量少,并且存储在一个地方的时候,并且为一个很大的数据创建索引也是一个很慢的过程。然而两者还是有一定的区别的。顺序扫描是每次查询都要从头查找,而创建索引的过程只有一次,以后就可以一劳永逸了,每次搜索,只要查询索引即可,而不用每次都去创建索引。