ES作为一款搜索引擎框架,文本搜索是其核心功能。ES在文本索引的建立和搜索过程中依赖两大组件,即Lucene和分析器。其中,Lucene负责进行倒排索引的物理构建,分析器负责在建立倒排索引前和搜索前对文本进行分词和语法处理。
文本的索引建立过程
为了完成对文本的快速搜索,ES使用了一种称为“倒排索引”的数据结构。倒排索引中的所有词语存储在词典中,每个词语又指向包含它的文档信息列表。
假设需要对下面两个旅馆的信息进行倒排索引的创建:
- 文档ID为001,旅馆名称为“北京嘉怡假日旅馆”;
- 文档ID为002,旅馆名称为“北京欣欣旅馆”。
首先,ES将文档交给分析器进行处理,处理的过程包括字符过滤、分词和分词过滤,最终的处理结果是文档内容被表示为一系列关键词信息的集合。这里的关键词信息指的是关键词本身以及它在文档中出现的位置信息和词性信息,下图所示为文档001的分析结果示意图。
其次,ES根据分析结果建立文档-词语矩阵,用以表示词语和文档的包含关系,本例中的文档-词语矩阵如下表所示:
北京 | 嘉怡 | 假日 | 欣欣 | 旅馆 | |
001 | 1 | 1 | 1 | 0 | 1 |
002 | 1 | 0 | 0 | 1 | 1 |
通过上面的文档-词语矩阵可知,ES从文档001中提取出4个词语,从文档002中提取出3个词语。
文档-词语矩阵建立完成之后,接着需要建立基于词语的倒排索引。ES会遍历文档词语矩阵中的每一个词语,然后将包含该词语的文档信息与该词语建立一种映射关系。映射关系中的词语集合叫作Term Dictionary,即“词典” .
映射中的文档集合信息不仅包含文档ID,还包含词语在文档中的位置和词频信息,包含这些文档信息的结构叫作Posting List。
对于一个规模很大的文档集合来说,可能包含几十万甚至上百万的词语集合,能否快速定位某个词语,直接影响搜索时的响应速度。
因此需要一种高效的数据结构对映射关系中的词语集合进行索引,这种结构叫作Term Index。上述3种结构结合在一起就构成了ES的倒排索引结构,倒排索引与三者之间的逻辑关系如下图所示:
本例中的倒排索引结构如下图所示:
文本的搜索过程
在ES中,一般使用match查询对文本字段进行搜索。match查询过程一般分为如下几步:
- ES将查询的字符串传入对应的分析器中,分析器的主要作用是对查询文本进行分词,并把分词后的每个词语变换为对应的底层lucene term查询。
- ES用term查询在倒排索引中查找每个term,然后获取一组包含该term的文档集合。
- ES根据文本相关度对每个文档进行打分计算,打分完毕后,ES把文档按照相关性进行倒序排序。
- ES根据得分高低返回匹配的文档。
比如以下对旅馆索引中搜索“金都嘉怡”的查询如下:
ES分析器先将查询词切分为“金都”和“嘉怡”,然后分别到倒排索引里查找两个词对应的文档列表并获得了文档001和002,然后根据相关性算法计算文档得分并进行排序,最后将文档集合返回给客户端。