文本分析概念
edit文本分析概念
edit本节解释了Elasticsearch中文本分析的基本概念。
分析器的剖析
edit一个分析器 —— 无论是内置的还是自定义的 —— 只是一个包含三个底层构建块的包:字符过滤器、分词器和词元过滤器。
内置的 分析器 预先将这些构建块打包成适用于不同语言和文本类型的分析器。
Elasticsearch 还公开了各个构建块,以便它们可以组合起来定义新的 自定义 分析器。
字符过滤器
edit一个字符过滤器接收原始文本作为字符流,并可以通过添加、删除或更改字符来转换流。例如,字符过滤器可以用于将阿拉伯-印度数字(٠١٢٣٤٥٦٧٨٩)转换为其阿拉伯-拉丁等效数字(0123456789),或者从流中去除HTML元素,如。
一个分析器可以有零个或多个 字符过滤器,它们按顺序应用。
分词器
edit一个分词器接收一个字符流,将其分解成单独的词元(通常是单个单词),并输出一个词元流。例如,一个空白分词器在看到任何空白时将文本分解成词元。它会将文本"Quick brown fox!"转换为词元[Quick, brown, fox!]。
分词器还负责记录每个词项的顺序或位置,以及该词项所代表的原始单词的开始和结束字符偏移量。
一个分析器必须有恰好一个 分词器。
词元过滤器
edit一个分词过滤器接收分词流,并可以添加、删除或更改分词。例如,一个lowercase分词过滤器将所有分词转换为小写,一个
stop分词过滤器移除常见词(停止词)如the从分词流中,以及一个
synonym分词过滤器将同义词引入分词流中。
Token filters 不允许改变每个token的位置或字符偏移量。
一个分析器可以有零个或多个 token filters,它们按顺序应用。
索引和搜索分析
edit文本分析发生在两个时间点:
每次使用的分析器或分析规则集分别称为索引分析器或搜索分析器。
索引和搜索分析器如何协同工作
edit在大多数情况下,索引和搜索时应使用相同的分析器。这确保了字段值和查询字符串被转换为相同的令牌形式。反过来,这确保了在搜索过程中令牌能够按预期匹配。
示例
一个文档在一个文本字段中被索引为以下值:
The QUICK brown foxes jumped over the dog!
字段的索引分析器将值转换为标记并对其进行规范化。在这种情况下,每个标记代表一个单词:
[ quick, brown, fox, jump, over, dog ]
这些令牌随后被索引。
后来,用户在相同的文本字段中搜索:
"Quick fox"
用户期望这次搜索能匹配之前索引的句子,
The QUICK brown foxes jumped over the dog!。
然而,查询字符串并不包含文档原始文本中使用的精确词语:
-
Quick对比QUICK -
fox对比foxes
为了解决这个问题,查询字符串使用相同的分析器进行分析。该分析器生成以下标记:
[ quick, fox ]
要执行搜索,Elasticsearch 会将这些查询字符串标记与 text 字段中索引的标记进行比较。
| Token | Query string | text field |
|---|---|---|
|
X |
X |
|
X |
|
|
X |
X |
|
X |
|
|
X |
|
|
X |
因为字段值和查询字符串以相同的方式进行了分析,它们生成了相似的词元。词元quick和fox是完全匹配的。这意味着搜索匹配了包含"The QUICK brown foxes jumped over the dog!"的文档,正如用户所期望的那样。
何时使用不同的搜索分析器
edit虽然不太常见,但在某些情况下,在索引和搜索时使用不同的分析器是有意义的。为此,Elasticsearch允许您指定一个单独的搜索分析器。
通常情况下,只有在使用相同形式的标记进行字段值和查询字符串时,会产生意外或不相关的搜索匹配时,才应指定单独的搜索分析器。
示例
Elasticsearch 用于创建一个搜索引擎,该引擎仅匹配以提供的前缀开头的单词。例如,搜索 tr 应返回 tram 或 trope——但绝不会返回 taxi 或 bat。
一个文档被添加到搜索引擎的索引中;该文档在一个文本字段中包含这样一个词:
"Apple"
字段的索引分析器将值转换为标记并对其进行规范化。在这种情况下,每个标记都代表该词的一个潜在前缀:
[ a, ap, app, appl, apple]
这些令牌随后被索引。
后来,用户在相同的文本字段中搜索:
"appli"
用户期望此搜索仅匹配以appli开头的单词,例如appliance或application。搜索不应匹配apple。
然而,如果使用索引分析器来分析这个查询字符串,它将产生以下标记:
[ a, ap, app, appl, appli ]
当Elasticsearch将这些查询字符串标记与为apple索引的标记进行比较时,它会找到多个匹配项。
| Token | appli |
apple |
|---|---|---|
|
X |
X |
|
X |
X |
|
X |
X |
|
X |
X |
|
X |
这意味着搜索会错误地匹配apple。不仅如此,它还会匹配任何以a开头的单词。
要解决这个问题,您可以为在text字段上使用的查询字符串指定一个不同的搜索分析器。
在这种情况下,您可以指定一个生成单个词元的搜索分析器,而不是一组前缀:
[ appli ]
此查询字符串标记将仅匹配以
appli开头的单词的标记,这更符合用户的搜索预期。
词干提取
edit词干提取是将一个单词缩减为其词根形式的过程。这确保了在搜索过程中单词的变体能够匹配。
例如,walking 和 walked 可以被词干提取为相同的词根:
walk。一旦被词干提取,这两个词中的任何一个在搜索中都会匹配另一个。
词干提取是依赖于语言的,但通常涉及从单词中去除前缀和后缀。
在某些情况下,词干化后的词根可能不是一个真实的词。例如,jumping 和 jumpiness 都可以被词干化为 jumpi。虽然 jumpi 不是一个真实的英语单词,但这对于搜索来说并不重要;如果一个词的所有变体都被简化为相同的词根形式,它们将会正确匹配。
词干提取器令牌过滤器
edit在Elasticsearch中,词干提取由词干器分词过滤器处理。这些分词过滤器可以根据它们提取词干的方式进行分类:
因为词干提取会改变词元,我们建议在索引和搜索分析期间使用相同的词干提取器词元过滤器。
算法词干提取器
edit算法词干提取器对每个单词应用一系列规则,将其简化为词根形式。例如,英语的算法词干提取器可能会去除复数单词末尾的-s和-es后缀。
算法词干提取器有一些优势:
- 它们几乎不需要设置,通常开箱即用。
- 它们占用很少的内存。
- 它们通常比字典词干提取器更快。
然而,大多数算法词干提取器仅改变单词的现有文本。这意味着它们可能无法很好地处理不规则单词,这些单词不包含其词根形式,例如:
-
be,are, 和am -
mouse和mice -
foot和feet
以下标记过滤器使用算法词干提取:
-
stemmer,为多种语言提供算法词干提取,其中一些语言有额外的变体。 -
kstem,一种结合了算法词干提取和内置词典的英语词干提取器。 -
porter_stem,我们推荐的英语算法词干提取器。 -
snowball,使用基于Snowball的词干提取规则为多种语言提供支持。
字典词干提取器
edit字典词干提取器在提供的字典中查找单词,将未词干化的单词变体替换为字典中的词干化单词。
理论上,字典词干提取器非常适合用于:
- 词干提取不规则单词
-
辨别拼写相似但概念上无关的词语,例如:
-
organ和organization -
broker和broken
-
在实践中,算法词干提取器通常优于字典词干提取器。这是因为字典词干提取器具有以下缺点:
-
字典质量
字典词干提取器的质量取决于其字典。为了表现良好,这些字典必须包含大量词汇,定期更新,并随语言趋势变化。通常,当一个字典发布时,它可能已经不完整,并且其中的一些条目已经过时。 -
大小和性能
字典词干提取器必须将其字典中的所有单词、前缀和后缀加载到内存中。这可能会占用大量内存。低质量的字典在处理前缀和后缀移除时也可能效率较低,这会显著减慢词干提取过程。
您可以使用 hunspell 分词过滤器来执行字典词干提取。
如果可用,我们建议在尝试使用 hunspell 分词过滤器之前,先尝试使用您语言的算法词干提取器。
控制词干提取
edit有时词干提取会产生拼写相似但概念上无关的共享根词。例如,词干提取器可能会将 skies 和 skiing 都简化为相同的根词:ski。
为了防止这种情况并更好地控制词干提取,您可以使用以下令牌过滤器:
-
stemmer_override,它允许你定义特定词干的规则。 -
keyword_marker,它将指定的标记标记为关键字。关键字标记不会被后续的词干化标记过滤器处理。 -
conditional,它可以用来将标记标记为关键字,类似于keyword_marker过滤器。
对于内置的语言分析器,您还可以使用
stem_exclusion参数来指定一个不会被词干化的单词列表。
代币图表
edit当一个分词器将文本转换为一系列标记时,它还会记录以下内容:
-
每个标记在流中的
位置 -
标记跨越的
位置长度,即标记跨越的位置数量
使用这些,您可以创建一个 有向无环图, 称为令牌图,用于一个流。在令牌图中,每个位置代表一个节点。每个令牌代表一条边或弧,指向下一位置。
同义词
edit一些 token filters 可以向现有的 token 流中添加新的 tokens,例如同义词。这些同义词通常与现有 tokens 占据相同的位置。
在下面的图中,quick 及其同义词 fast 的位置都是 0。它们占据了相同的位置。
多位置令牌
edit一些标记过滤器可以添加跨越多个位置的标记。这些可以包括多词同义词的标记,例如使用“atm”作为“自动取款机”的同义词。
然而,只有一些标记过滤器,称为图标记过滤器,能够准确记录多位置标记的positionLength。这些过滤器包括:
一些分词器,例如
nori_tokenizer,也能够准确地将复合词分解为多位置词。
在下面的图中,域名系统 及其同义词 dns 都具有 0 的位置。然而,dns 的 positionLength 为 3。图中的其他标记的默认 positionLength 为 1。
使用令牌图进行搜索
edit索引忽略positionLength属性,并且不支持包含多位置标记的标记图。
然而,像match或
match_phrase这样的查询,可以使用这些图表从单个查询字符串生成多个子查询。
示例
用户使用match_phrase查询对以下短语进行搜索:
域名系统是脆弱的
在搜索分析期间,dns(domain name system的同义词)被添加到查询字符串的标记流中。dns标记的positionLength为3。
The match_phrase query 使用此图表为以下短语生成子查询:
dns is fragile domain name system is fragile
这意味着查询匹配包含以下任一内容的文档:dns is fragile 或
domain name system is fragile。
无效的令牌图
edit以下标记过滤器可以添加跨越多个位置的标记,但仅记录默认的positionLength为1:
这意味着这些过滤器将对包含此类令牌的流生成无效的令牌图。
在下面的图中,dns 是 domain name system 的多位置同义词。然而,dns 的默认 positionLength 值为 1,导致图表无效。
避免使用无效的令牌图进行搜索。无效的图可能导致意外的搜索结果。