原英文版地址: https://www.elastic.co/guide/en/elasticsearch/reference/7.7/search-as-you-type.html, 原文档版权归 www.elastic.co 所有
本地英文版地址: ../en/search-as-you-type.html

search_as_you_type(输入即搜索)数据类型

search_as_you_type字段类型是一种类似文本的字段,它经过优化,为服务于随输入补全用例的查询提供开箱即用的支持。 它创建了一系列子字段,对这些子字段进行分析,以索引能够被部分匹配整个索引文本值的查询有效匹配的词项。 前缀补全(即匹配输入开头的词项)和中缀补全(即匹配输入中任何位置的词项)都受支持。

当将这种类型的字段添加到映射时

PUT my_index
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "search_as_you_type"
      }
    }
  }
}

这将创建以下字段:

my_field

这个字段会按照映射中的配置进行分析。如果没有配置分析器,则使用索引的默认分析器

my_field._2gram

用瓦片(shingle)大小为 2 的瓦片词元过滤器包装my_field的分析器

my_field._3gram

用分块(shingle)大小为 3 的分块词元过滤器包装my_field的分析器

my_field._index_prefix

使用一个 edge ngram 词元过滤器包装my_field._3gram的分析器

子字段中分块的大小可以通过映射参数max_shingle_size来配置。 默认值为 3,该参数的有效值为 2 - 4 之间的整数值。 将为从 2 到 max_shingle_size(包括最大值)的每个分块大小创建分块子字段。 my_field._index_prefix子字段在构建自己的分析器时,将始终使用具有max_shingle_size的分块子字段中的分析器。

增加max_shingle_size的值,将提高具有更多连续词项的查询的匹配度,但代价是索引更大。 默认的max_shingle_size通常就足够了。

当被索引的文档具有根字段my_field的值时,相同的输入文本被自动索引到这些字段中的每一个中,具有各自不同的分析链。

PUT my_index/_doc/1?refresh
{
  "my_field": "quick brown fox jump lazy dog"
}

最有效的查询方式通常是bool_prefix类型的multi_match查询,其目标是根search_as_you_type字段及其分块子字段。 这可以以任何顺序匹配查询词项,但是如果文档在一个分块子字段中按顺序包含这些词项,那么文档的得分会更高。

GET my_index/_search
{
  "query": {
    "multi_match": {
      "query": "brown f",
      "type": "bool_prefix",
      "fields": [
        "my_field",
        "my_field._2gram",
        "my_field._3gram"
      ]
    }
  }
}
{
  "took" : 44,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.8630463,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.8630463,
        "_source" : {
          "my_field" : "quick brown fox jump lazy dog"
        }
      }
    ]
  }
}

要按顺序搜索与查询词项严格匹配的文档,或使用短语查询的其他属性进行搜索,请在根字段上使用match_phrase_prefix查询。 如果最后一个词项应该完全匹配,而不是作为前缀,也可以使用match_phrase查询。 使用短语查询的效率可能不如使用match_bool_prefix查询。

GET my_index/_search
{
  "query": {
    "match_phrase_prefix": {
      "my_field": "brown f"
    }
  }
}

search_as_you_type字段的特定参数

search_as_you_type字段的映射中接受以下参数,且这些参数是特定于该字段类型的

max_shingle_size

(可选, 整型) 要创建的最大分块尺寸。 有效值是2 (含) 到 4 (含)。默认值为 3

2 和该值之间的每个整数创建一个子字段。 例如,值3创建两个子字段:my_field._2grammy_field._3gram

更多的子字段支持更具体的查询,但会增加索引大小。

作为文本字段的字段类型的参数

由于search_as_you_type字段本质上是一个类似文本的字段,因此在该字段的映射中接受以下参数,这些参数的行为与配置text数据类型的字段时的行为类似。 除非另有说明,否则这些选项以相同的方式配置根字段子字段。

analyzer
应该在索引时和搜索时用于文本字段的analyzer(分析器)分析器(除非被search_analyzer覆盖)。 默认值为默认的索引分析器,或者standard分析器
index
字段应该是可搜索的吗?接受true (默认) 或 false
index_options
为了搜索和高亮显示,应该在索引中存储什么信息。默认为positions
norms
查询评分时是否应考虑字段长度。 接受truefalse。 该选项配置根字段和分块子字段,其默认值为true。 当它为false时,不配置前缀子字段。
store
字段值是否应该与_source字段分开存储和检索。 接受truefalse (默认)。 此选项仅配置根字段,不配置任何子字段。
search_analyzer
应该在搜索text字段时使用的analyzer(分析器)。 默认为analyzer设置。
search_quote_analyzer
当遇到短语时,在搜索时应该使用的analyzer(分析器)。 默认为search_analyzer设置。
similarity
应该使用哪种评分或相似度算法。默认为BM25
term_vector
是否应为字段存储词项向量。 默认为no。 此选项配置根字段和分块子字段,但不配置前缀子字段。

前缀查询优化

当对根字段或它的任何子字段进行prefix(前缀)查询时,查询将被重写为对._index_prefix子字段的term查询。 这比典型的对文本字段的prefix查询更有效,因为每个分块的特定长度的前缀被直接索引为._index_prefix子字段。

._index_prefix子字段的分析器稍微修改了分块构建的行为,以便在字段值的末尾也索引通常不会作为分块产生的词项的前缀。 例如,如果值quick brown fox被索引到max_shingle_size为3的search_as_you_type字段中,则brown foxfox的前缀也被索引到._index_prefix子字段,即使它们不会以词项的形式出现在._3gram子字段中。 这允许字段输入中的所有词项的自动完成。