Link Search Menu Expand Document Documentation Menu

您是不是要找

Did-you-mean 建议器会显示拼写错误的搜索词的建议更正。

例如,如果用户输入“fliud”,OpenSearch 会建议更正后的搜索词,例如“fluid”。然后您可以向用户建议更正后的词语,甚至自动更正搜索词。

您可以通过以下方法之一实现 did-you-mean 建议器

词元建议器

使用词元建议器来建议单个词语的拼写更正。词元建议器使用 编辑距离 来计算建议。

编辑距离是指一个词元需要通过单个字符的插入、删除或替换操作来匹配另一个词元所需的次数。例如,要将单词“cat”更改为“hats”,您需要用“h”替换“c”并插入一个“s”,因此在这种情况下,编辑距离为 2。

要使用词元建议器,您不需要为索引设置任何特殊字段映射。默认情况下,字符串字段类型被映射为 texttext 字段会被分析,因此以下示例中的 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_tagpost_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"
        }
      }
    }
  }
}

结果建议包含设置为 truecollate_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 在将每个生成的建议传递给短语评分器之前,应用于每个生成的建议的分析器。
剩余 350 字符

有问题?

想贡献?