我的 Elasticsearch 系列文章,逐渐更新中,欢迎关注
0A. 关于 Elasticsearch 及实例应用
00.Solr 与 ElasticSearch 对比
01.ElasticSearch 能做什么?
02.Elastic Stack 功能介绍
03. 如何安装与设置 Elasticsearch API
04. 如果通过 elasticsearch 的 head 插件建立索引_CRUD 操作
05.Elasticsearch 多个实例和 head plugin 使用介绍
06. 当 Elasticsearch 进行文档索引时,它是如何工作的?
07.Elasticsearch 中的映射方式—简洁版教程
08.Elasticsearch 中的分析和分析器应用方式
另外 ES 入门,我强烈推荐这篇 Elasticsearch 权威搭建指南给你,非常想尽的指南手册。
介绍
在本系列的第一个博客中,我们看到了在 Elasticsearch 中对文档建立索引时的反向索引计算,而在第二个博客中,我们看到了 Elasticsearch 中的映射基础。现在,在此博客中,我们将详细介绍 Elasticsearch 的分析部分,如何完成以及如何定制分析。
1. 分析过程说明
为了了解 Elasticsearch 中的分析过程及其需求,我们需要对
inverted index
Elasticsearch 中的创建进行更深入的了解。我们在阶段 02 的博客 01 中讨论的关于
inverted index
创建的内容是基本版本,在这里让我为倒排索引创建场景添加一些复杂性。
当我们将这些文档索引到 Elasticsearch 时,流程如下:
现在让我解释反向索引创建之前的每个阶段:
1.1 字符过滤器
字符过滤器具有对提供给他们的输入文本执行添加,删除或替换操作的能力。为了更清楚地理解它,如果输入字符串包含重复出现的拼写错误的单词,而我们需要用正确的单词替换它,那么我们可以使用字符过滤器对此进行相同的处理。此过滤器最常见的应用之一是
html
从输入文本中剥离标签。
让我们看看使用 Elasticsearch 的 Analyze API 进行字符过滤的工作。在这里,我们将使用字符过滤器“html_strip”从文本中删除 html 标签。卷曲请求如下:
curl -XPOST ‘localhost:9200/_analyze?pretty’ -H ‘Content-Type: application/json’ -d ‘{
“tokenizer”: “standard”,
“char_filter”: [
"html_strip"
],
“text”: “The Auto-generation is a success”
}’
生成的令牌如下所示:
“The”,”Auto”,”generation”,”is”,”a”,”success”
在这里我们可以看到令牌中没有 html 标记。同样,尝试不带的上述 curl 请求,
“char_filter”:[“html_strip”]
然后看看有什么不同。
1.2 分词器
从“字符”过滤器转换后的输入文本将传递到令牌处理程序。令牌生成器会将输入文本拆分为特定字符处的单个令牌(或术语)。elasticsearch 中的默认标记器是“标准标记器”,它使用基于语法的标记化技术,该技术不仅可以扩展到英语,还可以扩展到许多其他语言。
让我们在下面看到一个标准令牌生成器的示例:
curl -XPOST‘localhost:9200/_analyze?pretty’-H‘Content-Type: application/json’-d ‘{
“tokenizer”:“standard”,
“text”:“The Auto-generation is a success”
}’
在响应中,您可以看到文本分为以下标记:
“The”,“Auto”,“Generation”,“is”,“a”,“success”
在这里,只要有空格和连字符(-),单词就会被拆分。
注意:有不同类型的标记器,用于不同的目的。在某些用例中,我们可能不需要拆分特殊字符(例如,在使用电子邮件 ID 或 url 的情况下),因此为了满足此类需求,我们可以使用“UAX URL Email Tokenizer”等标记器。可以在此处找到 Elasticsearch 提供的标记器列表
1.3 令牌过滤器
将输入文本拆分为标记 / 术语后,将其移至分析的最后阶段,即标记过滤。令牌过滤器可以作用于由令牌生成器生成的令牌,并可以对其进行修改,添加或删除。让我们尝试以上示例的令牌过滤器。我们将在这里尝试使用的令牌过滤器是小写的令牌过滤器,它将所有进入其中的令牌都小写。以下 curl 请求使用 analyst API 进行演示:
curl -XPOST ‘localhost:9200/_analyze?pretty’ -H ‘Content-Type: application/json’ -d'{
“tokenizer”: “standard”,
“filter”: [
"lowercase"
],
“text”: “The Auto-generation is a success”
}’
响应中生成的令牌如下所示:
“the”,“auto”,“generation”,“is”,“a”,“success”
请注意,每个标记现在都小写了。这就是小写令牌过滤器对令牌的作用。
有关 Elasticsearch 随附的令牌过滤器的列表
在 Elasticsearch 中,令牌过滤器最常见的用例之一是向单词添加同义词。从本质上讲,这意味着可以使用此过滤器将单词映射到其同义词,并且每当我们搜索同义词时,都会出现包含基础单词的文档。我们将在以后的博客中看到此方法的应用。
2. 分析仪
上一节介绍了 Elasticsearch 分析文档中字段内容的过程。正如在上一节中提到的,有几种类型的字符过滤器,令牌化器和令牌过滤器可用,我们应该根据遇到的用例明智地选择它们。这三个组件(字符过滤器,令牌生成器和令牌过滤器)的组合称为分析器。Elasticsearch 提供了几种类型的内置分析器,用于处理最常见的用例。例如,Elasticsearch 的默认分析器标准分析器是标准令牌生成器和两个令牌过滤器(标准令牌过滤器,小写和停止令牌过滤器)的组合。同样,根据字符过滤器的组合,可以使用多种分析仪,
分析仪的总体结构如下所示:
我们还可以通过选择所需的过滤器和标记器来制作自定义分析器。我们将在本系列的下一个博客中看到定制分析器的制作。
3. 分析阶段
现在我们对什么是分析以及什么是分析器有了清晰的了解,让我们进入在 Elasticsearch 中发生的分析的两个阶段,即索引时间分析和搜索时间分析。
3.1 索引时间分析
让我们考虑以下文档进行索引
curl -XPOST localhost:9200/testindex-0203/testtype/1 -d ‘{
“text”: “My name is Arun”
}’
由于我们没有使用分析器,因此 Elasticsearch 对此应用了默认的分析器“标准分析器”。让我们在分析 API 的帮助下,查看上述文档与 Standard Analyser 一起使用时的最终标记
curl -XPOST ‘localhost:9200/_analyze?pretty’ -H ‘Content-Type: application/json’ -d'{
“analyzer”: “standard”,
“text”: “My name is Arun”
}’
用于存储在倒排索引中的令牌是:
“我的”,“姓名”,“是”,“阿伦”
倒排的索引如下表所示:
这整个过程发生在索引时间中,因此发生在名称索引时间分析中。
3.2 搜索时间分析
顾名思义,搜索时间分析将在搜索时发生。但是有一个区别,就是这种分析是在查询上进行的,具体取决于所使用的查询。
3.2.1 术语查询 - 情况 1
考虑以下查询:
curl -XPOST localhost:9200/testindex-0203/testtype/_search -d ‘{
“query”: {
“term”: {“text”:“name”}
}
}’
如果我们对索引“testindex-0203”运行此查询,它将返回被索引的文档作为结果。标记“名称”存在于反向索引中,并再次映射到文档 1。因此,当我们搜索术语“名称”时,它将查找反向索引,并且由于找到了该术语,因此相应的文档被提取为结果。
3.2.2 术语查询 - 案例 2
现在考虑具有相同“条件”查询的另一种情况,如下所示:
curl -XPOST localhost:9200/testindex-0203/testtype/_search -d ‘{
“query”: {
“term”: {“text”:“Name”}
}
}’
在这里,我们使用相同的术语查询来进行查询,但是对于搜索关键字使用不同的大小写,其现在是“名称”而不是“名称”。现在发生了一些有趣的事情,此搜索不会给我们找到任何文件。这种奇怪行为的原因是,倒排索引中不存在“名称”,因此没有要显示的文档。
因此,对于“术语”查询,不允许对搜索关键字进行任何分析。
3.2.3 术语查询 - 情况 3
让我们考虑术语查询的另一种情况以查看此行为,这是查询
curl -XPOST localhost:9200/testindex-0203/testtype/_search -d ‘{
“query”: {
“term”: {“text”:“My name”}
}
}’
在上述情况下,没有分析搜索关键字,因此,Elasticsearch 在反向索引中寻找令牌“我的名字”。并且由于此类术语不存在,因此针对上述查询,elasticsearch 也将返回零结果。
在 Elasticsearch 中就是“条件”查询的情况。让我们尝试一个不同的查询,称为 match query 并检查输出。
3.2.4 匹配查询 - 情况 1
考虑以下查询:
curl -XPOST localhost:9200/testindex-0203/testtype/_search -d ‘{
“query”: {
“term”: {“text”:“My name”}
}
}’
这将返回带有索引文档的响应,因为反向索引中存在“名称”令牌。
3.2.5 匹配查询 - 情况 2
curl -XPOST localhost:9200/testindex-0203/testtype/_search -d ‘{
“query”: {
“match”: {“text”:“Name”}
}
}’
在这里,当我们对案例 2 使用“条件”查询时,没有任何响应。但是,对于匹配查询,无论在索引编制时将什么分析应用于要查询的字段(文本),都将对搜索关键字(“名称”)进行完全相同的分析。这使搜索关键字经历“标准分析”,并且搜索关键字“名称”更改为“名称”(由于标准分析器中的小写标记过滤器)。这个新的搜索关键字“名称”存在于反向索引中,并且响应也将具有相应的文档。
3.2.6 匹配查询 - 情况 3
curl -XPOST localhost:9200/testindex-0203/testtype/_search -d ‘{
“query”: {
“match”: {“text”:“My name”}
}
}’
这里给出的搜索关键字是“My name”,经过标准分析后,它将转换为关键字“我的名字”和“名字”。这两个关键字都存在于反向索引中,因此将文档作为响应返回。
因此,根据查询类型,搜索关键字将在搜索时间内进行分析(与查询的字段相同)。这称为搜索时间分析。
结论
在此博客中,我介绍了分析器的基本组成部分以及 Elasticsearch 中发生的分析类型。在下一个博客中,我们将看到如何针对非常特定的用例构建自己的自定义分析器。