ElasticSearch使用一种称之为 倒排索引 的数据结构,实现快速的全文索引。
一个倒排索引由 文档中所有不重复的词 + 包含对应的词的文档列表 组成。
比如有两个文档,有如下内容:
1. The quick brown fox jumped over the lazy dog
2. Quick brown foxes leap over lazy dogs in summer
为了创建倒排索引,
第一步工作 —— 分词(分出来的单独的词,我们称之为“词条”或“token”);
第二部工作 —— 创建一个包含不重复词条的排序列表,并列出该词条出现在哪个文档。结果如下所示:
Term Doc_1 Doc_2
-------------------------
Quick | | X
The | X |
brown | X | X
dog | X |
dogs | | X
fox | X |
foxes | | X
in | | X
jumped | X |
lazy | X | X
leap | | X
over | X | X
quick | X |
summer | | X
the | X |
------------------------
这就是乞丐版本的倒排索引。
如果我们想搜索quick brown,我们只需要查找包含各个词条的文档:
Term Doc_1 Doc_2
-------------------------
brown | X | X
quick | X |
------------------------
Total | 2 | 1
两个文档都匹配,但是第一个文档比第二个的匹配度更高,如果我们使用 仅计算匹配词条数量 的 简单相似性算法,我们可以说,查询的相关性第一个文档比第二个文档更佳。
但是当前的倒排索引有一些问题:
所以:
使用我们乞丐版的倒排索引搜索+Quick +fox不会得到任何文档(+前缀表示这个词必须存在)。但是用户觉得,第一个文档包含quick fox,第二个文档包含Quick foxes。这两个文档都满足的需求。为了满足常规需求,我们必须优化乞丐版倒排索引,如:
Term Doc_1 Doc_2
-------------------------
brown | X | X
dog | X | X
fox | X | X
in | | X
jump | X | X
lazy | X | X
over | X | X
quick | X | X
summer | | X
the | X | X
------------------------
此时我们搜索+Quick +fox还是会失败,因为索引中已经没有Quick了。所以我们还得对搜索条件做同样的标准化处理,才能匹配到两个文档。
分词和标准化的过程称之为分析。
分析包含如下过程:
分析器实际上是将三个功能封装到了一个包里:
ElasticSearch提供了开箱可用的预包装分析器。
"Set the shape to semi-transparent by calling set_trans(5)"
ElasticSearch默认使用的分析器。分析各种语言文本最常用的选择。它根据Unicode联盟定义的 单词边界划分文本,删除绝大多数标点,最后将词条小写。
set, the, shape, to, semi, transparent, by, calling, set_trans, 5
简单分析器在任何不是字母的地方分割文本,将词条小写。
set, the, shape, to, semi, transparent, by, calling, set, trans
在空格的地方分割文本。
Set, the, shape, to, semi-transparent, by, calling, set_trans(5)
特定语言分析器可以分析很多语言(https://www.elastic.co/guide/en/elasticsearch/reference/5.6/analysis-lang-analyzer.html),他们可以考虑制定语言的特点(如英语分析器附带了一组无用词过滤器,过滤a,the等)
set, shape, semi, transpar, call, set_tran, 5