索引和搜索分析
文本分析发生在两个时间点
- 索引时
- 当文档被索引时,任何
text字段的值都会被分析。 - 搜索时
-
在
text字段上进行 全文搜索 时,查询字符串(用户正在搜索的文本)会被分析。搜索时也称为查询时。有关搜索时文本分析的更多详细信息,请参阅 搜索期间的文本分析。
在每个时间点使用的分析器(或分析规则集)分别称为索引分析器或搜索分析器。
在大多数情况下,索引时和搜索时应使用相同的分析器。这确保了字段的值和查询字符串被转换为相同形式的 token。反过来,这确保了 token 在搜索过程中能按预期匹配。
示例
文档在 text 字段中以以下值被索引
The QUICK brown foxes jumped over the dog!
该字段的索引分析器将值转换为 token 并对其进行标准化。在本例中,每个 token 代表一个单词
[ quick, brown, fox, jump, over, dog ]
这些 token 随后被索引。
稍后,用户在同一个 text 字段中搜索
"Quick fox"
用户期望此搜索能匹配之前索引的句子 The QUICK brown foxes jumped over the dog!。
然而,查询字符串并不包含文档原始文本中使用的确切单词
Quick与QUICKfox与foxes
为了解决这个问题,使用相同的分析器对查询字符串进行分析。该分析器会产生以下 token
[ quick, fox ]
为了执行搜索,Elasticsearch 会将这些查询字符串的 token 与 text 字段中索引的 token 进行比较。
| 令牌 (Token) | Query string | text 字段 |
|---|---|---|
quick |
X | X |
brown |
X | |
fox |
X | X |
jump |
X | |
over |
X | |
dog |
X |
由于字段值和查询字符串以相同的方式被分析,它们产生了相似的 token。token quick 和 fox 是精确匹配的。这意味着搜索匹配到了包含 "The QUICK brown foxes jumped over the dog!" 的文档,正如用户所期望的那样。
虽然不太常见,但有时在索引时和搜索时使用不同的分析器是有意义的。为了实现这一点,Elasticsearch 允许您 指定单独的搜索分析器。
通常,仅当对字段值和查询字符串使用相同形式的 token 会导致意外或不相关的搜索匹配时,才应指定单独的搜索分析器。
示例
Elasticsearch 用于创建一个仅匹配以提供的前缀开头的单词的搜索引擎。例如,搜索 tr 应返回 tram 或 trope,但绝不应返回 taxi 或 bat。
一个文档被添加到搜索引擎的索引中;该文档在 text 字段中包含一个这样的单词
"Apple"
该字段的索引分析器将值转换为 token 并对其进行标准化。在本例中,每个 token 都代表单词的一个潜在前缀
[ a, ap, app, appl, apple]
这些 token 随后被索引。
稍后,用户在同一个 text 字段中搜索
"appli"
用户期望此搜索仅匹配以 appli 开头的单词,例如 appliance 或 application。该搜索不应匹配 apple。
然而,如果使用索引分析器来分析此查询字符串,它将产生以下 token
[ a, ap, app, appl, appli ]
当 Elasticsearch 将这些查询字符串的 token 与为 apple 索引的 token 进行比较时,它会发现几个匹配项。
| 令牌 (Token) | appli |
apple |
|---|---|---|
a |
X | X |
ap |
X | X |
app |
X | X |
appl |
X | X |
appli |
X |
这意味着搜索会错误地匹配到 apple。不仅如此,它还会匹配任何以 a 开头的单词。
为了解决这个问题,您可以为 text 字段上使用的查询字符串指定一个不同的搜索分析器。
在本例中,您可以指定一个产生单个 token 而不是一组前缀的搜索分析器
[ appli ]
此查询字符串 token 将仅匹配以 appli 开头的单词的 token,这更符合用户的搜索预期。