您是不是要找
Did-you-mean
建议器会显示拼写错误的搜索词的建议更正。
例如,如果用户输入“fliud”,OpenSearch 会建议更正后的搜索词,例如“fluid”。然后您可以向用户建议更正后的词语,甚至自动更正搜索词。
您可以通过以下方法之一实现 did-you-mean
建议器
词元建议器
使用词元建议器来建议单个词语的拼写更正。词元建议器使用 编辑距离 来计算建议。
编辑距离是指一个词元需要通过单个字符的插入、删除或替换操作来匹配另一个词元所需的次数。例如,要将单词“cat”更改为“hats”,您需要用“h”替换“c”并插入一个“s”,因此在这种情况下,编辑距离为 2。
要使用词元建议器,您不需要为索引设置任何特殊字段映射。默认情况下,字符串字段类型被映射为 text
。text
字段会被分析,因此以下示例中的 title
会被分词为单个词语。索引以下文档会创建一个 books
索引,其中 title
是一个 text
字段
PUT books/_doc/1
{
"title": "Design Patterns (Object-Oriented Software)"
}
PUT books/_doc/2
{
"title": "Software Architecture Patterns Explained"
}
要检查字符串如何被拆分为词元,您可以使用 _analyze
端点。要应用字段使用的相同分析器,您可以在 field
参数中指定字段名称
GET books/_analyze
{
"text": "Design Patterns (Object-Oriented Software)",
"field": "title"
}
默认分析器 (standard
) 会在单词边界处分割字符串,删除标点符号,并将词元转换为小写。
{
"tokens" : [
{
"token" : "design",
"start_offset" : 0,
"end_offset" : 6,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "patterns",
"start_offset" : 7,
"end_offset" : 15,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "object",
"start_offset" : 17,
"end_offset" : 23,
"type" : "<ALPHANUM>",
"position" : 2
},
{
"token" : "oriented",
"start_offset" : 24,
"end_offset" : 32,
"type" : "<ALPHANUM>",
"position" : 3
},
{
"token" : "software",
"start_offset" : 33,
"end_offset" : 41,
"type" : "<ALPHANUM>",
"position" : 4
}
]
}
要获取拼写错误的搜索词的建议,请使用词元建议器。在 text
字段中指定需要建议的输入文本,并在 field
字段中指定从中获取建议的字段
GET books/_search
{
"suggest": {
"spell-check": {
"text": "patern",
"term": {
"field": "title"
}
}
}
}
词元建议器在 options
数组中返回输入文本的更正列表
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"suggest" : {
"spell-check" : [
{
"text" : "patern",
"offset" : 0,
"length" : 6,
"options" : [
{
"text" : "patterns",
"score" : 0.6666666,
"freq" : 2
}
]
}
]
}
}
score
值是根据编辑距离计算的。分数越高,建议越好。freq
表示词元在指定索引文档中出现的次数。
您可以在一个请求中包含多个建议。以下示例使用词元建议器进行两种不同的建议
GET books/_search
{
"suggest": {
"spell-check1" : {
"text" : "patern",
"term" : {
"field" : "title"
}
},
"spell-check2" : {
"text" : "desing",
"term" : {
"field" : "title"
}
}
}
}
要在多个字段中接收相同输入文本的建议,您可以全局定义文本以避免重复
GET books/_search
{
"suggest": {
"text" : "patern",
"spell-check1" : {
"term" : {
"field" : "title"
}
},
"spell-check2" : {
"term" : {
"field" : "subject"
}
}
}
}
如果 text
在全局和单个建议级别都指定了,则建议级别的值将覆盖全局值。
词元建议器选项
您可以为词元建议器指定以下选项。
选项 | 描述 |
---|---|
field | 从中获取建议的字段。必填。可以为每个建议单独设置或全局设置。 |
分析器 | 用于分析输入文本的分析器。默认为为 field 配置的分析器。 |
size | 为输入文本中的每个词元返回的最大建议数量。 |
sort(排序) | 指定响应中建议的排序方式。有效值为 - score :按相似度分数排序,然后按文档频率排序,最后按词元本身排序。- frequency :按文档频率排序,然后按相似度分数排序,最后按词元本身排序。 |
suggest_mode | 建议模式指定了响应中应包含建议的词元。有效值为 - missing :仅为索引中指定字段中出现次数为零的输入词元返回建议。此检查是字段特定的:如果词元出现在其他字段中但未出现在目标字段中,则仍被视为缺失。请注意,此模式不考虑整个索引中的词元频率——仅考虑指定字段。- popular :仅当建议在文档中出现的频率高于原始输入文本时才返回建议。- always :始终为输入文本中的每个词元返回建议。默认值为 missing 。 |
max_edits | 建议的最大编辑距离。有效值在 [1, 2] 范围内。默认值为 2。 |
prefix_length | 一个整数,指定匹配前缀的最小长度,必须达到此长度才能开始返回建议。如果 prefix_length 的前缀不匹配,但搜索词仍在编辑距离内,则不返回任何建议。默认值为 1。较高的值可以提高拼写检查性能,因为拼写错误通常不会出现在单词的开头。 |
min_word_length | 建议必须达到的最小长度,才能包含在响应中。默认值为 4。 |
shard_size(分片大小) | 从每个分片获取的最大候选建议数量。考虑所有候选建议后,返回前 shard_size 个建议。默认值等于 size 值。分片级别的文档频率可能不精确,因为词元可能存在于不同的分片中。如果 shard_size 大于 size ,则建议的文档频率将更准确,但会降低性能。 |
max_inspections | shard_size 的乘数。OpenSearch 检查以查找建议的最大候选建议数量是 shard_size 乘以 max_inspection 计算得出的。这可能会提高准确性,但会降低性能。默认值为 5。 |
min_doc_freq | 建议必须出现在文档中的最小数量或百分比,才能返回该建议。通过仅返回具有高分片级文档频率的建议,可以提高准确性。有效值为表示文档频率的整数或表示文档百分比的 [0, 1] 范围内的浮点数。默认值为 0(功能禁用)。 |
max_term_freq | 建议必须出现在文档中的最大数量,才能返回该建议。有效值为表示文档频率的整数或表示文档百分比的 [0, 1] 范围内的浮点数。默认值为 0.01。排除高频词元可以提高拼写检查性能,因为高频词元通常拼写正确。使用分片级文档频率。 |
string_distance | 用于确定相似度的编辑距离算法。有效值为 - internal :默认算法,基于 达梅罗-莱文斯坦算法,但针对比较索引中词元的编辑距离进行了高度优化。- damerau_levenshtein :基于 达梅罗-莱文斯坦算法 的编辑距离算法。- levenshtein :基于 莱文斯坦编辑距离算法 的编辑距离算法。- jaro_winkler :基于 贾罗-温克勒算法 的编辑距离算法。- ngram :基于字符 n-gram 的编辑距离算法。 |
短语建议器
要实现 did-you-mean
,请使用短语建议器。短语建议器与词元建议器类似,但它使用 n-gram 语言模型来建议整个短语而不是单个词语。
要设置短语建议器,请创建一个名为 trigram
的自定义分析器,该分析器使用 shingle
过滤器并小写词元。此过滤器类似于 edge_ngram
过滤器,但它适用于单词而不是字母。然后使用您创建的自定义分析器配置用于获取建议的字段
PUT books2
{
"settings": {
"index": {
"analysis": {
"analyzer": {
"trigram": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"shingle"
]
}
},
"filter": {
"shingle": {
"type": "shingle",
"min_shingle_size": 2,
"max_shingle_size": 3
}
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"fields": {
"trigram": {
"type": "text",
"analyzer": "trigram"
}
}
}
}
}
}
将文档索引到新索引中
PUT books2/_doc/1
{
"title": "Design Patterns"
}
PUT books2/_doc/2
{
"title": "Software Architecture Patterns Explained"
}
假设用户搜索了错误的短语
GET books2/_search
{
"suggest": {
"phrase-check": {
"text": "design paterns",
"phrase": {
"field": "title.trigram"
}
}
}
}
短语建议器返回更正后的短语
{
"took" : 4,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"suggest" : {
"phrase-check" : [
{
"text" : "design paterns",
"offset" : 0,
"length" : 14,
"options" : [
{
"text" : "design patterns",
"score" : 0.31666178
}
]
}
]
}
}
要突出显示建议,请为短语建议器设置 highlight
字段
GET books2/_search
{
"suggest": {
"phrase-check": {
"text": "design paterns",
"phrase": {
"field": "title.trigram",
"gram_size": 3,
"highlight": {
"pre_tag": "<em>",
"post_tag": "</em>"
}
}
}
}
}
结果包含高亮文本
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"suggest" : {
"phrase-check" : [
{
"text" : "design paterns",
"offset" : 0,
"length" : 14,
"options" : [
{
"text" : "design patterns",
"highlighted" : "design <em>patterns</em>",
"score" : 0.31666178
}
]
}
]
}
}
短语建议器选项
您可以为短语建议器指定以下选项。
选项 | 描述 |
---|---|
field | 用于 n-gram 查找的字段。短语建议器使用此字段计算建议分数。必填。 |
gram_size | 字段中 n-gram(分词串)的最大大小 n 。如果字段不包含 n-gram(分词串),则省略此选项或将其设置为 1。如果字段使用 shingle 过滤器且未设置 gram_size ,则 gram_size 将设置为 max_shingle_size 。 |
real_word_error_likelihood | 即使词元存在于词典中,其拼写错误的概率。默认值为 0.95(词典中 5% 的单词拼写错误)。 |
confidence | 置信度是一个浮点因子,它与输入短语的分数相乘,以计算其他建议的阈值分数。只有分数高于阈值的建议才会被返回。如果置信度为 1.0,则只会返回分数高于输入短语的建议。如果 confidence 设置为 0,则返回前 size 个候选。默认值为 1。 |
max_errors | 可以错误的(拼写不正确)词元的最大数量或百分比,以便返回建议。有效值为表示词元数量的整数,或表示词元百分比的 (0, 1) 范围内的浮点数。默认值为 1(仅返回最多一个拼写错误的词元的建议)。将此值设置得很高可能会降低性能。我们建议将 max_errors 设置为较低的数字,例如 1 或 2,以减少建议调用相对于查询执行所花费的时间。 |
separator | 在二元词字段中词元的分隔符。默认为空格字符。 |
size | 每个查询词生成的候选建议数量。指定更高的值可能会返回编辑距离更大的词语。默认值为 5。 |
分析器 | 用于分析建议文本的分析器。默认为为 field 配置的分析器。 |
shard_size(分片大小) | 从每个分片获取的候选建议的最大数量。考虑所有候选建议后,返回排名前 shard_size 的建议。默认值为 5。 |
collate | 用于修剪索引中没有匹配文档的建议。 |
collate.query | 指定一个查询,用于检查建议以修剪索引中没有匹配文档的建议。 |
collate.prune | 指定是否返回所有建议。如果 prune 设置为 false ,则仅返回具有匹配文档的建议。如果 prune 设置为 true ,则返回所有建议;每个建议都带有一个额外的 collate_match 字段,如果建议有匹配文档则为 true ,否则为 false 。默认值为 false 。 |
highlight | 配置建议高亮显示。需要同时提供 pre_tag 和 post_tag 值。 |
highlight.pre_tag | 高亮显示的起始标签。 |
highlight.post_tag | 高亮显示的结束标签。 |
smoothing | 平滑模型,用于平衡索引中频繁出现的 shingle 与不频繁出现的 shingle 的权重。 |
Collate 字段
为了过滤掉不会返回任何结果的拼写检查建议,您可以使用 collate
字段。该字段包含一个脚本查询,针对每个返回的建议运行。有关构建模板化查询的信息,请参阅搜索模板。您可以使用 {{suggestion}}
变量指定当前建议,或者在 params
字段中传递您自己的模板参数(建议值将添加到您指定的变量中)。
建议的 collate 查询仅在其来源分片上运行。此查询是必需的。
此外,如果 prune
参数设置为 true
,则会为每个建议添加一个 collate_match
字段。如果查询没有返回结果,则 collate_match
的值为 false
。然后您可以根据 collate_match
字段过滤建议。 prune
参数的默认值为 false
。
例如,以下查询将 collate
字段配置为运行一个 match_phrase
查询,将 title
字段与当前建议进行匹配
GET books2/_search
{
"suggest": {
"phrase-check": {
"text": "design paterns",
"phrase": {
"field": "title.trigram",
"collate" : {
"query" : {
"source": {
"match_phrase" : {
"title": ""
}
}
},
"prune": "true"
}
}
}
}
}
结果建议包含设置为 true
的 collate_match
字段,这意味着 match_phrase
查询将为该建议返回匹配文档。
{
"took" : 7,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"suggest" : {
"phrase-check" : [
{
"text" : "design paterns",
"offset" : 0,
"length" : 14,
"options" : [
{
"text" : "design patterns",
"score" : 0.56759655,
"collate_match" : true
}
]
}
]
}
}
平滑模型
对于大多数用例,在计算建议的分数时,您不仅要考虑 shingle 的频率,还要考虑 shingle 的大小。平滑模型用于计算不同大小 shingle 的分数,平衡频繁和不频繁 shingle 的权重。
支持以下平滑模型。
模型 | 描述 |
---|---|
stupid_backoff | 如果高阶 n-gram 计数为 0,则回退到低阶 n-gram 模型,并将低阶 n-gram 模型乘以一个常数因子(discount )。这是默认的平滑模型。 |
stupid.backoff.discount | 乘以低阶 n-gram 模型的因子。可选。默认值为 0.4。 |
laplace | 使用加法平滑,将常数 alpha 添加到所有计数中以平衡权重。 |
laplace.alpha | 添加到所有计数中以平衡权重的常数,通常为 1.0 或更小。可选。默认值为 0.5。 |
默认情况下,OpenSearch 使用 Stupid Backoff 模型——一个简单的算法,它从最高阶的 shingle 开始,如果未找到更高阶的 shingle,则采用低阶 shingle。例如,如果您将短语建议器设置为包含 3-gram、2-gram 和 1-gram,则 Stupid Backoff 模型首先检查 3-gram。如果没有 3-gram,它会检查 2-gram 但将分数乘以 discount
因子。如果没有 2-gram,它会检查 1-gram 但再次将分数乘以 discount
因子。Stupid Backoff 模型在大多数情况下效果很好。如果需要选择 Laplace 平滑模型,请在 smoothing
参数中指定。
GET books2/_search
{
"suggest": {
"phrase-check": {
"text": "design paterns",
"phrase": {
"field": "title.trigram",
"size" : 1,
"smoothing" : {
"laplace" : {
"alpha" : 0.7
}
}
}
}
}
}
候选生成器
候选生成器根据输入文本中的词语提供可能的建议词。目前有一个可用的候选生成器——direct_generator
。直接生成器的工作方式类似于词语建议器:它也针对输入文本中的每个词语进行调用。短语建议器支持多个候选生成器,每个生成器都会为输入文本中的每个词语调用。它还允许您指定一个预过滤器(在拼写检查阶段之前分析输入文本词语的分析器)和一个后过滤器(在返回生成的建议之前分析它们的分析器)。
为短语建议器设置直接生成器
GET books2/_search
{
"suggest": {
"text": "design paterns",
"phrase-check": {
"phrase": {
"field": "title.trigram",
"size": 1,
"direct_generator": [
{
"field": "title.trigram",
"suggest_mode": "always",
"min_word_length": 3
}
]
}
}
}
}
您可以指定以下直接生成器选项。
选项 | 描述 |
---|---|
field | 从中获取建议的字段。必填。可以为每个建议单独设置或全局设置。 |
size | 为输入文本中的每个词元返回的最大建议数量。 |
suggest_mode | 建议模式指定了每个分片上生成的建议应包含的词语。建议模式应用于每个分片的建议,并且在合并来自不同分片的建议时不会进行检查。因此,如果建议模式是 missing ,即使某个词语在一个分片中缺失但在另一个分片中存在,也会返回建议。有效值包括:- missing : 仅返回分片中不存在的输入文本词语的建议。- popular : 仅当建议在分片文档中出现的频率高于原始输入文本时才返回建议。- always : 始终返回建议。默认值为 missing 。 |
max_edits | 建议的最大编辑距离。有效值在 [1, 2] 范围内。默认值为 2。 |
prefix_length | 一个整数,指定匹配前缀的最小长度,达到该长度后才开始返回建议。如果未匹配到 prefix_length 的前缀,但搜索词仍在编辑距离内,则不返回任何建议。默认值为 1。较高的值可以提高拼写检查性能,因为拼写错误通常不会出现在单词的开头。 |
min_word_length | 建议被包含所需的最小长度。默认值为 4。 |
max_inspections | shard_size 的乘数。OpenSearch 检查以查找建议的最大候选建议数量是 shard_size 乘以 max_inspection 计算得出的。这可能会提高准确性,但会降低性能。默认值为 5。 |
min_doc_freq | 建议必须出现的最小文档数量或百分比,才能被返回。通过仅返回具有高分片级文档频率的建议,可以提高准确性。有效值是表示文档频率的整数,或表示文档百分比的 [0, 1] 范围内的浮点数。默认值为 0(功能禁用)。 |
max_term_freq | 建议必须出现在文档中的最大数量,才能返回该建议。有效值为表示文档频率的整数或表示文档百分比的 [0, 1] 范围内的浮点数。默认值为 0.01。排除高频词元可以提高拼写检查性能,因为高频词元通常拼写正确。使用分片级文档频率。 |
pre_filter | 在生成建议之前,应用于传递给生成器的每个输入文本标记的分析器。 |
post_filter | 在将每个生成的建议传递给短语评分器之前,应用于每个生成的建议的分析器。 |