即时搜索字段类型

编辑

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

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

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "my_field": {
                "type": "search_as_you_type"
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        my_field: {
          type: 'search_as_you_type'
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      my_field: {
        type: "search_as_you_type",
      },
    },
  },
});
console.log(response);
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "search_as_you_type"
      }
    }
  }
}

这将创建以下字段

my_field

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

my_field._2gram

使用大小为 2 的瓦片令牌过滤器封装 my_field 的分析器

my_field._3gram

使用大小为 3 的瓦片令牌过滤器封装 my_field 的分析器

my_field._index_prefix

使用边缘 n 元语法令牌过滤器封装 my_field._3gram 的分析器

可以使用 max_shingle_size 映射参数配置子字段中瓦片的尺寸。默认值为 3,此参数的有效值为 2 - 4 的整数值(包括 2 和 4)。将为每个瓦片大小创建瓦片子字段,从 2 到 max_shingle_size(包括该值)。构造其自己的分析器时,my_field._index_prefix 子字段将始终使用 max_shingle_size 的瓦片子字段中的分析器。

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

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

resp = client.index(
    index="my-index-000001",
    id="1",
    refresh=True,
    document={
        "my_field": "quick brown fox jump lazy dog"
    },
)
print(resp)
response = client.index(
  index: 'my-index-000001',
  id: 1,
  refresh: true,
  body: {
    my_field: 'quick brown fox jump lazy dog'
  }
)
puts response
const response = await client.index({
  index: "my-index-000001",
  id: 1,
  refresh: "true",
  document: {
    my_field: "quick brown fox jump lazy dog",
  },
});
console.log(response);
PUT my-index-000001/_doc/1?refresh
{
  "my_field": "quick brown fox jump lazy dog"
}

服务于即时搜索用例的最有效查询方式通常是 multi_match 查询(类型为 bool_prefix),该查询以根 search_as_you_type 字段及其瓦片子字段为目标。这可以按任何顺序匹配查询词条,但如果文档在瓦片子字段中按顺序包含词条,则会为文档打出更高的分数。

resp = client.search(
    index="my-index-000001",
    query={
        "multi_match": {
            "query": "brown f",
            "type": "bool_prefix",
            "fields": [
                "my_field",
                "my_field._2gram",
                "my_field._3gram"
            ]
        }
    },
)
print(resp)
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
const response = await client.search({
  index: "my-index-000001",
  query: {
    multi_match: {
      query: "brown f",
      type: "bool_prefix",
      fields: ["my_field", "my_field._2gram", "my_field._3gram"],
    },
  },
});
console.log(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 查询效率高。

resp = client.search(
    index="my-index-000001",
    query={
        "match_phrase_prefix": {
            "my_field": "brown f"
        }
    },
)
print(resp)
response = client.search(
  index: 'my-index-000001',
  body: {
    query: {
      match_phrase_prefix: {
        my_field: 'brown f'
      }
    }
  }
)
puts response
const response = await client.search({
  index: "my-index-000001",
  query: {
    match_phrase_prefix: {
      my_field: "brown f",
    },
  },
});
console.log(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

(可选,整数)要创建的最大瓦片大小。有效值为 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。此选项配置根字段和瓦片子字段,其中默认值为 true。它不配置前缀子字段,其中默认值为 false
store
字段值是否应该存储,并且可以与 _source 字段分开检索。接受 truefalse(默认)。此选项仅配置根字段,而不配置任何子字段。
search_analyzer
应该在搜索时在 text 字段上使用的 analyzer。默认为 analyzer 设置。
search_quote_analyzer
当遇到短语时应该在搜索时使用的 analyzer。默认为 search_analyzer 设置。
similarity
应该使用哪个评分算法或相似度。默认为 BM25
term_vector
是否应该为该字段存储词条向量。默认为 no。此选项配置根字段和瓦片子字段,但不配置前缀子字段。

前缀查询的优化

编辑

当向根字段或其任何子字段发出 prefix 查询时,查询将重写为 term 查询,该查询以 ._index_prefix 子字段为目标。这比文本字段上的 prefix 查询更有效地匹配,因为每个瓦片的特定长度的前缀会直接作为 ._index_prefix 子字段中的词条进行索引。

._index_prefix 子字段的分析器会稍微修改瓦片构建行为,以索引字段值末尾词条的前缀,而这些前缀通常不会作为瓦片生成。例如,如果将值 quick brown fox 索引到 max_shingle_size 为 3 的 search_as_you_type 字段中,则 brown foxfox 的前缀也会索引到 ._index_prefix 子字段中,即使它们没有作为 ._3gram 子字段中的词条出现。这样就可以完成字段输入中的所有词条。

合成 _source

编辑

合成 _source 仅对 TSDB 索引(index.mode 设置为 time_series 的索引)正式可用。对于其他索引,合成 _source 处于技术预览阶段。技术预览阶段的功能可能会在未来版本中更改或删除。Elastic 将努力修复任何问题,但技术预览阶段的功能不受官方 GA 功能的支持 SLA 的约束。

search_as_you_type 字段在其默认配置中支持 合成 _source