即时搜索字段类型编辑

search_as_you_type 字段类型是一种类似文本的字段,经过优化后可以为即时搜索完成用例提供开箱即用的支持。它会创建一系列子字段,这些子字段经过分析后会生成索引词条,这些词条可以通过与整个索引文本值部分匹配的查询进行高效匹配。支持前缀补全(即匹配从输入开头开始的词条)和中缀补全(即匹配输入中任何位置的词条)。

将此类型的字段添加到映射时

response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        my_field: {
          type: 'search_as_you_type'
        }
      }
    }
  }
)
puts response
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "search_as_you_type"
      }
    }
  }
}

这将创建以下字段

my_field

根据映射中的配置进行分析。如果未配置分析器,则使用索引的默认分析器

my_field._2gram

使用 shingle 大小为 2 的 shingle 标记过滤器包装 my_field 的分析器

my_field._3gram

使用 shingle 大小为 3 的 shingle 标记过滤器包装 my_field 的分析器

my_field._index_prefix

使用边缘 ngram 标记过滤器包装 my_field._3gram 的分析器

可以使用 max_shingle_size 映射参数配置子字段中 shingle 的大小。默认值为 3,此参数的有效值为整数 2 到 4(含)。将为从 2 到 max_shingle_size(含)的每个 shingle 大小创建 Shingle 子字段。my_field._index_prefix 子字段在构建自己的分析器时,将始终使用 shingle 大小为 max_shingle_size 的 shingle 子字段的分析器。

增加 max_shingle_size 将提高包含更多连续词条的查询的匹配度,但代价是索引大小更大。默认的 max_shingle_size 通常应该足够了。

当索引文档的根字段 my_field 有值时,相同的输入文本会使用不同的分析链自动索引到每个字段中。

response = client.index(
  index: 'my-index-000001',
  id: 1,
  refresh: true,
  body: {
    my_field: 'quick brown fox jump lazy dog'
  }
)
puts response
PUT my-index-000001/_doc/1?refresh
{
  "my_field": "quick brown fox jump lazy dog"
}

为即时搜索用例提供查询的最有效方法通常是针对根 search_as_you_type 字段及其 shingle 子字段的类型为 bool_prefixmulti_match 查询。这可以匹配任意顺序的查询词条,但如果文档在 shingle 子字段中按顺序包含词条,则得分会更高。

response = client.search(
  index: 'my-index-000001',
  body: {
    query: {
      multi_match: {
        query: 'brown f',
        type: 'bool_prefix',
        fields: [
          'my_field',
          'my_field._2gram',
          'my_field._3gram'
        ]
      }
    }
  }
)
puts response
GET my-index-000001/_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-000001",
        "_id" : "1",
        "_score" : 0.8630463,
        "_source" : {
          "my_field" : "quick brown fox jump lazy dog"
        }
      }
    ]
  }
}

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

response = client.search(
  index: 'my-index-000001',
  body: {
    query: {
      match_phrase_prefix: {
        my_field: 'brown f'
      }
    }
  }
)
puts response
GET my-index-000001/_search
{
  "query": {
    "match_phrase_prefix": {
      "my_field": "brown f"
    }
  }
}

search_as_you_type 字段特有的参数编辑

以下参数在 search_as_you_type 字段的映射中接受,并且是此字段类型特有的

max_shingle_size

(可选,整数)要创建的最大 shingle 大小。有效值为 2(含)到 4(含)。默认为 3

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

更多子字段可以实现更具体的查询,但会增加索引大小。

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

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

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

前缀查询的优化编辑

对根字段或其任何子字段进行 prefix 查询时,该查询将被重写为对 ._index_prefix 子字段的 term 查询。这比对文本字段进行典型的 prefix 查询更有效,因为每个 shingle 的前缀(最大长度)都直接作为词条索引在 ._index_prefix 子字段中。

._index_prefix 子字段的分析器稍微修改了 shingle 构建行为,还会索引字段值末尾词条的前缀,这些前缀通常不会作为 shingle 生成。例如,如果值 quick brown fox 被索引到 max_shingle_size 为 3 的 search_as_you_type 字段中,则 brown foxfox 的前缀也会被索引到 ._index_prefix 子字段中,即使它们没有作为词条出现在 ._3gram 子字段中。这允许补全字段输入中的所有词条。