搜索API

edit

搜索API用于搜索和聚合存储在Elasticsearch索引和数据流中的数据。有关概述和相关教程,请参阅搜索API

大多数搜索API支持多目标语法,但explain API除外。

核心搜索

edit

搜索测试

edit

搜索模板

edit

地理空间搜索

edit

搜索 API

edit

返回与请求中定义的查询匹配的搜索结果。

GET /my-index-000001/_search

请求

edit

GET //_search

GET /_search

POST //_search

POST /_search

先决条件

edit
  • 如果启用了Elasticsearch的安全功能,您必须拥有目标数据流、索引或别名的读取权限。对于跨集群搜索,请参阅配置跨集群搜索的权限

    要搜索一个别名的时间点 (PIT),您必须对该别名的数据流或索引具有read索引权限。

描述

edit

允许您执行搜索查询并获取与查询匹配的搜索结果。您可以使用q查询字符串参数请求体来提供搜索查询。

路径参数

edit
<target>
(可选,字符串) 要搜索的数据流、索引和别名的逗号分隔列表。支持通配符 (*)。要搜索所有数据流和索引,请省略此参数或使用 *_all

查询参数

edit

此API的几个选项可以通过查询参数或请求体参数来指定。如果同时指定了这两个参数,则仅使用查询参数。

allow_no_indices

(可选, 布尔值) 如果为false,当任何通配符表达式、 索引别名_all值仅针对缺失或关闭的索引时,请求将返回错误。 即使请求针对其他打开的索引,此行为也适用。例如,如果一个请求针对foo*,bar*,但没有任何索引以bar开头,即使存在以foo开头的索引,请求也会返回错误。

默认为 true

allow_partial_search_results

(可选, 布尔值) 如果为true,则在存在分片请求超时或 分片失败时返回部分结果。如果为false,则返回错误且不包含部分结果。默认为true

要覆盖此字段的默认设置,请将search.default_allow_partial_results集群设置设置为false

analyzer

(可选, 字符串) 用于查询字符串的分析器。

此参数只能在指定了q查询字符串参数时使用。

analyze_wildcard

(可选,布尔值) 如果为 true,通配符和前缀查询会被分析。 默认为 false

此参数只能在指定了 q 查询字符串参数时使用。

batched_reduce_size
(可选,整数) 在协调节点上应一次减少的分片结果数量。如果请求中可能的分片数量较大,此值应作为保护机制,以减少每个搜索请求的内存开销。默认为 512
ccs_minimize_roundtrips
(可选,布尔值) 如果为true,则在执行跨集群搜索(CCS)请求时,协调节点与远程集群之间的网络往返次数将最小化。请参阅跨集群搜索如何处理网络延迟。默认为true
default_operator

(可选,字符串) 查询字符串查询的默认操作符:AND 或 OR。 默认为 OR

此参数只能在指定了q查询字符串参数时使用。

df

(可选,字符串) 在查询字符串中没有给出字段前缀时,用作默认字段的字段。

此参数只能在指定了q查询字符串参数时使用。

docvalue_fields
(可选,字符串) 以逗号分隔的字段列表,用于返回每个命中的字段的文档值表示。请参阅 文档值字段
expand_wildcards

(可选,字符串) 通配符模式可以匹配的索引类型。如果请求可以针对数据流,此参数确定通配符表达式是否匹配隐藏的数据流。支持逗号分隔的值,例如 open,hidden。有效值为:

all
匹配任何数据流或索引,包括 隐藏的 数据流和索引。
open
匹配开放的、非隐藏的索引。同时也匹配任何非隐藏的数据流。
closed
匹配关闭的、非隐藏的索引。同时也匹配任何非隐藏的数据流。数据流不能被关闭。
hidden
匹配隐藏的数据流和隐藏的索引。必须与 openclosed 或两者结合使用。
none
不接受通配符模式。

默认为 open

explain
(可选,布尔值) 如果 true,返回命中中关于评分计算的详细信息。默认为 false
from

(可选,整数) 起始文档偏移量。需要是非负数,默认为 0

默认情况下,您不能使用fromsize参数分页浏览超过10,000条结果。要分页浏览更多结果,请使用search_after参数。

ignore_throttled

(可选,布尔值) 如果为 true,冻结时会忽略具体的、扩展的或别名的索引。默认为 true

[7.16.0] 在7.16.0中已弃用。

include_named_queries_score
(可选, 布尔值) 如果为true, 则包括任何命名查询的分数贡献。 此功能会在搜索响应中的每个命中上重新运行每个命名查询。通常,这会增加请求的少量开销。然而,在大量命中上使用计算昂贵的命名查询可能会增加显著的开销。默认为false
ignore_unavailable
(可选,布尔值) 如果为false,则当请求目标是一个缺失或关闭的索引时,请求将返回错误。默认为false
lenient

(可选,布尔值) 如果为 true,查询字符串中基于格式的查询失败(例如向数值字段提供文本)将被忽略。默认为 false

此参数只能在指定了 q 查询字符串参数时使用。

max_concurrent_shard_requests
(可选,整数) 定义每个节点上此搜索并发执行的分片请求数量。此值应用于限制搜索对集群的影响,以限制并发分片请求的数量。默认为 5
pre_filter_shard_size

(可选, 整数) 定义一个阈值, 当搜索请求扩展到的分片数量超过该阈值时, 强制执行一个预过滤的往返, 以基于查询重写预过滤搜索分片。如果例如分片无法基于其重写方法匹配任何文档, 则此过滤往返可以显著限制分片的数量, 例如如果日期过滤器是强制匹配的, 但分片边界和查询是不相交的。 当未指定时, 如果满足以下任一条件, 则执行预过滤阶段:

  • 请求目标超过 128 个分片。
  • 请求目标一个或多个只读索引。
  • 查询的主排序目标是一个索引字段。
preference

(可选,字符串) 用于搜索的节点和分片。默认情况下,Elasticsearch使用自适应副本选择从符合条件的节点和分片中进行选择,并考虑分配感知

有效值为 preference
_only_local
仅在本地节点上的分片上运行搜索。
_local
如果可能,在本地节点上的分片上运行搜索。如果不能,使用默认方法选择分片。
_only_nodes:,
仅在指定的节点ID上运行搜索。如果在多个选定节点上存在合适的分片,使用默认方法在这些节点上的分片上运行搜索。如果指定的节点都不可用,使用默认方法从任何可用节点选择分片。
_prefer_nodes:,
如果可能,在指定的节点ID上运行搜索。如果不能,使用默认方法选择分片。
_shards:,
仅在指定的分片上运行搜索。您可以将此值与其他 preference 值结合使用。但是,_shards 值必须放在第一位。例如:_shards:2,3|_local
任何不以 _ 开头的字符串。如果集群状态和选定的分片没有变化,使用相同的 值的搜索将按相同的顺序路由到相同的分片。
q

(可选, 字符串) 使用Lucene查询字符串语法的查询。

您可以使用 q 参数来运行查询参数搜索。查询参数搜索不支持完整的 Elasticsearch 查询DSL,但对于测试非常方便。

参数q覆盖了请求体中的query参数。如果两个参数都被指定,则不会返回与请求体中的query参数匹配的文档。

request_cache
(可选,布尔值) 如果 true,则对 size0 的请求启用搜索结果的缓存。请参阅 Shard request cache settings。默认为索引级别设置。
rest_total_hits_as_int
(可选,布尔值) 指示在搜索响应中,hits.total是否应渲染为整数或对象。默认为false
routing
(可选, 字符串) 自定义值,用于将操作路由到特定分片。
scroll

(可选, 时间值) 保留搜索上下文的时间段。请参阅 滚动搜索结果

默认情况下,此值不能超过 1d(24 小时)。您可以使用 search.max_keep_alive 集群级别设置来更改此限制。

search_type

(可选, 字符串) 如何为分布式词频计算 相关性评分

有效值为 search_type
query_then_fetch
(默认) 分布式词频在每个运行搜索的分片上本地计算。我们推荐此选项以获得更快的搜索速度,但评分可能不太准确。
dfs_query_then_fetch
分布式词频全局计算,使用从所有运行搜索的分片收集的信息。虽然此选项提高了评分的准确性,但它增加了到每个分片的往返,可能导致搜索速度变慢。
seq_no_primary_term
(可选,布尔值) 如果 true,返回每个命中的最后修改的序列号和主项。请参阅乐观并发控制
size

(可选, 整数) 定义返回的命中数量。默认为 10

默认情况下,您不能使用fromsize参数分页浏览超过10,000条结果。要分页浏览更多结果,请使用search_after参数。

sort
(可选,字符串) 以逗号分隔的 <字段>:<方向> 对列表。
_source

(可选) 指示为匹配的文档返回哪些源字段。这些字段在搜索响应的hits._source属性中返回。默认为true。请参阅源过滤

有效的_source
true
(布尔值) 返回整个文档源。
false
(布尔值) 不返回文档源。
(字符串) 要返回的源字段的逗号分隔列表。 支持通配符 (*) 模式。
_source_excludes

(可选,字符串) 一个逗号分隔的列表,用于从响应中排除源字段

您也可以使用此参数从_source_includes查询参数中指定的子集中排除字段。

如果 _source 参数为 false,则忽略此参数。

_source_includes

(可选,字符串) 一个逗号分隔的源字段列表,用于包含在响应中。

如果指定了此参数,则仅返回这些源字段。您可以使用_source_excludes查询参数从此子集中排除字段。

如果 _source 参数为 false,则忽略此参数。

stats
(可选,字符串) 用于日志记录和统计目的的请求的特定 tag
stored_fields

(可选,字符串) 以逗号分隔的存储字段列表,作为命中的一部分返回。如果未指定字段,则响应中不包含任何存储字段。请参阅 存储字段

如果指定了此字段,_source 参数默认设置为 false。你可以传递 _source: true 以在搜索响应中返回源字段和存储字段。

suggest_field
(可选,字符串) 指定用于建议的字段。
suggest_mode

(可选,字符串) 指定 建议模式。默认为 missing。可用选项:

  • always
  • missing
  • popular

此参数只能在指定了 suggest_fieldsuggest_text 查询字符串参数时使用。

suggest_size

(可选,整数) 返回的建议数量。

此参数只能在指定了 suggest_fieldsuggest_text 查询字符串参数时使用。

suggest_text

(可选,字符串) 应返回建议的源文本。

此参数只能在指定了suggest_field查询字符串参数时使用。

terminate_after

(可选,整数) 每个分片收集的最大文档数。如果查询达到此限制,Elasticsearch 会提前终止查询。Elasticsearch 在排序之前收集文档。

谨慎使用。Elasticsearch将此参数应用于处理请求的每个分片。如果可能,让Elasticsearch自动执行早期终止。避免为针对具有跨多个数据层的后备索引的数据流请求指定此参数。

默认为 0,表示不会提前终止查询执行。

timeout
(可选,时间单位) 指定等待每个分片响应的时间段。如果在超时到期之前未收到响应,请求将失败并返回错误。默认为无超时。
track_scores
(可选,布尔值) 如果为true,则计算并返回文档分数,即使这些分数不用于排序。默认为false
track_total_hits

(可选,整数或布尔值) 匹配查询的命中次数,精确计数。默认为 10000

如果true,则以牺牲一些性能为代价返回匹配查询的命中数的准确值。 如果false,则响应中不包括与查询匹配的总命中数。

typed_keys
(可选,布尔值) 如果为 true,聚合和建议器的名称将在响应中以其各自类型为前缀。默认为 false
version
(可选,布尔值) 如果为true,则在命中结果中返回文档版本。默认为false

请求体

edit
docvalue_fields

(可选,字符串和对象数组) 字段模式的数组。请求返回与这些模式匹配的字段名称的值,这些值位于响应的 hits.fields 属性中。

您可以将数组中的项指定为字符串或对象。请参阅 Doc value fields

Properties of docvalue_fields objects
field
(必需, 字符串) 通配符模式。请求返回与该模式匹配的字段名称的doc值。
format

(可选, 字符串) 返回的doc值的格式。

对于日期字段,您可以指定一个日期格式。对于数值字段,您可以指定一个DecimalFormat模式

对于其他字段数据类型,此参数不受支持。

fields

(可选,字符串和对象数组) 字段模式的数组。请求返回与这些模式匹配的字段名称的值,这些值位于响应的 hits.fields 属性中。

您可以将数组中的项指定为字符串或对象。请参阅 the fields 选项

Properties of fields objects
field
(必需, 字符串) 要返回的字段。支持通配符 (*)。
format

(可选, 字符串) 日期和地理空间字段的格式。其他字段数据类型不支持此参数。

datedate_nanos 字段接受一个 日期格式geo_pointgeo_shape 字段接受:

geojson (默认)
GeoJSON
wkt
Well Known Text
mvt()

二进制 Mapbox 矢量瓦片。API 返回瓦片作为base64编码的字符串。 的格式为 //,带有两个可选的后缀:@ 和/或 :。例如,2/0/12/0/1@4096:5

mvt parameters
(必需, 整数) 瓦片的缩放级别。接受 0-29
(必需, 整数) 瓦片的X坐标。
(必需, 整数) 瓦片的Y坐标。
(可选, 整数) 瓦片一边的大小,以像素为单位。矢量瓦片是正方形,边长相等。默认为 4096
(可选, 整数) 瓦片外部裁剪缓冲区的大小,以像素为单位。这允许渲染器避免几何图形延伸到瓦片范围之外时产生的轮廓伪影。默认为 5
stored_fields

(可选,字符串) 以逗号分隔的存储字段列表,作为命中的一部分返回。如果未指定字段,则响应中不包含任何存储字段。请参阅 存储字段

如果指定了此选项,_source 参数默认设置为 false。你可以传递 _source: true 以在搜索响应中返回源字段和存储字段。

explain
(可选,布尔值) 如果 true,返回命中中关于评分计算的详细信息。默认为 false
from

(可选,整数) 起始文档偏移量。需要是非负数,默认为 0

默认情况下,您不能使用fromsize参数分页浏览超过10,000条结果。要分页浏览更多结果,请使用search_after参数。

indices_boost

(可选,对象数组) 提升来自指定索引的文档的_score

Properties of indices_boost objects
:

(必需,浮点数) 是索引或索引别名的名称。支持通配符 (*) 表达式。

是分数乘以的因子。

大于 1.0 的提升值会增加分数。介于 01.0 之间的提升值会降低分数。

knn

(可选,对象或对象数组) 定义要运行的kNN查询。

Properties of knn object
field
(Required, string) The name of the vector field to search against. Must be a dense_vector field with indexing enabled.
filter
(Optional, Query DSL object) Query to filter the documents that can match. The kNN search will return the top k documents that also match this filter. The value can be a single query or a list of queries. If filter is not provided, all documents are allowed to match.
k
(Optional, integer) Number of nearest neighbors to return as top hits. This value must be less than or equal to num_candidates. Defaults to size.
num_candidates
(Optional, integer) The number of nearest neighbor candidates to consider per shard. Needs to be greater than k, or size if k is omitted, and cannot exceed 10,000. Elasticsearch collects num_candidates results from each shard, then merges them to find the top k results. Increasing num_candidates tends to improve the accuracy of the final k results. Defaults to Math.min(1.5 * k, 10_000).
query_vector
(Optional, array of floats) Query vector. Must have the same number of dimensions as the vector field you are searching against. Must be either an array of floats or a hex-encoded byte vector.
query_vector_builder
(Optional, object) A configuration object indicating how to build a query_vector before executing the request. You must provide a query_vector_builder or query_vector, but not both. Refer to Perform semantic search to learn more.
similarity

(可选, 浮点数) 文档被视为匹配项所需的最小相似度。计算出的相似度值与使用的原始相似度相关。不是文档分数。然后根据相似度对匹配的文档进行评分,并应用提供的boost

参数 similarity 是直接的向量相似度计算。

  • l2_norm: also known as Euclidean, will include documents where the vector is within the dims dimensional hypersphere with radius similarity with origin at query_vector.
  • cosine, dot_product, and max_inner_product: Only return vectors where the cosine similarity or dot-product are at least the provided similarity.

阅读更多内容:knn similarity search

min_score
(可选, 浮点数) 匹配文档的最小_score。低于此_score的文档将不包含在搜索结果中。
pit

(可选, 对象) 将搜索限制在时间点 (PIT)。如果你提供 一个pit,你不能在请求路径中指定一个

Properties of pit
id
(必填*, 字符串) 用于搜索的PIT的ID。如果你提供一个pit对象,此参数是 必需的。
keep_alive
(可选, 时间值) 用于延长PIT生命周期的时段。
query
(可选, 查询对象) 使用 查询DSL定义搜索定义。
retriever
[预览] 此功能处于技术预览阶段,可能会在未来的版本中进行更改或删除。Elastic 将努力修复任何问题,但技术预览中的功能不受官方 GA 功能支持 SLA 的约束。 (可选, 检索器对象) 定义一个顶级检索器,以指定一组所需的顶级文档,而不是标准查询或 knn 搜索。
runtime_mappings

(可选,对象的对象) 定义搜索请求中的一个或多个运行时字段。这些字段优先于具有相同名称的映射字段。

Properties of runtime_mappings objects

(必需,对象) 运行时字段的配置。键是字段名称。

Properties of
type

(必需的, 字符串) 字段类型, 可以是以下任意一种:

  • boolean
  • composite
  • date
  • double
  • geo_point
  • ip
  • keyword
  • long
  • lookup
script

(可选, 字符串) Painless脚本 在查询时执行。该脚本可以访问文档的整个上下文,包括原始的 _source 和任何映射字段及其值。

此脚本必须包含 emit 以返回计算值。例如:

"script": "emit(doc['@timestamp'].value.dayOfWeekEnum.toString())"
seq_no_primary_term
(可选,布尔值) 如果 true,返回每个命中的最后修改的序列号和主项。请参阅乐观并发控制
size

(可选,整数) 返回的命中数量。需要是非负数,默认为 10

默认情况下,您不能使用fromsize参数分页浏览超过10,000条结果。要分页浏览更多结果,请使用search_after参数。

_source

(可选) 指示为匹配的文档返回哪些源字段。这些字段在搜索响应的hits._source属性中返回。默认为true。请参阅源过滤

Valid values for _source
true
(布尔值) 返回整个文档源。
false
(布尔值) 不返回文档源。
(字符串或字符串数组) 通配符 (*) 模式或包含要返回的源字段的模式数组。

(对象) 包含要包含或排除的源字段列表的对象。

Properties for
excludes

(字符串或字符串数组) 通配符 (*) 模式或包含要从响应中排除的源字段的模式数组。

您也可以使用此属性从includes属性中指定的子集中排除字段。

includes

(字符串或字符串数组) 通配符 (*) 模式或包含要返回的源字段的模式的数组。

如果指定了此属性,则仅返回这些源字段。您可以使用excludes属性从此子集中排除字段。

stats
(可选,字符串数组) 要与搜索关联的统计组。每个组为其关联的搜索维护一个统计聚合。您可以使用 索引统计 API 检索这些统计信息。
terminate_after

(可选,整数) 每个分片收集的最大文档数。如果查询达到此限制,Elasticsearch 会提前终止查询。Elasticsearch 在排序之前收集文档。

谨慎使用。Elasticsearch将此参数应用于处理请求的每个分片。如果可能,让Elasticsearch自动执行早期终止。避免为针对具有跨多个数据层的后备索引的数据流请求指定此参数。

默认为 0,表示不会提前终止查询执行。

timeout
(可选,时间单位) 指定等待每个分片响应的时间段。如果在超时到期之前未收到响应,请求将失败并返回错误。默认为无超时。
version
(可选,布尔值) 如果为true,则在命中结果中返回文档版本。默认为false

响应体

edit
_scroll_id

(字符串) 用于搜索及其搜索上下文的标识符。

您可以使用此滚动ID与滚动API来检索请求的下一批搜索结果。请参阅滚动搜索结果

此参数仅在请求中指定了scroll查询参数时返回。

took

(整数) Elasticsearch执行请求所花费的毫秒数。

此值是通过测量协调节点接收到请求的时间与协调节点准备好发送响应的时间之间的时间差来计算的。

花费时间包括:

  • 协调节点与数据节点之间的通信时间
  • 请求在search 线程池中排队等待执行的时间
  • 实际执行时间

花费的时间不包括:

  • 将请求发送到Elasticsearch所需的时间
  • 序列化JSON响应所需的时间
  • 将响应发送给客户端所需的时间
timed_out
(布尔值) 如果true, 请求在完成之前超时; 返回的结果可能是部分或空的。
_shards

(对象) 包含用于请求的分片计数。

Properties of _shards
total
(整数) 需要查询的分片总数, 包括未分配的分片。
successful
(整数) 成功执行请求的分片数量。
skipped
(整数) 跳过请求的分片数量,因为轻量级检查 帮助意识到该分片上不可能有任何文档匹配。这 通常发生在搜索请求包含范围过滤器且 该分片只有落在该范围之外的值时。
failed
(整数) 未能执行请求的分片数量。请注意, 未分配的分片将被视为既不成功也不失败。 因此,failed+successful 少于 total 表示 某些分片未被分配。
hits

(对象) 包含返回的文档和元数据。

Properties of hits
total

(对象) 匹配文档数量的元数据。

Properties of total
value
(整数) 匹配文档的总数。
relation

(字符串) 指示在 value 参数中匹配文档的数量是准确的,还是一个下限。

Values of relation:
eq
准确
gte
下限
max_score

(浮点数) 返回的最高 文档 _score

对于不按 _score 排序的请求,此值为 null

hits

(对象数组) 返回的文档对象数组。

Properties of hits objects
_index
(字符串) 包含返回文档的索引名称。
_id
(字符串) 返回文档的唯一标识符。 此ID仅在返回的索引中唯一。
_score
(浮点数) 用于确定返回文档相关性的正32位浮点数。
_source

(对象) 在索引时传递的原始JSON正文。

您可以使用 _source 参数从响应中排除此属性,或指定要返回的源字段。

fields

(对象) 包含文档的字段值。这些字段必须在请求中使用以下一个或多个请求参数指定:

仅当设置了一个或多个这些参数时,才会返回此属性。

Properties of fields
(数组) 键是字段名称。值是字段的值。

示例

edit
GET /my-index-000001/_search?from=40&size=20
{
  "query": {
    "term": {
      "user.id": "kimchy"
    }
  }
}

API返回以下响应:

{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 20,
      "relation": "eq"
    },
    "max_score": 1.3862942,
    "hits": [
      {
        "_index": "my-index-000001",
        "_id": "0",
        "_score": 1.3862942,
        "_source": {
          "@timestamp": "2099-11-15T14:12:12",
          "http": {
            "request": {
              "method": "get"
            },
            "response": {
              "status_code": 200,
              "bytes": 1070000
            },
            "version": "1.1"
          },
          "source": {
            "ip": "127.0.0.1"
          },
          "message": "GET /search HTTP/1.1 200 1070000",
          "user": {
            "id": "kimchy"
          }
        }
      },
      ...
    ]
  }
}

异步搜索

edit

异步搜索 API 允许您异步执行搜索请求,监控其进度,并在结果可用时检索部分结果。

提交异步搜索 API

edit

异步执行搜索请求。它接受与search API相同的参数和请求体。

POST /sales*/_async_search?size=0
{
  "sort": [
    { "date": { "order": "asc" } }
  ],
  "aggs": {
    "sale_date": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "1d"
      }
    }
  }
}

响应包含正在执行的搜索的标识符。您可以使用此ID稍后检索搜索的最终结果。当前可用的搜索结果作为response对象的一部分返回。

{
  "id" : "FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=", 
  "is_partial" : true, 
  "is_running" : true, 
  "start_time_in_millis" : 1583945890986,
  "expiration_time_in_millis" : 1584377890986,
  "response" : {
    "took" : 1122,
    "timed_out" : false,
    "num_reduce_phases" : 0,
    "_shards" : {
      "total" : 562, 
      "successful" : 3, 
      "skipped" : 0,
      "failed" : 0
    },
    "hits" : {
      "total" : {
        "value" : 157483, 
        "relation" : "gte"
      },
      "max_score" : null,
      "hits" : [ ]
    }
  }
}

可用于监控其进度、检索其结果和/或删除它的异步搜索的标识符

当查询不再运行时,指示搜索是否在所有分片上成功完成或失败。在查询执行过程中,is_partial 始终设置为 true

搜索是否仍在执行或已完成

搜索将在多少个分片上执行,总计

有多少分片成功完成了搜索

当前有多少文档与查询匹配,这些文档属于已经完成搜索的分片

尽管查询不再运行,因此is_running被设置为false,结果可能是部分的。这种情况发生在搜索在某些分片返回结果后失败,或者当协调异步搜索的节点死亡时。

可以通过提供wait_for_completion_timeout参数来阻止并等待搜索完成,直到达到某个超时时间,该参数默认值为1秒。当异步搜索在该超时时间内完成时,响应不会包含ID,因为结果不会存储在集群中。keep_on_completion参数默认值为false,可以设置为true,以请求在搜索在wait_for_completion_timeout内完成时也存储结果以供以后检索。

您还可以通过keep_alive参数指定异步搜索需要保持可用的时间,该参数默认值为5d(五天)。在此期间之后,所有正在进行的异步搜索和任何保存的搜索结果都将被删除。

当结果的主要排序是基于一个索引字段时,分片会根据它们在该字段上持有的最小值和最大值进行排序,因此部分结果会按照请求的排序标准变得可用。

提交异步搜索API支持与搜索API相同的参数,尽管其中一些参数具有不同的默认值:

  • batched_reduce_size 默认值为 5:这会影响部分结果的可用频率,每当分片结果被减少时就会发生。每当协调节点接收到一定数量的新分片响应(默认情况下为 5)时,就会执行部分减少。
  • request_cache 默认值为 true
  • pre_filter_shard_size 默认值为 1 且无法更改:这是为了强制执行预过滤往返以从每个分片检索统计信息,以便跳过那些肯定不包含与查询匹配的文档的分片。
  • ccs_minimize_roundtrips 默认值为 false。在进行跨集群搜索时,将其设置为 true 可能会提高整体搜索延迟,特别是在搜索具有大量分片的集群时。然而,当设置为 true 时,远程集群上的搜索进度将不会被接收到,直到所有集群上的搜索完成。有关更多信息,请参阅 跨集群搜索

异步搜索不支持滚动 也不支持仅包含建议部分的搜索请求。

默认情况下,Elasticsearch不允许存储大于10Mb的异步搜索响应,尝试这样做会导致错误。可以通过更改search.max_async_search_response_size集群级别设置来设置存储的异步搜索响应的最大允许大小。

获取异步搜索

edit

get async search API 检索先前提交的异步搜索请求的结果,给定其id。

如果启用了Elasticsearch的安全功能,则对特定异步搜索结果的访问仅限于 提交它的用户或API密钥

GET /_async_search/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=
{
  "id" : "FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=",
  "is_partial" : false, 
  "is_running" : false, 
  "start_time_in_millis" : 1583945890986,
  "expiration_time_in_millis" : 1584377890986, 
  "completion_time_in_millis" : 1583945903130, 
  "response" : {
    "took" : 12144,
    "timed_out" : false,
    "num_reduce_phases" : 46, 
    "_shards" : {
      "total" : 562,
      "successful" : 188, 
      "skipped" : 0,
      "failed" : 0
    },
    "hits" : {
      "total" : {
        "value" : 456433,
        "relation" : "eq"
      },
      "max_score" : null,
      "hits" : [ ]
    },
    "aggregations" : { 
      "sale_date" :  {
        "buckets" : []
      }
    }
  }
}

当查询不再运行时,指示搜索是否在所有分片上成功完成或失败。在查询执行过程中,is_partial 始终设置为 true

搜索是否仍在执行或已完成

异步搜索何时过期

当异步搜索完成时,完成时间会被标示出来(开始时间 + 耗时)

指示已经对结果进行了多少次缩减。如果这个数字与上次检索的结果相比有所增加,您可以预期在搜索响应中包含更多的结果

指示有多少分片执行了查询。请注意,为了使分片结果包含在搜索响应中,它们需要先进行归约。

部分聚合结果,来自已经完成查询执行的分片。

在调用 Get Async Search API 时,也可以提供 wait_for_completion_timeout 参数,以便在提供的超时时间内等待搜索完成。如果在超时到期之前有最终结果可用,则返回最终结果,否则在超时到期时返回当前可用的结果。默认情况下不设置超时,这意味着将返回当前可用的结果,而不会进行任何额外的等待。

参数 keep_alive 指定了异步搜索在集群中保持可用的时间。如果未指定,将使用相应的提交异步请求时设置的 keep_alive。否则,可以覆盖该值并延长请求的有效期。当此期限到期时,如果搜索仍在运行,则会被取消。如果搜索已完成,其保存的结果将被删除。

获取异步搜索状态

edit

get async search status API 不获取搜索结果,仅显示先前提交的异步搜索请求的状态,前提是提供其 id

如果启用了Elasticsearch安全功能,则访问特定异步搜索状态的权限将受到限制:

  • 提交原始异步搜索请求的用户或API密钥
  • 拥有monitor集群权限或更高权限的用户。

您还可以通过keep_alive参数指定异步搜索需要保持可用的时间,该参数默认值为5d(五天)。在此期间之后,所有正在进行的异步搜索和任何保存的搜索结果都将被删除。

GET /_async_search/status/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=
{
  "id" : "FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=",
  "is_running" : true,
  "is_partial" : true,
  "start_time_in_millis" : 1583945890986,
  "expiration_time_in_millis" : 1584377890986,
  "_shards" : {
      "total" : 562,
      "successful" : 188, 
      "skipped" : 0,
      "failed" : 0
  }
}

指示到目前为止有多少分片执行了查询。

对于已完成的异步搜索,状态响应中有一个额外的 completion_status 字段,显示已完成异步搜索的状态码。

{
  "id" : "FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=",
  "is_running" : false,
  "is_partial" : false,
  "start_time_in_millis" : 1583945890986,
  "expiration_time_in_millis" : 1584377890986,
  "_shards" : {
      "total" : 562,
      "successful" : 562,
      "skipped" : 0,
      "failed" : 0
  },
 "completion_status" : 200 
}

表示异步搜索已成功完成。

{
  "id" : "FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=",
  "is_running" : false,
  "is_partial" : true,
  "start_time_in_millis" : 1583945890986,
  "expiration_time_in_millis" : 1584377890986,
  "_shards" : {
      "total" : 562,
      "successful" : 450,
      "skipped" : 0,
      "failed" : 112
  },
 "completion_status" : 503 
}

表示异步搜索已完成并出现错误。

删除异步搜索

edit

您可以使用删除异步搜索API通过ID手动删除异步搜索。如果搜索仍在进行中,搜索请求将被取消。否则,保存的搜索结果将被删除。

DELETE /_async_search/FmRldE8zREVEUzA2ZVpUeGs2ejJFUFEaMkZ5QTVrSTZSaVN3WlNFVmtlWHJsdzoxMDc=

如果启用了Elasticsearch安全功能,删除特定异步搜索的权限将受到限制:

  • 提交原始异步搜索请求的用户或API密钥
  • 拥有cancel_task集群权限或更高权限的用户。

时间点 API

edit

默认情况下,搜索请求会针对目标索引的最新可见数据执行,这称为时间点。Elasticsearch 时间点(point in time)是一个轻量级的视图,展示了数据在其启动时的状态。在某些情况下,更倾向于使用相同的时间点执行多个搜索请求。例如,如果在 刷新 之间执行 search_after 请求,那么这些请求的结果可能不一致,因为搜索之间发生的更改仅对更新的时间点可见。

先决条件

edit
  • 如果启用了Elasticsearch的安全功能,您必须对目标数据流、索引或别名具有读取权限。

    要搜索一个别名的时间点 (PIT),您必须对该别名的数据流或索引具有read索引权限。

请求体

edit
index_filter
(可选, 查询对象 允许在提供的查询在每个分片上重写为 match_none 时过滤索引。

示例

edit

在使用时间点进行搜索请求之前,必须显式打开它。keep_alive参数告诉Elasticsearch应该保持时间点活动的时间,例如?keep_alive=5m

POST /my-index-000001/_pit?keep_alive=1m

上述请求的结果包括一个id,该id应传递给搜索请求的pit参数的id

POST /_search  
{
    "size": 100,  
    "query": {
        "match" : {
            "title" : "elasticsearch"
        }
    },
    "pit": {
	    "id":  "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA==", 
	    "keep_alive": "1m"  
    }
}

带有pit参数的搜索请求不得指定indexroutingpreference,因为这些参数是从时间点复制的。

就像常规搜索一样,您可以使用 fromsize 来分页浏览搜索结果,最多可达前10,000条记录。如果您想检索更多记录,请使用 PIT 与 search_after

参数 id 告诉 Elasticsearch 使用从此时间点开始的上下文执行请求。

参数 keep_alive 告诉 Elasticsearch 应该延长时间点的生存时间多久。

时间点开放请求和每个后续搜索请求可能会返回不同的id;因此,请始终使用最近收到的id进行下一次搜索请求。

除了keep_alive参数外,还可以定义allow_partial_search_results参数。 该参数确定在最初创建时间点 (PIT)时,是否应容忍不可用的分片或分片故障。 如果设置为true,PIT将使用可用分片创建,并引用任何缺失的分片。 如果设置为false,如果任何分片不可用,操作将失败。 默认值为false。

PIT 响应包括分片总数的摘要,以及创建 PIT 时的成功分片数。

POST /my-index-000001/_pit?keep_alive=1m&allow_partial_search_results=true
{
  "id": "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA=",
  "_shards": {
    "total": 10,
    "successful": 10,
    "skipped": 0,
    "failed": 0
  }
}

当在搜索请求中使用包含分片失败的PIT时,缺失的分片总是会在搜索响应中作为NoShardAvailableActionException异常报告。为了消除这些异常,需要创建一个新的PIT,以便可以处理之前PIT中缺失的分片,假设它们在此期间变得可用。

保持时间点存活

edit

传递给开放时间点请求和搜索请求的keep_alive参数,延长了相应时间点的生存时间。 值(例如1m,参见时间单位)不需要足够长以处理所有数据——它只需要足够长以处理下一个请求。

通常,后台合并过程通过将较小的段合并在一起,创建新的、更大的段来优化索引。一旦较小的段不再需要,它们就会被删除。然而,开放的point-in-times阻止旧段被删除,因为它们仍在使用中。

保持旧段落存活意味着需要更多的磁盘空间和文件句柄。确保您已配置节点以拥有充足的可用文件句柄。请参阅文件描述符

此外,如果一个分段包含已删除或更新的文档,那么时间点必须跟踪该分段中的每个文档在初始搜索请求时是否处于活动状态。如果在一个索引上有许多打开的时间点,并且该索引正在进行删除或更新操作,请确保您的节点有足够的堆空间。请注意,时间点不会阻止与其关联的索引被删除。

您可以检查有多少个时间点(即搜索上下文)是打开的,使用节点统计 API

GET /_nodes/stats/indices/search

关闭时间点 API

edit

当其keep_alive时间已过期时,时间点会自动关闭。然而,保持时间点会产生成本,如前一节所述。时间点应在不再用于搜索请求时立即关闭。

DELETE /_pit
{
    "id" : "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA=="
}

API返回以下响应:

{
   "succeeded": true, 
   "num_freed": 3     
}

如果为真,与时间点ID关联的所有搜索上下文都已成功关闭

搜索上下文的数量已成功关闭

搜索切片

edit

在分页浏览大量文档时,将搜索分成多个切片以便独立处理它们可能会很有帮助:

GET /_search
{
  "slice": {
    "id": 0,                      
    "max": 2                      
  },
  "query": {
    "match": {
      "message": "foo"
    }
  },
  "pit": {
    "id": "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA=="
  }
}

GET /_search
{
  "slice": {
    "id": 1,
    "max": 2
  },
  "pit": {
    "id": "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA=="
  },
  "query": {
    "match": {
      "message": "foo"
    }
  }
}

切片的ID

最大切片数量

第一个请求的结果返回属于第一个切片(id: 0)的文档,第二个请求的结果返回第二个切片中的文档。由于最大切片数设置为2,因此这两个请求结果的并集等同于没有切片的点对点搜索结果。默认情况下,首先在分片上进行分割,然后在每个分片上本地进行分割。本地分割根据Lucene文档ID将分片划分为连续的范围。

例如,如果分片数量等于2,用户请求了4个切片,那么切片0和2分配给第一个分片,切片1和3分配给第二个分片。

所有切片应使用相同的时点ID。如果使用不同的时点ID,则切片可能会重叠并遗漏文档。这是因为分割标准基于Lucene文档ID,而这些ID在索引更改时并不稳定。

kNN 搜索 API

edit

在8.4.0中已弃用。

kNN 搜索 API 已被搜索 API 中的 knn 选项 所取代。

执行k近邻(kNN)搜索并返回匹配的文档。

GET my-index/_knn_search
{
  "knn": {
    "field": "image_vector",
    "query_vector": [0.3, 0.1, 1.2],
    "k": 10,
    "num_candidates": 100
  },
  "_source": ["name", "file_type"]
}

请求

edit

GET /_knn_search

POST /_knn_search

先决条件

edit
  • 如果启用了Elasticsearch安全功能,您必须对目标数据流、索引或别名具有权限。 索引权限

描述

edit

kNN搜索API在一个dense_vector字段上执行k近邻(kNN)搜索。给定一个查询向量,它找到最接近的k个向量,并将这些文档作为搜索结果返回。

Elasticsearch 使用 HNSW 算法 来支持高效的 kNN 搜索。与大多数 kNN 算法一样,HNSW 是一种近似方法,它牺牲了结果的准确性以提高搜索速度。这意味着返回的结果并不总是真正的 k 个最近邻。

kNN 搜索 API 支持使用过滤器来限制搜索。搜索将返回与过滤器查询匹配的前 k 个文档。

路径参数

edit
<target>
(可选,字符串) 逗号分隔的数据流、索引和别名列表,用于搜索。支持通配符 (*)。要搜索所有数据流和索引,请使用 *_all

查询参数

edit
routing
(可选, 字符串) 自定义值,用于将操作路由到特定分片。

请求体

edit
filter
(可选, 查询DSL对象) 用于过滤可以匹配的文档的查询。kNN搜索将返回同时匹配此过滤器的顶部 k 个文档。值可以是一个查询或一个查询列表。如果未提供 filter,则允许所有文档匹配。
knn

(必需, 对象) 定义要运行的kNN查询。

Properties of knn object
field
(必需, 字符串) 要搜索的向量字段的名称。必须是启用了索引的dense_vector字段
k
(可选, 整数) 作为最高命中返回的最近邻数量。此值必须小于或等于num_candidates。默认为size
num_candidates
(可选, 整数) 每个分片要考虑的最近邻候选数量。 需要大于k,或者如果省略k,则需要大于size,且不能超过10,000。 Elasticsearch从每个分片收集num_candidates结果,然后合并它们以找到前k个结果。增加num_candidates通常会提高最终k结果的准确性。默认为Math.min(1.5 * k, 10_000)
query_vector
(必需, 浮点数数组或字符串) 查询向量。必须与要搜索的向量字段具有相同的维度数。必须是浮点数数组或十六进制编码的字节向量。
docvalue_fields

(可选,字符串和对象数组) 字段模式的数组。请求返回与这些模式匹配的字段名称的值,这些值位于响应的 hits.fields 属性中。

您可以将数组中的项指定为字符串或对象。请参阅 Doc value fields

Properties of docvalue_fields objects
field
(必需, 字符串) 通配符模式。请求返回与该模式匹配的字段名称的doc值。
format

(可选, 字符串) 返回的doc值的格式。

对于日期字段,您可以指定一个日期格式。对于数值字段,您可以指定一个DecimalFormat模式

对于其他字段数据类型,此参数不受支持。

fields

(可选,字符串和对象数组) 字段模式的数组。请求返回与这些模式匹配的字段名称的值,这些值位于响应的 hits.fields 属性中。

您可以将数组中的项指定为字符串或对象。请参阅 the fields 选项

Properties of fields objects
field
(必需, 字符串) 要返回的字段。支持通配符 (*)。
format

(可选, 字符串) 日期和地理空间字段的格式。其他字段数据类型不支持此参数。

datedate_nanos 字段接受一个 日期格式geo_pointgeo_shape 字段接受:

geojson (默认)
GeoJSON
wkt
Well Known Text
mvt()

二进制 Mapbox 矢量瓦片。API 返回瓦片作为base64编码的字符串。 的格式为 //,带有两个可选的后缀:@ 和/或 :。例如,2/0/12/0/1@4096:5

mvt parameters
(必需, 整数) 瓦片的缩放级别。接受 0-29
(必需, 整数) 瓦片的X坐标。
(必需, 整数) 瓦片的Y坐标。
(可选, 整数) 瓦片一边的大小,以像素为单位。矢量瓦片是正方形,边长相等。默认为 4096
(可选, 整数) 瓦片外部裁剪缓冲区的大小,以像素为单位。这允许渲染器避免几何图形延伸到瓦片范围之外时产生的轮廓伪影。默认为 5
_source

(可选) 指示为匹配的文档返回哪些源字段。这些字段在搜索响应的hits._source属性中返回。默认为true。请参阅源过滤

Valid values for _source
true
(布尔值) 返回整个文档源。
false
(布尔值) 不返回文档源。
(字符串或字符串数组) 通配符 (*) 模式或包含要返回的源字段的模式数组。

(对象) 包含要包含或排除的源字段列表的对象。

Properties for
excludes

(字符串或字符串数组) 通配符 (*) 模式或包含要从响应中排除的源字段的模式数组。

您也可以使用此属性从includes属性中指定的子集中排除字段。

includes

(字符串或字符串数组) 通配符 (*) 模式或包含要返回的源字段的模式的数组。

如果指定了此属性,则仅返回这些源字段。您可以使用excludes属性从此子集中排除字段。

stored_fields

(可选,字符串) 以逗号分隔的存储字段列表,作为命中的一部分返回。如果未指定字段,则响应中不包含任何存储字段。请参阅 存储字段

如果指定了此选项,_source 参数默认设置为 false。你可以传递 _source: true 以在搜索响应中返回源字段和存储字段。

响应体

edit

kNN搜索响应与搜索API响应具有完全相同的结构。然而,某些部分具有特定于kNN搜索的含义:

  • 文档 _score 是通过查询和文档向量之间的相似性来确定的。参见 similarity
  • hits.total 对象包含考虑的最近邻候选者的总数,即 num_candidates * num_shardshits.total.relation 将始终为 eq,表示一个精确值。

检索器

edit

检索器是一种规范,用于描述从搜索中返回的顶级文档。检索器取代了搜索 API中其他也返回顶级文档的元素,例如queryknn。检索器可能包含子检索器,其中具有两个或更多子检索器的检索器被视为复合检索器。这允许在称为检索器树的树状结构中描述复杂行为,以更好地阐明搜索期间发生的操作顺序。

请参阅Retrievers以获取检索器抽象的高级概述。

以下检索器可用:

standard
一个 检索器,它取代了传统 查询 的功能。
knn
一个检索器,取代了knn搜索的功能。
rrf
一个检索器,它从倒数排名融合 (RRF)中生成顶级文档。
text_similarity_reranker
一个检索器,通过使用机器学习模型,根据与指定推理文本的语义相似度对文档进行重排序,从而增强搜索结果。

标准检索器

edit

一个标准的检索器从传统的查询中返回顶级文档。

参数:

edit
query

(可选,查询对象

定义一个查询以检索一组顶级文档。

filter

(可选, 查询对象或查询对象列表)

对此检索器应用一个布尔查询过滤器,其中所有文档都必须匹配此查询,但不会对分数产生贡献。

search_after

(可选, search after对象)

定义用于分页的搜索后对象参数。

terminate_after

(可选,整数) 每个分片收集的最大文档数。如果查询达到此限制,Elasticsearch 会提前终止查询。Elasticsearch 在排序之前收集文档。

谨慎使用。Elasticsearch将此参数应用于处理请求的每个分片。如果可能,让Elasticsearch自动执行早期终止。避免为针对具有跨多个数据层的后备索引的数据流请求指定此参数。

sort

(可选, 排序对象) 一个排序对象,用于指定匹配文档的顺序。

min_score

(可选, 浮点数)

匹配文档的最小_score。得分较低的文档不会包含在顶部文档中。

collapse

(可选, 折叠对象)

将顶部文档按指定键折叠为每个键的单一顶部文档。

限制

edit

当检索器树包含一个复合检索器(具有两个或更多子检索器的检索器)时,search after 参数不受支持。

示例

edit
GET /restaurants/_search
{
  "retriever": { 
    "standard": { 
      "query": { 
        "bool": { 
          "should": [ 
            {
              "match": { 
                "region": "Austria"
              }
            }
          ],
          "filter": [ 
            {
              "term": { 
                "year": "2019" 
              }
            }
          ]
        }
      }
    }
  }
}

打开retriever对象。

用于定义传统的 Elasticsearch 查询的 standard retriever。

定义搜索查询的入口点。

The bool 对象允许逻辑上组合多个查询子句。

The should 数组表示文档匹配的条件。匹配这些条件的文档将增加其相关性分数。

The match 对象查找 region 字段包含单词 "Austria" 的文档。

The filter 数组提供了必须满足的过滤条件,但这些条件不会影响相关性评分。

对象用于精确匹配,在这种情况下,通过字段过滤文档。

year字段中要匹配的确切值。

kNN 检索器

edit

kNN检索器从k近邻搜索(kNN)中返回最相关的文档。

参数

edit
field

(必需,字符串)

要搜索的向量字段名称。必须是启用了索引的dense_vector字段

query_vector

(如果未定义query_vector_builder,则为必需,数组类型为float)

查询向量。必须与您搜索的向量字段具有相同的维度数量。必须是浮点数数组或十六进制编码的字节向量。

query_vector_builder

(如果未定义query_vector,则需要查询向量构建器对象)

定义一个模型来构建查询向量。

k

(必需,整数)

返回的最近邻数量作为顶部匹配项。此值必须小于或等于num_candidates

num_candidates

(必需,整数)

每个分片要考虑的最近邻候选数量。 需要大于 k,或者如果省略 k,则需要大于 size,且不能超过 10,000。 Elasticsearch 从每个分片收集 num_candidates 个结果,然后将它们合并 以找到前 k 个结果。增加 num_candidates 通常会提高最终 k 个结果的准确性。默认为 Math.min(1.5 * k, 10_000)

filter

(可选, 查询对象或查询对象列表)

用于过滤可以匹配的文档的查询。kNN 搜索将返回同时匹配此过滤器的顶部 k 个文档。值可以是单个查询或查询列表。如果未提供 filter,则允许所有文档匹配。

similarity

(可选,浮点数)

文档被视为匹配项所需的最小相似度。计算出的相似度值与使用的原始相似度相关。不是文档分数。然后根据相似度对匹配的文档进行评分,并应用提供的boost

参数 similarity 是直接的向量相似度计算。

  • l2_norm: 也称为欧几里得,将包括向量在dims维超球体内且半径为similarity的文档,原点在query_vector
  • cosine, dot_product, 和 max_inner_product: 仅返回余弦相似度或点积至少为提供的similarity的向量。

阅读更多内容:knn similarity search

限制

edit

参数 query_vectorquery_vector_builder 不能同时使用。

示例

edit
GET /restaurants/_search
{
  "retriever": {
    "knn": { 
      "field": "vector", 
      "query_vector": [10, 22, 77], 
      "k": 10, 
      "num_candidates": 10 
    }
  }
}

k-近邻(knn)搜索的配置,基于向量相似度。

指定包含向量的字段名称。

knn搜索中,与文档向量进行比较的查询向量。

返回的最近邻数量作为顶部命中。此值必须小于或等于num_candidates

从初始候选集中选择最终的 k 个最近邻的大小。

RRF 检索器

edit

一个RRF检索器根据RRF公式返回顶级文档, 平等地对两个或多个子检索器进行加权。 倒数排名融合(RRF)是一种将具有不同相关性指示器的多个结果集 组合成一个结果集的方法。

参数

edit
retrievers

(必需,检索器对象数组)

指定哪些返回的顶级文档集将应用RRF公式的子检索器列表。每个子检索器在RRF公式中具有相同的权重。需要两个或更多的子检索器。

rank_constant

(可选,整数)

此值决定了每个查询的结果集中,单个文档对最终排名结果集的影响程度。值越高,表示排名较低的文档影响越大。此值必须大于或等于1。默认值为60

rank_window_size

(可选,整数)

此值决定每个查询的单个结果集的大小。较高的值将提高结果的相关性,但会牺牲性能。最终的排名结果集会被修剪到搜索请求的大小rank_window_size必须大于或等于size,并且大于或等于1。默认为size参数。

filter

(可选, 查询对象或查询对象列表)

根据每个检索器的规范,将指定的布尔查询过滤器应用于所有指定的子检索器。

示例:混合搜索

edit

一个简单的混合搜索示例(词法搜索 + 密集向量搜索),结合了 standard 检索器和 knn 检索器使用 RRF:

GET /restaurants/_search
{
  "retriever": {
    "rrf": { 
      "retrievers": [ 
        {
          "standard": { 
            "query": {
              "multi_match": {
                "query": "Austria",
                "fields": [
                  "city",
                  "region"
                ]
              }
            }
          }
        },
        {
          "knn": { 
            "field": "vector",
            "query_vector": [10, 22, 77],
            "k": 10,
            "num_candidates": 10
          }
        }
      ],
      "rank_constant": 1, 
      "rank_window_size": 50  
    }
  }
}

定义一个带有RRF检索器的检索树。

子检索器数组。

第一个子检索器是一个标准检索器。

第二个子检索器是一个knn检索器。

RRF检索器的排名常数。

RRF检索器的排名窗口大小。

示例:使用稀疏向量的混合搜索

edit

一个更复杂的混合搜索示例(词汇搜索 + ELSER 稀疏向量搜索 + 密集向量搜索)使用 RRF:

GET movies/_search
{
  "retriever": {
    "rrf": {
      "retrievers": [
        {
          "standard": {
            "query": {
              "sparse_vector": {
                "field": "plot_embedding",
                "inference_id": "my-elser-model",
                "query": "films that explore psychological depths"
              }
            }
          }
        },
        {
          "standard": {
            "query": {
              "multi_match": {
                "query": "crime",
                "fields": [
                  "plot",
                  "title"
                ]
              }
            }
          }
        },
        {
          "knn": {
            "field": "vector",
            "query_vector": [10, 22, 77],
            "k": 10,
            "num_candidates": 10
          }
        }
      ]
    }
  }
}

文本相似度重排序检索器

edit

检索器 text_similarity_reranker 使用 NLP 模型通过根据文档与查询的语义相似性重新排序前 k 个文档来改进搜索结果。

请参阅语义重新排序以获取语义重新排序的高级概述。

先决条件

edit

要使用 text_similarity_reranker,您必须首先使用 创建推理 API 设置一个 rerank 任务。 rerank 任务应使用能够计算文本相似度的机器学习模型进行设置。请参阅 Elastic NLP 模型参考 以获取 Elasticsearch 支持的第三方文本相似度模型列表。

目前你可以:

参数

edit
retriever

(必需的, 检索器)

用于生成初始排序文档集的子检索器。

field

(必需, 字符串)

用于文本相似度比较的文档字段。此字段应包含将与 inferenceText 进行比较的文本。

inference_id

(必需的, 字符串)

使用推理 API 创建的推理端点的唯一标识符。

inference_text

(必需的, 字符串)

用于相似性比较的文本片段。

rank_window_size

(可选, int)

在重新排序过程中考虑的顶级文档数量。默认为 10

min_score

(可选, 浮点数)

设置一个最低阈值分数,用于包含在重新排序结果中的文档。相似度分数低于此阈值的文档将被排除。请注意,分数计算因使用的模型而异。

filter

(可选, 查询对象或查询对象列表)

将指定的布尔查询过滤器应用于子检索器。如果子检索器已经指定了任何过滤器,则此顶级过滤器将与子检索器中定义的过滤器一起应用。

示例:Cohere 重新排序

edit

此示例通过使用Cohere Rerank API重新排序顶级文档,实现了开箱即用的语义搜索。这种方法消除了为所有索引文档生成和存储嵌入的需求。 这需要使用rerank任务类型的Cohere Rerank推理端点

GET /index/_search
{
   "retriever": {
      "text_similarity_reranker": {
         "retriever": {
            "standard": {
               "query": {
                  "match_phrase": {
                     "text": "landmark in Paris"
                  }
               }
            }
         },
         "field": "text",
         "inference_id": "my-cohere-rerank-model",
         "inference_text": "Most famous landmark in Paris",
         "rank_window_size": 100,
         "min_score": 0.5
      }
   }
}

示例:使用 Hugging Face 模型的语义重新排序

edit

以下示例使用 Hugging Face 的 cross-encoder/ms-marco-MiniLM-L-6-v2 模型根据语义相似性对搜索结果进行重新排序。 该模型必须使用 Eland 上传到 Elasticsearch。

请参阅 Elastic NLP 模型参考 以获取 Elasticsearch 支持的第三方文本相似性模型列表。

按照以下步骤加载模型并创建一个语义重新排序器。

  1. 使用 pip 安装 Eland

    python -m pip install eland[pytorch]
  2. 使用 Eland 将模型上传到 Elasticsearch。此示例假设您有一个 Elastic Cloud 部署和一个 API 密钥。有关更多身份验证选项,请参阅 Eland 文档

    eland_import_hub_model \
      --cloud-id $CLOUD_ID \
      --es-api-key $ES_API_KEY \
      --hub-model-id cross-encoder/ms-marco-MiniLM-L-6-v2 \
      --task-type text_similarity \
      --clear-previous \
      --start
  3. rerank任务创建一个推理端点

    PUT _inference/rerank/my-msmarco-minilm-model
    {
      "service": "elasticsearch",
      "service_settings": {
        "num_allocations": 1,
        "num_threads": 1,
        "model_id": "cross-encoder__ms-marco-minilm-l-6-v2"
      }
    }
  4. 定义一个 text_similarity_rerank 检索器。

    POST movies/_search
    {
      "retriever": {
        "text_similarity_reranker": {
          "retriever": {
            "standard": {
              "query": {
                "match": {
                  "genre": "drama"
                }
              }
            }
          },
          "field": "plot",
          "inference_id": "my-msmarco-minilm-model",
          "inference_text": "films that explore psychological depths"
        }
      }
    }

    此检索器使用标准的 match 查询在 movie 索引中搜索带有“drama”标签的电影。然后,它根据与 inference_text 参数中的文本的语义相似性对结果进行重新排序,使用我们上传到 Elasticsearch 的模型。

使用 fromsize 与检索树

edit

全局提供的fromsize参数是作为一般搜索API的一部分。它们适用于检索器树中的所有检索器,除非特定的检索器使用如rank_window_size等不同的参数覆盖size参数。尽管如此,最终的搜索结果总是限制在size之内。

使用聚合与检索器树

edit

聚合 是作为搜索请求的一部分全局指定的。 用于聚合的查询是所有叶子检索器的组合,作为布尔查询中的 should 子句。

指定检索器时的搜索参数限制

edit

当检索器被指定为搜索的一部分时,以下元素不允许在顶层使用,而是仅允许作为特定检索器的元素:

倒数排名融合

edit

倒数排名融合(RRF) 是一种将具有不同相关性指示的多个结果集合并为单个结果集的方法。 RRF不需要调整,并且不同的相关性指示不必相互关联即可获得高质量的结果。

RRF 使用以下公式来确定每个文档的排名分数:

score = 0.0
for q in queries:
    if d in result(q):
        score += 1.0 / ( k + rank( result(q), d ) )
return score

# where
# k is a ranking constant
# q is a query in the set of queries
# d is a document in the result set of q
# result(q) is the result set of q
# rank( result(q), d ) is d's rank within the result(q) starting from 1

倒数排名融合 API

edit

您可以将RRF作为搜索的一部分,使用来自多个子检索器的独立顶级文档集(结果集),通过RRF检索器进行组合和排序。 至少需要两个子检索器进行排序。

RRF检索器是作为搜索请求的检索器参数的一部分定义的可选对象。RRF检索器对象包含以下参数:

retrievers

(必需,检索器对象数组)

指定哪些返回的顶级文档集将应用RRF公式的子检索器列表。每个子检索器在RRF公式中具有相同的权重。需要两个或更多的子检索器。

rank_constant

(可选,整数)

此值决定了每个查询的结果集中,单个文档对最终排名结果集的影响程度。值越高,表示排名较低的文档影响越大。此值必须大于或等于1。默认值为60

rank_window_size

(可选,整数)

此值决定每个查询的单个结果集的大小。较高的值将提高结果的相关性,但会牺牲性能。最终的排名结果集会被修剪到搜索请求的大小rank_window_size必须大于或等于size,并且大于或等于1。默认为size参数。

使用RRF的示例请求:

GET example-index/_search
{
    "retriever": {
        "rrf": { 
            "retrievers": [
                {
                    "standard": { 
                        "query": {
                            "term": {
                                "text": "shoes"
                            }
                        }
                    }
                },
                {
                    "knn": { 
                        "field": "vector",
                        "query_vector": [1.25, 2, 3.5],
                        "k": 50,
                        "num_candidates": 100
                    }
                }
            ],
            "rank_window_size": 50,
            "rank_constant": 20
        }
    }
}

在上面的示例中,我们独立执行了knnstandard检索器。 然后我们使用rrf检索器来合并结果。

首先,我们执行由knn检索器指定的kNN搜索,以获取其全局前50个结果。

其次,我们执行由standard检索器指定的查询,以获取其全局前50个结果。

然后,在协调节点上,我们将kNN搜索的顶部文档与查询的顶部文档结合起来,并根据RRF公式使用rrf检索器的参数对它们进行排序,以使用默认的size10来获取组合的顶部文档。

请注意,如果来自knn搜索的k大于rank_window_size,结果将被截断为rank_window_size。如果k小于rank_window_size,结果将为k大小。

倒数排名融合支持的功能

edit

The rrf retriever 支持:

The rrf retriever 目前不支持:

使用不支持的功能作为使用rrf检索器的搜索的一部分会导致异常。

+ 重要提示:最好避免在请求中提供一个时间点,因为RRF会在内部创建一个共享给所有子检索器的时间点,以确保结果的一致性。

使用多个标准检索器的互惠排名融合

edit

The rrf retriever 提供了一种结合和排序多个 standard retriever 的方法。 一个主要的用例是将传统 BM25 查询和 ELSER 查询的顶级文档结合起来,以实现更高的相关性。

使用RRF与多个标准检索器的示例请求:

GET example-index/_search
{
    "retriever": {
        "rrf": { 
            "retrievers": [
                {
                    "standard": { 
                        "query": {
                            "term": {
                                "text": "blue shoes sale"
                            }
                        }
                    }
                },
                {
                    "standard": { 
                        "query": {
                            "sparse_vector":{
                                "field": "ml.tokens",
                                "inference_id": "my_elser_model",
                                "query": "What blue shoes are on sale?"
                            }
                        }
                    }
                }
            ],
            "rank_window_size": 50,
            "rank_constant": 20
        }
    }
}

在上面的示例中,我们分别独立执行了两个标准检索器。 然后我们使用rrf检索器来合并结果。

首先我们运行 standard 检索器,指定一个针对 blue shoes sales 的术语查询,使用标准的 BM25 评分算法。

接下来,我们运行 standard 检索器,指定一个针对 What blue shoes are on sale? 的 sparse_vector 查询,使用我们的 ELSER 评分算法。

The rrf retriever 允许我们将由完全独立的评分算法生成的两个顶级文档集以相同的权重进行组合。

这不仅消除了使用线性组合确定适当权重的需求,而且RRF还被证明在单独查询的基础上提高了相关性。

使用子搜索的倒数排名融合

edit

使用子搜索的RRF不再支持。 请改用retriever API。 参见使用多个标准检索器的示例。

倒数排名融合完整示例

edit

我们首先为包含文本字段、向量字段和整数字段的索引创建一个映射,并索引几个文档。 在这个例子中,我们将使用仅具有单一维度的向量,以便更容易解释排名。

PUT example-index
{
    "mappings": {
        "properties": {
            "text" : {
                "type" : "text"
            },
            "vector": {
                "type": "dense_vector",
                "dims": 1,
                "index": true,
                "similarity": "l2_norm",
                 "index_options": {
                     "type": "hnsw"
                 }
            },
            "integer" : {
                "type" : "integer"
            }
        }
    }
}

PUT example-index/_doc/1
{
    "text" : "rrf",
    "vector" : [5],
    "integer": 1
}

PUT example-index/_doc/2
{
    "text" : "rrf rrf",
    "vector" : [4],
    "integer": 2
}

PUT example-index/_doc/3
{
    "text" : "rrf rrf rrf",
    "vector" : [3],
    "integer": 1
}

PUT example-index/_doc/4
{
    "text" : "rrf rrf rrf rrf",
    "integer": 2
}

PUT example-index/_doc/5
{
    "vector" : [0],
    "integer": 1
}

POST example-index/_refresh

我们现在使用一个rrf检索器执行搜索,该检索器与一个指定BM25查询的standard检索器、一个指定kNN搜索的knn检索器以及一个词条聚合一起使用。

GET example-index/_search
{
    "retriever": {
        "rrf": {
            "retrievers": [
                {
                    "standard": {
                        "query": {
                            "term": {
                                "text": "rrf"
                            }
                        }
                    }
                },
                {
                    "knn": {
                        "field": "vector",
                        "query_vector": [3],
                        "k": 5,
                        "num_candidates": 5
                    }
                }
            ],
            "rank_window_size": 5,
            "rank_constant": 1
        }
    },
    "size": 3,
    "aggs": {
        "int_count": {
            "terms": {
                "field": "integer"
            }
        }
    }
}

并且我们接收到包含排名hits和术语聚合结果的响应。 我们既有排名器的score,也有_rank选项来展示我们的顶级文档。

{
    "took": ...,
    "timed_out" : false,
    "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
    },
    "hits" : {
        "total" : {
            "value" : 5,
            "relation" : "eq"
        },
        "max_score" : ...,
        "hits" : [
            {
                "_index" : "example-index",
                "_id" : "3",
                "_score" : 0.8333334,
                "_source" : {
                    "integer" : 1,
                    "vector" : [
                        3
                    ],
                    "text" : "rrf rrf rrf"
                }
            },
            {
                "_index" : "example-index",
                "_id" : "2",
                "_score" : 0.5833334,
                "_source" : {
                    "integer" : 2,
                    "vector" : [
                        4
                    ],
                    "text" : "rrf rrf"
                }
            },
            {
                "_index" : "example-index",
                "_id" : "4",
                "_score" : 0.5,
                "_source" : {
                    "integer" : 2,
                    "text" : "rrf rrf rrf rrf"
                }
            }
        ]
    },
    "aggregations" : {
        "int_count" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
                {
                    "key" : 1,
                    "doc_count" : 3
                },
                {
                    "key" : 2,
                    "doc_count" : 2
                }
            ]
        }
    }
}

让我们分解一下这些命中是如何排名的。 我们首先运行standard检索器,指定一个查询,并分别运行knn检索器指定一个kNN搜索,以收集它们的单独命中。

首先,我们查看从标准检索器中查询的命中结果。

"hits" : [
    {
        "_index" : "example-index",
        "_id" : "4",
        "_score" : 0.16152832,              
        "_source" : {
            "integer" : 2,
            "text" : "rrf rrf rrf rrf"
        }
    },
    {
        "_index" : "example-index",
        "_id" : "3",                        
        "_score" : 0.15876243,
        "_source" : {
            "integer" : 1,
            "vector" : [3],
            "text" : "rrf rrf rrf"
        }
    },
    {
        "_index" : "example-index",
        "_id" : "2",                        
        "_score" : 0.15350538,
        "_source" : {
            "integer" : 2,
            "vector" : [4],
            "text" : "rrf rrf"
        }
    },
    {
        "_index" : "example-index",
        "_id" : "1",                        
        "_score" : 0.13963442,
        "_source" : {
            "integer" : 1,
            "vector" : [5],
            "text" : "rrf"
        }
    }
]

排名 1, _id 4

排名 2, _id 3

排名 3, _id 2

排名 4, _id 1

请注意,我们的第一个命中结果在vector字段中没有值。 现在,我们查看从knn检索器中进行的kNN搜索的结果。

"hits" : [
    {
        "_index" : "example-index",
        "_id" : "3",                   
        "_score" : 1.0,
        "_source" : {
            "integer" : 1,
            "vector" : [3],
            "text" : "rrf rrf rrf"
        }
    },
    {
        "_index" : "example-index",
        "_id" : "2",                   
        "_score" : 0.5,
        "_source" : {
            "integer" : 2,
            "vector" : [4],
            "text" : "rrf rrf"
        }
    },
    {
        "_index" : "example-index",
        "_id" : "1",                   
        "_score" : 0.2,
        "_source" : {
            "integer" : 1,
            "vector" : [5],
            "text" : "rrf"
        }
    },
    {
        "_index" : "example-index",
        "_id" : "5",                   
        "_score" : 0.1,
        "_source" : {
            "integer" : 1,
            "vector" : [0]
        }
    }
]

排名 1, _id 3

排名 2, _id 2

排名 3, _id 1

排名 4, _id 5

我们现在可以将两个单独排序的结果集应用RRF公式,使用rrf检索器的参数来获得最终的排序。

# doc  | query     | knn       | score
_id: 1 = 1.0/(1+4) + 1.0/(1+3) = 0.4500
_id: 2 = 1.0/(1+3) + 1.0/(1+2) = 0.5833
_id: 3 = 1.0/(1+2) + 1.0/(1+1) = 0.8333
_id: 4 = 1.0/(1+1)             = 0.5000
_id: 5 =             1.0/(1+4) = 0.2000

我们根据RRF公式对文档进行排序,使用rank_window_size5,在我们的RRF结果集中截断底部的2个文档,结果集大小为3。 我们最终得到_id: 3_rank: 1_id: 2_rank: 2,以及_id: 4_rank: 3。 这个排序与原始RRF搜索的结果集相匹配,符合预期。

在RRF中解释

edit

除了单个查询的评分细节外,我们还可以利用 explain=true 参数来获取每个文档的 RRF 评分是如何计算的信息。 以上面的例子为例,通过在搜索请求中添加 explain=true,我们现在会得到一个类似如下的响应:

{
    "hits":
    [
        {
            "_index": "example-index",
            "_id": "3",
            "_score": 0.8333334,
            "_explanation":
            {
                "value": 0.8333334,                                                                                                                                               
                "description": "rrf score: [0.8333334] computed for initial ranks [2, 1] with rankConstant: [1] as sum of [1 / (rank + rankConstant)] for each query",            
                "details":                                                                                                                                                        
                [
                    {
                        "value": 2,                                                                                                                                               
                        "description": "rrf score: [0.33333334], for rank [2] in query at index [0] computed as [1 / (2 + 1]), for matching query with score: ",
                        "details":                                                                                                                                                
                        [
                            {
                                "value": 0.15876243,
                                "description": "weight(text:rrf in 0) [PerFieldSimilarity], result of:",
                                "details":
                                [
                                    ...
                                ]
                            }
                        ]
                    },
                    {
                        "value": 1,                                                                                                                                              
                        "description": "rrf score: [0.5], for rank [1] in query at index [1] computed as [1 / (1 + 1]), for matching query with score: ",
                        "details":
                        [
                            {
                                "value": 1,
                                "description": "within top k documents",
                                "details":
                                []
                            }
                        ]
                    }
                ]
            }
        }
        ...
    ]
}

文档的最终RRF分数为 _id=3

基于该文档在每个单独查询中的排名计算此分数的描述

每个查询的RRF得分是如何计算的详细信息

这里的 value 指定了该文档在特定查询中的 rank

底层查询的标准 explain 输出,描述匹配的术语和权重

这里的 value 指定了该文档在第二个 (knn) 查询中的 rank

除了上述内容外,RRF 还支持使用 _name 参数的 命名查询。 使用命名查询可以更容易且更直观地理解 RRF 分数计算,尤其是在处理多个查询时。 因此,我们现在将拥有:

GET example-index/_search
{
    "retriever": {
        "rrf": {
            "retrievers": [
                {
                    "standard": {
                        "query": {
                            "term": {
                                "text": "rrf"
                            }
                        }
                    }
                },
                {
                    "knn": {
                        "field": "vector",
                        "query_vector": [3],
                        "k": 5,
                        "num_candidates": 5,
                        "_name": "my_knn_query"                           
                    }
                }
            ],
            "rank_window_size": 5,
            "rank_constant": 1
        }
    },
    "size": 3,
    "aggs": {
        "int_count": {
            "terms": {
                "field": "integer"
            }
        }
    }
}

这里我们为knn检索器指定了一个_name

响应现在将在解释中包含命名查询:

{
    "hits":
    [
        {
            "_index": "example-index",
            "_id": "3",
            "_score": 0.8333334,
            "_explanation":
            {
                "value": 0.8333334,
                "description": "rrf score: [0.8333334] computed for initial ranks [2, 1] with rankConstant: [1] as sum of [1 / (rank + rankConstant)] for each query",
                "details":
                [
                    {
                        "value": 2,
                        "description": "rrf score: [0.33333334], for rank [2] in query at index [0] computed as [1 / (2 + 1]), for matching query with score: ",
                        "details":
                        [
                            ...
                        ]
                    },
                    {
                        "value": 1,
                        "description": "rrf score: [0.5], for rank [1] in query [my_knn_query] computed as [1 / (1 + 1]), for matching query with score: ",                      
                        "details":
                        [
                           ...
                        ]
                    }
                ]
            }
        }
        ...
    ]
}

现在我们有了对命名查询 my_knn_query 的引用,而不是匿名的 at index n

RRF中的分页

edit

当使用rrf时,您可以通过from参数对结果进行分页。 由于最终排名仅依赖于原始查询的排名,为了在分页时确保一致性,我们必须确保在from变化时,我们已经看到的内容的顺序保持不变。 为此,我们使用了一个固定的rank_window_size作为整个可用结果集,以便我们可以进行分页。 这基本上意味着如果:

  • from + sizerank_window_size : 我们可以从最终的 rrf 排序结果集中获取 results[from: from+size] 文档
  • from + size > rank_window_size : 我们将不会得到任何结果,因为请求会超出可用 rank_window_size 大小的结果集。

这里需要注意的一个重要事项是,由于 rank_window_size 是我们从各个查询组件中可以看到的所有结果,分页保证了结果的一致性,即在多个页面中不会跳过或重复任何文档,前提是 rank_window_size 保持不变。 如果 rank_window_size 发生变化,那么即使对于相同的排名,结果的顺序也可能会发生变化。

为了说明上述所有内容,让我们考虑以下简化的示例,其中我们有两个查询,queryAqueryB 以及它们的排名文档:

     |  queryA   |  queryB    |
_id: |  1        |  5         |
_id: |  2        |  4         |
_id: |  3        |  3         |
_id: |  4        |  1         |
_id: |           |  2         |

对于 rank_window_size=5,我们将能够看到来自 queryAqueryB 的所有文档。 假设 rank_constant=1rrf 分数将是:

# doc   | queryA     | queryB       | score
_id: 1 =  1.0/(1+1)  + 1.0/(1+4)      = 0.7
_id: 2 =  1.0/(1+2)  + 1.0/(1+5)      = 0.5
_id: 3 =  1.0/(1+3)  + 1.0/(1+3)      = 0.5
_id: 4 =  1.0/(1+4)  + 1.0/(1+2)      = 0.533
_id: 5 =    0        + 1.0/(1+1)      = 0.5

因此,最终的排名结果集将是 [1, 4, 2, 3, 5],我们将对其进行分页,因为 rank_window_size == len(results)。 在这种情况下,我们将有:

  • from=0, size=2 将返回文档 [1, 4] 及其排名 [1, 2]
  • from=2, size=2 将返回文档 [2, 3] 及其排名 [3, 4]
  • from=4, size=2 将返回文档 [5] 及其排名 [5]
  • from=6, size=2 将返回一个空的结果集,因为已经没有更多结果可以迭代了

现在,如果我们有一个 rank_window_size=2,我们将只能看到查询 queryAqueryB 分别对应的文档 [1, 2][5, 4]。 通过计算,我们会发现结果现在会有所不同,因为我们对于任何一个查询都没有位置 [3: end] 的文档信息。

# doc   | queryA     | queryB         | score
_id: 1 =  1.0/(1+1)  + 0              = 0.5
_id: 2 =  1.0/(1+2)  + 0              = 0.33
_id: 4 =    0        + 1.0/(1+2)      = 0.33
_id: 5 =    0        + 1.0/(1+1)      = 0.5

最终排名的结果集将是 [1, 5, 2, 4],我们可以在前 rank_window_size 个结果上进行分页,即 [1, 5]。 因此,对于与上述相同的参数,我们现在将拥有:

  • from=0, size=2 将返回 [1, 5],排名为 [1, 2]
  • from=2, size=2 将返回一个空的结果集,因为它会超出可用的 rank_window_size 结果范围。

滚动 API

edit

我们不再推荐使用滚动API进行深度分页。如果你需要在分页超过10,000条记录时保留索引状态,请使用search_after参数与时间点(PIT)。

检索滚动搜索的下一组结果。

GET /_search/scroll
{
  "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}

请求

edit

GET /_search/scroll/ [7.0.0] 在7.0.0中已弃用。

GET /_search/scroll

POST /_search/scroll/ [7.0.0] 在7.0.0中已弃用。

POST /_search/scroll

先决条件

edit
  • 如果启用了Elasticsearch安全功能,您必须对目标数据流、索引或别名具有权限。 索引权限

描述

edit

您可以使用滚动 API 从单个滚动搜索请求中检索大量结果。

滚动 API 需要一个滚动 ID。要获取滚动 ID,请提交一个包含 搜索 API 请求,该请求包括一个用于 scroll 查询参数 的参数。scroll 参数指示 Elasticsearch 应为请求保留多长时间的 搜索上下文

搜索响应在响应体参数 _scroll_id 中返回一个滚动 ID。然后,您可以使用滚动 ID 与滚动 API 来检索请求的下一批结果。如果启用了 Elasticsearch 安全功能,则特定滚动 ID 的结果访问权限仅限于 提交搜索的用户或 API 密钥

您还可以使用滚动 API 来指定一个新的 scroll 参数,该参数可以延长或缩短搜索上下文的保留期。

查看 滚动搜索结果

滚动搜索的结果反映了初始搜索请求时索引的状态。后续的索引或文档更改仅影响后续的搜索和滚动请求。

路径参数

edit
<scroll_id>

[7.0.0] 在7.0.0中已弃用。 (可选,字符串) 搜索的滚动ID。

滚动ID可能会很长。我们建议仅使用scroll_id请求体参数来指定滚动ID。

查询参数

edit
scroll

(可选, 时间值) 保留搜索上下文的时间段。请参阅 滚动搜索结果

此值覆盖原始搜索API请求中scroll参数设置的持续时间。

默认情况下,此值不能超过 1d(24 小时)。您可以使用 search.max_keep_alive 集群级别设置来更改此限制。

您还可以使用 scroll 请求体参数来指定此值。如果两个参数都指定了,则只使用查询参数。

scroll_id

[7.0.0] 在7.0.0中已弃用。 (可选,字符串) 搜索的滚动ID。

滚动ID可能会很长。我们建议仅使用scroll_id请求体参数来指定滚动ID。

rest_total_hits_as_int
(可选, 布尔值) 如果true,API响应的hit.total属性将返回为整数。 如果false,API响应的hit.total属性将返回为对象。 默认为false

请求体

edit
scroll

(可选, 时间值) 保留搜索上下文的时间段。请参阅 滚动搜索结果

此值覆盖原始搜索API请求中scroll参数设置的持续时间。

默认情况下,此值不能超过 1d(24 小时)。您可以使用 search.max_keep_alive 集群级别设置来更改此限制。

您也可以使用scroll查询参数来指定此值。如果同时指定了这两个参数,则仅使用查询参数。

scroll_id
(必需,字符串) 搜索的滚动ID。

响应体

edit

滚动API返回与搜索API相同的响应体。请参阅搜索API的响应体参数

清除滚动 API

edit

清除搜索上下文和结果,用于滚动搜索

DELETE /_search/scroll
{
  "scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="
}

请求

edit

DELETE /_search/scroll/ [7.0.0] 在7.0.0中已弃用。

DELETE /_search/scroll

路径参数

edit
<scroll_id>

[7.0.0] 在7.0.0中已弃用。 (可选,字符串) 逗号分隔的滚动ID列表以清除。要清除所有滚动ID,请使用_all

滚动ID可能会很长。我们建议仅通过scroll_id 请求体参数指定滚动ID。

查询参数

edit
scroll_id

[7.0.0] 在7.0.0中已弃用。 (可选,字符串) 逗号分隔的滚动ID列表以清除。要清除所有滚动ID,请使用_all

滚动ID可能会很长。我们建议仅通过scroll_id 请求体参数来指定滚动ID。

请求体

edit
scroll_id
(必需,字符串或字符串数组) 要清除的滚动ID。要清除所有滚动ID,请使用_all

响应体

edit
succeeded
(布尔值) 如果true,表示请求成功。这并不表示是否清除了任何滚动搜索请求。
num_freed
(整数) 清除的滚动搜索请求数量。

搜索模板 API

edit

使用搜索模板进行搜索。

GET my-index/_search/template
{
  "id": "my-search-template",
  "params": {
    "query_string": "hello world",
    "from": 0,
    "size": 10
  }
}

请求

edit

GET /_search/template

GET _search/template

POST /_search/template

POST _search/template

先决条件

edit
  • 如果启用了Elasticsearch安全功能,您必须对目标数据流、索引或别名具有权限。对于跨集群搜索,请参阅远程集群

路径参数

edit
<target>
(可选,字符串) 要搜索的数据流、索引和别名的逗号分隔列表。支持通配符 (*)。要搜索所有数据流和索引,请省略此参数或使用 *

查询参数

edit
allow_no_indices

(可选, 布尔值) 如果为false,当任何通配符表达式、 索引别名_all值仅针对缺失或关闭的索引时,请求将返回错误。 即使请求针对其他打开的索引,此行为也适用。例如,如果一个请求针对foo*,bar*,但没有任何索引以bar开头,即使存在以foo开头的索引,请求也会返回错误。

默认为 true

ccs_minimize_roundtrips
(可选,布尔值) 如果为 true,则最大限度地减少跨集群搜索请求的网络往返次数。默认为 true
expand_wildcards

(可选,字符串) 通配符模式可以匹配的索引类型。如果请求可以针对数据流,此参数确定通配符表达式是否匹配隐藏的数据流。支持逗号分隔的值,例如 open,hidden。有效值为:

all
匹配任何数据流或索引,包括 隐藏的 数据流和索引。
open
匹配开放的、非隐藏的索引。同时也匹配任何非隐藏的数据流。
closed
匹配关闭的、非隐藏的索引。同时也匹配任何非隐藏的数据流。数据流不能被关闭。
hidden
匹配隐藏的数据流和隐藏的索引。必须与 openclosed 或两者结合使用。
none
不接受通配符模式。
explain
(可选,布尔值) 如果为 true,响应将包含命中中评分计算的额外详细信息。默认为 false
ignore_throttled

(可选,布尔值) 如果为 true,冻结时会忽略具体的、扩展的或别名的索引。默认为 true

[7.16.0] 在7.16.0中已弃用。

ignore_unavailable
(可选,布尔值) 如果为false,则当请求目标是一个缺失或关闭的索引时,请求将返回错误。默认为false
preference
(可选,字符串) 指定操作应在其上执行的节点或分片。默认情况下是随机的。
rest_total_hits_as_int
(可选,布尔值) 如果 true,响应返回 hits.total 作为整数。 如果为 false,则返回 hits.total 作为对象。默认为 false
routing
(可选, 字符串) 自定义值,用于将操作路由到特定分片。
scroll
(可选,时间单位) 指定为滚动搜索维护索引一致视图的时间长度。
search_type

(可选,字符串)搜索操作的类型。可用选项:

  • query_then_fetch
  • dfs_query_then_fetch
typed_keys
(可选,布尔值) 如果为 true,响应会将聚合和建议器的名称与其各自的类型一起前缀。默认为 false

请求体

edit
explain

(可选,布尔值) 如果为 true,则在每个命中结果中返回有关评分计算的详细信息。默认为 false

如果你同时指定了这个和explain查询参数,API将仅使用查询参数。

id
(必需*, 字符串) 要使用的搜索模板的ID。如果没有指定source,则此参数是必需的。
params
(可选,对象) 用于替换模板中 Mustache 变量的键值对。键是变量名。值是变量值。
profile
(可选,布尔值) 如果 true,则对查询执行进行分析。默认为 false
source

(必需*, 对象) 一个内联搜索模板。支持与 搜索 API 请求体相同的参数。还支持 Mustache 变量。

如果没有指定id,则此参数是必需的。

多搜索模板 API

edit

通过单个请求运行多个模板化搜索

GET my-index/_msearch/template
{ }
{ "id": "my-search-template", "params": { "query_string": "hello world", "from": 0, "size": 10 }}
{ }
{ "id": "my-other-search-template", "params": { "query_type": "match_all" }}

请求

edit

GET /_msearch/template

GET _msearch/template

POST /_msearch/template

POST _msearch/template

先决条件

edit
  • 如果启用了Elasticsearch安全功能,您必须具有目标数据流、索引或别名的读取 索引权限。对于跨集群搜索,请参阅远程集群

路径参数

edit
<target>
(可选,字符串) 要搜索的数据流、索引和别名的逗号分隔列表。支持通配符 (*)。要搜索所有数据流和索引,请省略此参数或使用 *

查询参数

edit
ccs_minimize_roundtrips
(可选,布尔值) 如果为 true,则最大限度地减少跨集群搜索请求的网络往返次数。默认为 true
max_concurrent_searches
(可选, 整数) API 可以运行的最大并发搜索数量。 默认为 max(1, (# of 数据节点 * min(搜索线程池大小, 10)))
rest_total_hits_as_int
(可选,布尔值) 如果 true,响应返回 hits.total 为整数。 如果为 false,则返回 hits.total 为对象。默认为 false
search_type

(可选,字符串)搜索操作的类型。可用选项:

  • query_then_fetch
  • dfs_query_then_fetch
typed_keys
(可选,布尔值) 如果 true,响应会将聚合和建议器的名称与其各自的类型前缀。默认为 false

请求体

edit

请求体必须是以下格式的换行符分隔的JSON(NDJSON):

<header>\n
<body>\n
<header>\n
<body>\n

每个

对表示一个搜索请求。

支持与 multi search API
相同的参数。 支持与 search template API 的请求体相同的参数。

<header>

(必需, 对象) 用于限制或更改搜索的参数。

此对象是每个搜索体所必需的,但可以是空的({})或空白行。

Properties of
objects
allow_no_indices

(可选,布尔值) 如果为true,则当通配符表达式或_all值仅检索到缺失或关闭的索引时,请求不会返回错误。

此参数也适用于指向缺失或索引的别名

expand_wildcards

(可选,字符串) 通配符模式可以匹配的索引类型。如果请求可以针对数据流,此参数确定通配符表达式是否匹配隐藏的数据流。支持逗号分隔的值,例如 open,hidden。有效值为:

all
匹配任何数据流或索引,包括隐藏的。
open
匹配开放的、非隐藏的索引。也匹配任何非隐藏的数据流。
closed
匹配关闭的、非隐藏的索引。也匹配任何非隐藏的数据流。数据流不能被关闭。
hidden
匹配隐藏的数据流和隐藏的索引。必须与openclosed或两者结合使用。
none
不接受通配符模式。

默认为 open

ignore_unavailable
(可选, 布尔值) 如果为true,则缺失或关闭的索引中的文档不会包含在响应中。默认为false
index

(可选,字符串或字符串数组) 要搜索的数据流、索引和别名。支持通配符 (*)。可以通过数组指定多个目标。

如果未指定此参数,则使用 请求路径参数作为回退。

preference
(可选, 字符串) 用于执行搜索的节点或分片。默认为随机。
request_cache
(可选, 布尔值) 如果为true,则可以为此搜索使用请求缓存。默认为索引级设置。请参阅分片请求缓存设置
routing
(可选, 字符串) 用于将搜索操作路由到特定分片的自定义路由值
search_type

(可选,字符串) 指示在评分返回的文档时是否应使用全局术语和文档频率。

选项包括:

query_then_fetch
(默认) 文档使用分片的本地术语和文档频率进行评分。这通常更快但不太准确。
dfs_query_then_fetch
文档使用所有分片的全局术语和文档频率进行评分。这通常较慢但更准确。
<body>

(请求, 对象) 搜索的参数。

explain
(可选, 布尔值) 如果为true,则返回每个命中的得分计算的详细信息。默认为false
id
(必需*, 字符串) 要使用的搜索模板的ID。如果没有指定source,则此参数是必需的。
params
(可选, 对象) 用于替换模板中的Mustache变量的键值对。键是变量名。值是变量值。
profile
(可选, 布尔值) 如果为true,则对查询执行进行分析。默认为false
source

(必需*, 对象) 一个内联搜索模板。支持与 搜索 API 请求体相同的参数。还支持 Mustache 变量。

如果没有指定id,则此参数是必需的。

响应代码

edit

API仅在请求本身失败时返回400状态码。如果请求中的一个或多个搜索失败,API将返回200状态码,并在响应中为每个失败的搜索返回一个error对象。

响应体

edit
responses

(对象数组) 每个搜索的结果,按提交顺序返回。 每个对象使用与search API的响应相同的属性。

如果搜索失败,响应中会包含一个错误对象,其中包含错误消息。

curl 请求

edit

如果向 curl 提供文本文件或文本输入,请使用 --data-binary 标志而不是 -d 以保留换行符。

$ cat requests
{ "index": "my-index" }
{ "id": "my-search-template", "params": { "query_string": "hello world", "from": 0, "size": 10 }}
{ "index": "my-other-index" }
{ "id": "my-other-search-template", "params": { "query_type": "match_all" }}

$ curl -H "Content-Type: application/x-ndjson" -XGET localhost:9200/_msearch/template --data-binary "@requests"; echo

渲染搜索模板 API

edit

渲染一个搜索模板作为搜索请求体

POST _render/template
{
  "id": "my-search-template",
  "params": {
    "query_string": "hello world",
    "from": 20,
    "size": 10
  }
}

请求

edit

GET _render/template

GET _render/template/

POST _render/template

POST _render/template/

先决条件

edit
  • 如果启用了Elasticsearch安全功能,您必须至少对一个索引模式拥有read 索引权限

路径参数

edit
<template-id>
(必需*, 字符串) 要渲染的搜索模板的ID。如果没有指定source,则此参数或请求体参数id是必需的。

请求体

edit
id
(必需*, 字符串) 要渲染的搜索模板的ID。如果没有指定source,则此参数或请求路径参数是必需的。如果同时指定了此参数和参数,API仅使用
params
(可选,对象) 用于替换模板中 Mustache 变量的键值对。键是变量名。值是变量值。
source
(必需*, 对象) 一个内联搜索模板。支持与搜索 API请求体相同的参数。这些参数还支持Mustache变量。如果没有指定id,则此参数是必需的。

搜索分片 API

edit

返回搜索请求将执行的索引和分片。

GET /my-index-000001/_search_shards

请求

edit

GET //_search_shards

先决条件

edit
  • 如果启用了Elasticsearch安全功能,您必须拥有目标数据流、索引或别名的view_index_metadatamanage 索引权限

描述

edit

搜索分片 API 返回搜索请求将执行的索引和分片。这对于解决分片路由和分片偏好问题或进行优化规划非常有用。当使用过滤别名时,过滤器将作为 indices 部分的一部分返回。

路径参数

edit
<target>
(可选,字符串) 要搜索的数据流、索引和别名的逗号分隔列表。支持通配符 (*)。要搜索所有数据流和索引,请省略此参数或使用 *_all

查询参数

edit
allow_no_indices

(可选, 布尔值) 如果为false,当任何通配符表达式、 索引别名_all值仅针对缺失或关闭的索引时,请求将返回错误。 即使请求针对其他打开的索引,此行为也适用。例如,如果一个请求针对foo*,bar*,但没有任何索引以bar开头,即使存在以foo开头的索引,请求也会返回错误。

默认为 true

expand_wildcards

(可选,字符串) 通配符模式可以匹配的索引类型。如果请求可以针对数据流,此参数确定通配符表达式是否匹配隐藏的数据流。支持逗号分隔的值,例如 open,hidden。有效值为:

all
匹配任何数据流或索引,包括 隐藏的 数据流和索引。
open
匹配开放的、非隐藏的索引。同时也匹配任何非隐藏的数据流。
closed
匹配关闭的、非隐藏的索引。同时也匹配任何非隐藏的数据流。数据流不能被关闭。
hidden
匹配隐藏的数据流和隐藏的索引。必须与 openclosed 或两者结合使用。
none
不接受通配符模式。

默认为 open

ignore_unavailable
(可选,布尔值) 如果为false,则当请求目标是一个缺失或关闭的索引时,请求将返回错误。默认为false
local
(可选,布尔值) 如果 true,请求仅从本地节点检索信息。默认为 false,这意味着信息从主节点检索。
preference
(可选,字符串) 指定操作应在其上执行的节点或分片。默认情况下是随机的。
routing
(可选, 字符串) 自定义值,用于将操作路由到特定分片。
master_timeout
(可选,时间单位) 等待主节点的时间段。如果在超时到期之前主节点不可用,请求将失败并返回错误。默认为30s。 也可以设置为-1,表示请求不应超时。

示例

edit
GET /my-index-000001/_search_shards

API返回以下结果:

{
  "nodes": ...,
  "indices" : {
    "my-index-000001": { }
  },
  "shards": [
    [
      {
        "index": "my-index-000001",
        "node": "JklnKbD7Tyqi9TP3_Q_tBg",
        "relocating_node": null,
        "primary": true,
        "shard": 0,
        "state": "STARTED",
        "allocation_id": {"id":"0TvkCyF7TAmM1wHP4a42-A"},
        "relocation_failure_info" : {
          "failed_attempts" : 0
        }
      }
    ],
    [
      {
        "index": "my-index-000001",
        "node": "JklnKbD7Tyqi9TP3_Q_tBg",
        "relocating_node": null,
        "primary": true,
        "shard": 1,
        "state": "STARTED",
        "allocation_id": {"id":"fMju3hd1QHWmWrIgFnI4Ww"},
        "relocation_failure_info" : {
          "failed_attempts" : 0
        }
      }
    ],
    [
      {
        "index": "my-index-000001",
        "node": "JklnKbD7Tyqi9TP3_Q_tBg",
        "relocating_node": null,
        "primary": true,
        "shard": 2,
        "state": "STARTED",
        "allocation_id": {"id":"Nwl0wbMBTHCWjEEbGYGapg"},
        "relocation_failure_info" : {
          "failed_attempts" : 0
        }
      }
    ],
    [
      {
        "index": "my-index-000001",
        "node": "JklnKbD7Tyqi9TP3_Q_tBg",
        "relocating_node": null,
        "primary": true,
        "shard": 3,
        "state": "STARTED",
        "allocation_id": {"id":"bU_KLGJISbW0RejwnwDPKw"},
        "relocation_failure_info" : {
          "failed_attempts" : 0
        }
      }
    ],
    [
      {
        "index": "my-index-000001",
        "node": "JklnKbD7Tyqi9TP3_Q_tBg",
        "relocating_node": null,
        "primary": true,
        "shard": 4,
        "state": "STARTED",
        "allocation_id": {"id":"DMs7_giNSwmdqVukF7UydA"},
        "relocation_failure_info" : {
          "failed_attempts" : 0
        }
      }
    ]
  ]
}

指定相同的请求,这次使用路由值:

GET /my-index-000001/_search_shards?routing=foo,bar

API返回以下结果:

{
  "nodes": ...,
  "indices" : {
      "my-index-000001": { }
  },
  "shards": [
    [
      {
        "index": "my-index-000001",
        "node": "JklnKbD7Tyqi9TP3_Q_tBg",
        "relocating_node": null,
        "primary": true,
        "shard": 2,
        "state": "STARTED",
        "allocation_id": {"id":"fMju3hd1QHWmWrIgFnI4Ww"},
        "relocation_failure_info" : {
          "failed_attempts" : 0
        }
      }
    ],
    [
      {
        "index": "my-index-000001",
        "node": "JklnKbD7Tyqi9TP3_Q_tBg",
        "relocating_node": null,
        "primary": true,
        "shard": 3,
        "state": "STARTED",
        "allocation_id": {"id":"0TvkCyF7TAmM1wHP4a42-A"},
        "relocation_failure_info" : {
          "failed_attempts" : 0
        }
      }
    ]
  ]
}

由于指定了路由值,搜索仅在两个分片上执行。

建议器

edit

基于提供的文本,使用建议器建议相似的术语。

POST my-index-000001/_search
{
  "query" : {
    "match": {
      "message": "tring out Elasticsearch"
    }
  },
  "suggest" : {
    "my-suggestion" : {
      "text" : "tring out Elasticsearch",
      "term" : {
        "field" : "message"
      }
    }
  }
}

请求

edit

建议功能根据提供的文本使用建议器建议相似的术语。建议请求部分与查询部分一起定义在_search请求中。如果省略查询部分,则仅返回建议。

示例

edit

每个请求可以指定多个建议。每个建议都有一个任意的名称。在下面的示例中,请求了两个建议。my-suggest-1my-suggest-2 建议都使用了 term 建议器,但具有不同的 text

POST _search
{
  "suggest": {
    "my-suggest-1" : {
      "text" : "tring out Elasticsearch",
      "term" : {
        "field" : "message"
      }
    },
    "my-suggest-2" : {
      "text" : "kmichy",
      "term" : {
        "field" : "user.id"
      }
    }
  }
}

下面的建议响应示例包括了针对my-suggest-1my-suggest-2的建议响应。每个建议部分都包含条目。每个条目实际上是建议文本中的一个标记,并包含建议条目文本、在建议文本中的原始起始偏移量和长度,以及如果找到的任意数量的选项。

{
  "_shards": ...
  "hits": ...
  "took": 2,
  "timed_out": false,
  "suggest": {
    "my-suggest-1": [ {
      "text": "tring",
      "offset": 0,
      "length": 5,
      "options": [ {"text": "trying", "score": 0.8, "freq": 1 } ]
    }, {
      "text": "out",
      "offset": 6,
      "length": 3,
      "options": []
    }, {
      "text": "elasticsearch",
      "offset": 10,
      "length": 13,
      "options": []
    } ],
    "my-suggest-2": ...
  }
}

每个选项数组包含一个选项对象,其中包括建议的文本、其文档频率以及与建议条目文本相比的得分。得分的含义取决于所使用的建议器。术语建议器的得分基于编辑距离。

全局建议文本
edit

为了避免建议文本的重复,可以定义一个全局文本。在下面的示例中,建议文本是全局定义的,并适用于my-suggest-1my-suggest-2建议。

POST _search
{
  "suggest": {
    "text" : "tring out Elasticsearch",
    "my-suggest-1" : {
      "term" : {
        "field" : "message"
      }
    },
    "my-suggest-2" : {
       "term" : {
        "field" : "user"
       }
    }
  }
}

建议文本在上述示例中也可以指定为特定建议选项。在建议级别指定的建议文本会覆盖全局级别的建议文本。

术语建议器

edit

The term suggester 基于编辑距离提供术语建议。提供的建议文本在术语被建议之前会进行分析。建议的术语是针对每个分析后的建议文本标记提供的。term suggester 不会考虑作为请求一部分的查询。

常见的建议选项:

edit

文本

建议文本。建议文本是一个必需的选项,需要全局设置或按建议设置。

字段

用于获取候选建议的字段。这是一个必需的选项,需要全局设置或按建议设置。

分析器

用于分析建议文本的分析器。默认为建议字段的搜索分析器。

大小

每个建议文本标记要返回的最大修正数。

排序

定义每个建议文本词条的排序方式。两个可能的值:

  • score: 首先按分数排序,然后按文档频率排序,最后按词条本身排序。
  • frequency: 首先按文档频率排序,然后按相似度分数排序,最后按词条本身排序。

suggest_mode

建议模式控制包含哪些建议或控制应为哪些建议文本术语提供建议。可以指定三个可能的值:

  • missing: 仅对索引中不存在的建议文本术语提供建议(默认)。
  • popular: 仅建议在比原始建议文本术语更多文档中出现的建议。
  • always: 根据建议文本中的术语提供任何匹配的建议。

其他术语建议选项:

edit

max_edits

候选建议的最大编辑距离,以便被视为建议。只能是一个介于1和2之间的值。任何其他值都会导致抛出错误的请求错误。默认为2。

prefix_length

必须匹配的最小前缀字符数,以便成为建议的候选者。默认为 1。增加此数字可以提高拼写检查性能。通常,拼写错误不会出现在术语的开头。

min_word_length

建议文本术语必须具有的最小长度,以便被包含。默认为 4

shard_size

设置从每个单独分片中检索的最大建议数量。在归约阶段,仅返回基于size选项的前N个建议。默认为size选项。将此值设置为高于size的值可能有助于在性能成本下获得更准确的拼写校正文档频率。由于术语在分片之间进行分区,拼写校正的分片级别文档频率可能不精确。增加此值将使这些文档频率更加精确。

max_inspections

一个用于与 shard_size 相乘的因子,以便在分片级别检查更多候选拼写纠正。可以在牺牲性能的情况下提高准确性。 默认为 5。

min_doc_freq

建议应出现的文档数量的最小阈值。这可以指定为绝对数量或文档数量的相对百分比。这可以通过仅建议高频词来提高质量。默认值为 0f 且未启用。如果指定的值大于 1,则该数字不能为小数。此选项使用分片级别的文档频率。

max_term_freq

建议文本标记可以存在的文档数量中的最大阈值,以便被包含。可以是相对百分比数字(例如,0.4)或表示文档频率的绝对数字。如果指定的值大于1,则不能指定小数。默认为0.01f。这可以用于排除通常拼写正确的高频词,从而提高拼写检查的性能。此选项使用分片级别的文档频率。

string_distance

用于比较建议词相似度的字符串距离实现。可以指定五种可能的值:

  • internal: 默认基于damerau_levenshtein,但针对索引内术语的字符串距离比较进行了高度优化。
  • damerau_levenshtein: 基于Damerau-Levenshtein算法的字符串距离算法。
  • levenshtein: 基于Levenshtein编辑距离算法的字符串距离算法。
  • jaro_winkler: 基于Jaro-Winkler算法的字符串距离算法。
  • ngram: 基于字符n-gram的字符串距离算法。

短语建议器

edit

The term suggester 提供了一个非常方便的 API 来访问在特定字符串距离内的单词替代方案。该 API 允许在流中单独访问每个标记,同时将建议选择留给 API 消费者。然而,通常需要预先选择的建议以呈现给最终用户。phrase suggester 在 term suggester 的基础上添加了额外的逻辑,以选择整个修正的短语,而不是基于 ngram-language 模型的加权单个标记。实际上,这个 suggester 将能够基于共现和频率做出更好的决定,选择哪些标记。

API 示例

edit

通常,短语建议器需要预先进行特殊映射才能工作。 本页上的短语建议器示例需要以下映射才能工作。反转分析器仅在最后一个示例中使用。

PUT test
{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "analysis": {
        "analyzer": {
          "trigram": {
            "type": "custom",
            "tokenizer": "standard",
            "filter": ["lowercase","shingle"]
          },
          "reverse": {
            "type": "custom",
            "tokenizer": "standard",
            "filter": ["lowercase","reverse"]
          }
        },
        "filter": {
          "shingle": {
            "type": "shingle",
            "min_shingle_size": 2,
            "max_shingle_size": 3
          }
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "fields": {
          "trigram": {
            "type": "text",
            "analyzer": "trigram"
          },
          "reverse": {
            "type": "text",
            "analyzer": "reverse"
          }
        }
      }
    }
  }
}
POST test/_doc?refresh=true
{"title": "noble warriors"}
POST test/_doc?refresh=true
{"title": "nobel prize"}

一旦设置了分析器和映射,您可以在使用 term 建议器的地方使用 phrase 建议器:

POST test/_search
{
  "suggest": {
    "text": "noble prize",
    "simple_phrase": {
      "phrase": {
        "field": "title.trigram",
        "size": 1,
        "gram_size": 3,
        "direct_generator": [ {
          "field": "title.trigram",
          "suggest_mode": "always"
        } ],
        "highlight": {
          "pre_tag": "<em>",
          "post_tag": "</em>"
        }
      }
    }
  }
}

响应包含按最可能的拼写修正排序的建议。在这种情况下,我们收到了预期的修正“诺贝尔奖”。

{
  "_shards": ...
  "hits": ...
  "timed_out": false,
  "took": 3,
  "suggest": {
    "simple_phrase" : [
      {
        "text" : "noble prize",
        "offset" : 0,
        "length" : 11,
        "options" : [ {
          "text" : "nobel prize",
          "highlighted": "<em>nobel</em> prize",
          "score" : 0.48614594
        }]
      }
    ]
  }
}

基本短语建议API参数

edit

字段

用于语言模型进行n-gram查找的字段名称,建议器将使用此字段来获取统计信息以评分修正。此字段是强制性的。

gram_size

设置 field 中 n-grams(shingles)的最大大小。 如果该字段不包含 n-grams(shingles),则应省略此设置或将其设置为 1。请注意,Elasticsearch 会尝试根据指定的 field 检测 gram 大小。如果该字段使用了 shingle 过滤器,则 gram_size 会设置为 max_shingle_size,除非明确设置。

real_word_error_likelihood

即使术语存在于字典中,术语被拼写错误的概率。默认值是 0.95,意味着5%的真实单词被拼写错误。

置信度

置信度级别定义了一个应用于输入短语分数的因子,该因子用作其他建议候选者的阈值。只有得分高于阈值的候选者才会被包含在结果中。例如,置信度级别为1.0将仅返回得分高于输入短语的建议。如果设置为0.0,则返回前N个候选者。默认值为1.0

max_errors

要形成修正的最大术语百分比被认为是拼写错误。此方法接受范围为[0..1)的浮点值作为实际查询术语的分数,或接受>=1的数字作为查询术语的绝对数量。默认设置为1.0,这意味着仅返回最多有一个拼写错误的术语的修正。请注意,设置过高可能会对性能产生负面影响。建议使用较低的值,如12;否则,建议调用所花费的时间可能会超过查询执行的时间。

分隔符

用于在大词组字段中分隔术语的分隔符。如果未设置,则使用空白字符作为分隔符。

大小

为每个查询词生成的候选词数量。像35这样的低数值通常会产生良好的结果。提高这个数值可以带来编辑距离更高的词。默认值是5

分析器

设置用于分析建议文本的分析器。 默认为通过 field 传递的建议字段的搜索分析器。

shard_size

设置从每个单独分片中检索的最大建议词数量。在归约阶段,仅返回基于size选项的前N个建议。默认为5

文本

设置用于提供建议的文本/查询。

高亮

设置建议高亮显示。如果没有提供,则不会返回highlighted字段。如果提供了,则必须包含pre_tagpost_tag,它们会包裹在更改的标记周围。如果连续多个标记被更改,则整个更改的短语会被包裹,而不是每个标记单独包裹。

排序规则

检查每个建议是否符合指定的query,以修剪索引中不存在匹配文档的建议。对于一个建议的校对查询仅在生成该建议的本地分片上运行。query必须指定,并且它可以是模板化的。请参阅搜索模板。当前的建议会自动作为{{suggestion}}变量提供,该变量应在您的查询中使用。您仍然可以指定自己的模板params——suggestion值将被添加到您指定的变量中。此外,您可以指定一个prune来控制是否返回所有短语建议;当设置为true时,建议将有一个额外的选项collate_match,如果找到短语的匹配文档,则为true,否则为falseprune的默认值是false

POST test/_search
{
  "suggest": {
    "text" : "noble prize",
    "simple_phrase" : {
      "phrase" : {
        "field" :  "title.trigram",
        "size" :   1,
        "direct_generator" : [ {
          "field" :            "title.trigram",
          "suggest_mode" :     "always",
          "min_word_length" :  1
        } ],
        "collate": {
          "query": { 
            "source" : {
              "match": {
                "{{field_name}}" : "{{suggestion}}" 
              }
            }
          },
          "params": {"field_name" : "title"}, 
          "prune": true 
        }
      }
    }
  }
}

此查询将为每个建议运行一次。

变量 {{suggestion}} 将被替换为每个建议的文本。

params中指定了一个额外的field_name变量,并由match查询使用。

所有建议都将返回一个额外的collate_match选项,指示生成的短语是否匹配任何文档。

平滑模型

edit

The phrase suggester 支持多种平滑模型,以平衡不常见词组(词组(短语)在索引中不存在)和常见词组(在索引中至少出现一次)之间的权重。可以通过将 smoothing 参数设置为以下选项之一来选择平滑模型。每个平滑模型都支持特定的属性,可以进行配置。

stupid_backoff

一个简单的回退模型,如果高阶n-gram模型的计数为0,则回退到低阶n-gram模型,并对低阶n-gram模型进行恒定因子的折扣。默认的discount0.4。Stupid Backoff是默认模型。

拉普拉斯

一个使用加性平滑的平滑模型,其中所有计数都加上一个常数(通常是1.0或更小)以平衡权重。默认的alpha0.5

线性插值

一个平滑模型,根据用户提供的权重(lambdas)对一元组、二元组和三元组进行加权平均。线性插值没有任何默认值。所有参数(trigram_lambdabigram_lambdaunigram_lambda)都必须提供。

POST test/_search
{
  "suggest": {
    "text" : "obel prize",
    "simple_phrase" : {
      "phrase" : {
        "field" : "title.trigram",
        "size" : 1,
        "smoothing" : {
          "laplace" : {
            "alpha" : 0.7
          }
        }
      }
    }
  }
}

候选生成器

edit

The phrase suggester 使用候选生成器为给定文本中的每个术语生成一个可能术语的列表。一个单一的候选生成器类似于为文本中的每个单独术语调用的 term suggester。生成器的输出随后与来自其他术语的候选词结合进行评分,以生成建议候选词。

目前仅支持一种类型的候选生成器,即 direct_generator。Phrase suggest API 接受一个生成器列表, 该列表位于键 direct_generator 下;列表中的每个生成器 都会针对原始文本中的每个术语进行调用。

直接生成器

edit

直接生成器支持以下参数:

字段

用于获取候选建议的字段。这是一个必需的选项,需要全局设置或按建议设置。

大小

每个建议文本标记要返回的最大修正数。

suggest_mode

建议模式控制每个分片生成的建议中包含哪些建议。除了always之外的所有值都可以被视为一种优化,以生成更少的建议来在每个分片上测试,并且在合并每个分片生成的建议时不会重新检查。因此,missing将为不包含这些术语的分片生成建议,即使其他分片包含这些术语。这些应该使用confidence进行过滤。可以指定三个可能的值:

  • missing:仅为分片中不存在的术语生成建议。这是默认设置。
  • popular:仅建议在分片中比原始术语出现在更多文档中的术语。
  • always:根据建议文本中的术语建议任何匹配的建议。

max_edits

候选建议的最大编辑距离,以便被视为建议。只能是一个介于1和2之间的值。任何其他值都会导致抛出错误的请求错误。默认为2。

prefix_length

必须匹配的最小前缀字符数,以便成为候选建议。默认为 1。增加此数字可以提高拼写检查性能。通常,拼写错误不会出现在术语的开头。

min_word_length

建议文本术语必须具有的最小长度,以便被包含在内。默认为4。

max_inspections

一个用于与 shard_size 相乘的因子,以便在分片级别检查更多候选拼写纠正。可以在牺牲性能的情况下提高准确性。 默认为 5。

min_doc_freq

建议应出现的文档数量的最小阈值。这可以指定为绝对数量或文档数量的相对百分比。这可以通过仅建议高频词来提高质量。默认值为 0f 且未启用。如果指定的值大于 1,则该数字不能为小数。此选项使用分片级别的文档频率。

max_term_freq

建议文本标记可以存在的文档数量中的最大阈值,以便被包含。可以是相对百分比数字(例如,0.4)或表示文档频率的绝对数字。如果指定的值大于1,则不能指定小数。默认为0.01f。这可以用于排除通常拼写正确的高频词,从而提高拼写检查的性能。此选项使用分片级别的文档频率。

预过滤器

应用于传递给此候选生成器的每个标记的过滤器(分析器)。此过滤器在生成候选之前应用于原始标记。

post_filter

应用于每个生成的标记的过滤器(分析器),这些标记在传递给实际的短语评分器之前应用。

以下示例展示了一个包含两个生成器的短语建议调用:第一个生成器使用包含普通索引词的字段,第二个生成器使用包含通过反转过滤器索引的词的字段(标记以反向顺序索引)。这是为了克服直接生成器的限制,即需要一个常量前缀以提供高性能建议。预过滤器后过滤器选项接受普通分析器名称。

POST test/_search
{
  "suggest": {
    "text" : "obel prize",
    "simple_phrase" : {
      "phrase" : {
        "field" : "title.trigram",
        "size" : 1,
        "direct_generator" : [ {
          "field" : "title.trigram",
          "suggest_mode" : "always"
        }, {
          "field" : "title.reverse",
          "suggest_mode" : "always",
          "pre_filter" : "reverse",
          "post_filter" : "reverse"
        } ]
      }
    }
  }
}

pre_filterpost_filter 也可以用于在生成候选词后注入同义词。例如,对于查询 captain usq,我们可能会为术语 usq 生成候选词 usa,这是 america 的同义词。这样,如果这个短语得分足够高,我们就可以向用户展示 captain america

完成建议器

edit

The completion suggester 提供了自动完成/输入即搜索的功能。这是一个导航功能,用于在用户输入时引导他们找到相关结果,从而提高搜索的精确度。它不适用于拼写纠正或类似 termphrase suggesters 的“您是不是想找”功能。

理想情况下,自动完成功能应与用户输入的速度一样快,以提供与用户已输入内容相关的即时反馈。因此,completion suggester 针对速度进行了优化。该 suggester 使用能够实现快速查找的数据结构,但构建成本较高且存储在内存中。

映射

edit

要使用completion suggester,请将您希望从中生成建议的字段映射为类型completion。这将索引字段值以实现快速完成。

PUT music
{
  "mappings": {
    "properties": {
      "suggest": {
        "type": "completion"
      }
    }
  }
}

用于completion字段的参数

edit

以下参数由 completion 字段接受:

analyzer

要使用的索引分析器,默认为 简单

search_analyzer

要使用的搜索分析器,默认为 analyzer 的值。

保留分隔符

保留分隔符,默认为 true。 如果禁用,你可能会找到一个以 Foo Fighters 开头的字段,如果你建议为 foof

preserve_position_increments

启用位置增量,默认为 true。 如果禁用并使用停用词分析器,您可能会得到一个以 The Beatles 开头的字段,如果您建议 b注意:您也可以通过索引两个输入 BeatlesThe Beatles 来实现这一点,如果您能够丰富您的数据,则无需更改简单的分析器。

max_input_length

限制单个输入的长度,默认为 50 个 UTF-16 代码点。 此限制仅在索引时使用,以减少每个输入字符串的总字符数,从而防止大量输入导致底层数据结构膨胀。大多数用例不会受到默认值的影响,因为前缀补全很少会超出几个字符长的前缀。

索引

edit

您可以像其他字段一样索引建议。一个建议由一个input和一个可选的weight属性组成。input是建议查询预期匹配的文本,而weight决定了建议的评分方式。索引一个建议如下所示:

PUT music/_doc/1?refresh
{
  "suggest" : {
    "input": [ "Nevermind", "Nirvana" ],
    "weight" : 34
  }
}

支持以下参数:

输入

要存储的输入,这可以是一个字符串数组或只是一个字符串。此字段是必填的。

此值不能包含以下 UTF-16 控制字符:

  • \u0000(空)
  • \u001f(信息分隔符一)
  • \u001e(信息分隔符二)

weight

一个正整数或包含正整数的字符串, 用于定义权重并允许您对建议进行排序。 此字段是可选的。

您可以为文档索引多个建议,如下所示:

PUT music/_doc/1?refresh
{
  "suggest": [
    {
      "input": "Nevermind",
      "weight": 10
    },
    {
      "input": "Nirvana",
      "weight": 3
    }
  ]
}

你可以使用以下简写形式。请注意,在简写形式中不能指定建议的权重。

PUT music/_doc/1?refresh
{
  "suggest" : [ "Nevermind", "Nirvana" ]
}

查询

edit

建议功能与往常一样,只是您必须将建议类型指定为completion。建议是近乎实时的,这意味着通过刷新可以使新的建议变得可见,而一旦删除的文档将永远不会再显示。这个请求:

POST music/_search?pretty
{
  "suggest": {
    "song-suggest": {
      "prefix": "nir",        
      "completion": {         
          "field": "suggest"  
      }
    }
  }
}

用于搜索建议的前缀

建议的类型

用于搜索建议的字段名称

返回此响应:

{
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits": ...
  "took": 2,
  "timed_out": false,
  "suggest": {
    "song-suggest" : [ {
      "text" : "nir",
      "offset" : 0,
      "length" : 3,
      "options" : [ {
        "text" : "Nirvana",
        "_index": "music",
        "_id": "1",
        "_score": 1.0,
        "_source": {
          "suggest": ["Nevermind", "Nirvana"]
        }
      } ]
    } ]
  }
}

_source 元数据字段必须启用,这是默认行为,以启用返回带有建议的 _source

建议的配置权重返回为 _scoretext 字段使用索引建议的 input。建议默认返回完整的文档 _source_source 的大小可能会由于磁盘获取和网络传输开销而影响性能。 为了节省一些网络开销,可以使用 source filtering_source 中过滤掉不必要的字段,以最小化 _source 的大小。请注意,_suggest 端点不支持源过滤,但在 _search 端点上使用建议时支持:

POST music/_search
{
  "_source": "suggest",     
  "suggest": {
    "song-suggest": {
      "prefix": "nir",
      "completion": {
        "field": "suggest", 
        "size": 5           
      }
    }
  }
}

过滤源以仅返回suggest字段

用于搜索建议的字段名称

返回的建议数量

看起来应该是:

{
  "took": 6,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 0,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "suggest": {
    "song-suggest": [ {
        "text": "nir",
        "offset": 0,
        "length": 3,
        "options": [ {
            "text": "Nirvana",
            "_index": "music",
            "_id": "1",
            "_score": 1.0,
            "_source": {
              "suggest": [ "Nevermind", "Nirvana" ]
            }
          } ]
      } ]
  }
}

基本的完成建议查询支持以下参数:

字段

要在其上运行查询的字段的名称(必填)。

大小

返回的建议数量(默认为5)。

跳过重复项

是否应过滤掉重复的建议(默认为false)。

完成建议器会考虑索引中的所有文档。 请参阅上下文建议器以了解如何查询文档子集的说明。

在跨多个分片完成查询的情况下,建议操作分为两个阶段执行,其中最后一个阶段从分片中获取相关文档,这意味着对单个分片执行完成请求由于文档获取开销而更具性能,当建议跨多个分片时。为了获得最佳的完成性能,建议将完成索引到单个分片索引中。如果由于分片大小导致堆使用率过高,仍然建议将索引拆分为多个分片,而不是为了完成性能进行优化。

跳过重复的建议

edit

查询可能会返回来自不同文档的重复建议。 可以通过将skip_duplicates设置为true来修改此行为。 当设置此选项时,它会从结果中过滤掉具有重复建议的文档。

POST music/_search?pretty
{
  "suggest": {
    "song-suggest": {
      "prefix": "nor",
      "completion": {
        "field": "suggest",
        "skip_duplicates": true
      }
    }
  }
}

当设置为 true 时,此选项可能会减慢搜索速度,因为需要访问更多建议以找到前 N 个。

模糊查询

edit

完成建议器也支持模糊查询——这意味着你可以在搜索中有一个拼写错误,但仍然能得到结果。

POST music/_search?pretty
{
  "suggest": {
    "song-suggest": {
      "prefix": "nor",
      "completion": {
        "field": "suggest",
        "fuzzy": {
          "fuzziness": 2
        }
      }
    }
  }
}

与查询 prefix 共享最长前缀的建议将获得更高的评分。

模糊查询可以接受特定的模糊参数。 支持以下参数:

模糊性

模糊因子,默认为 AUTO。 请参阅 Fuzziness 以了解允许的设置。

转置

如果设置为 true,转置将被计为一次更改而不是两次,默认为 true

min_length

在返回模糊建议之前输入的最小长度,默认为 3

prefix_length

输入的最小长度,不检查模糊替代项,默认为 1

unicode_aware

如果true,所有测量(如模糊编辑距离、转置和长度)都以Unicode代码点而不是字节为单位进行测量。这比原始字节稍慢,因此默认设置为false

如果你想坚持使用默认值,但仍然使用模糊匹配,你可以使用 fuzzy: {}fuzzy: true

正则表达式查询

edit

完成建议器也支持正则表达式查询,这意味着你可以将前缀表示为正则表达式

POST music/_search?pretty
{
  "suggest": {
    "song-suggest": {
      "regex": "n[ever|i]r",
      "completion": {
        "field": "suggest"
      }
    }
  }
}

正则表达式查询可以接受特定的正则表达式参数。 支持以下参数:

标志

可能的标志是 ALL(默认),ANYSTRINGCOMPLEMENTEMPTYINTERSECTIONINTERVAL,或 NONE。请参阅 regexp-syntax 以了解它们的含义

max_determinized_states

正则表达式是危险的,因为很容易意外地创建一个看似无害的正则表达式,该表达式需要Lucene执行时使用指数数量的内部确定化自动机状态(以及相应的RAM和CPU)。Lucene通过使用max_determinized_states设置(默认为10000)来防止这些情况。您可以提高此限制,以允许执行更复杂的正则表达式。

上下文建议器

edit

完成建议器会考虑索引中的所有文档,但通常希望根据某些条件过滤和/或提升建议。例如,您希望根据某些艺术家过滤歌曲标题,或者您希望根据歌曲的流派提升歌曲标题。

要实现建议过滤和/或提升,您可以在配置完成字段时添加上下文映射。您可以为一个完成字段定义多个上下文映射。 每个上下文映射都有一个唯一的名称和类型。有两种类型:类别地理。上下文映射在字段映射中的上下文参数下进行配置。

在索引和查询启用上下文的完成字段时,必须提供上下文。

允许的最大完成字段上下文映射数量是10。

以下定义了类型,每个类型为完成字段提供了两个上下文映射:

PUT place
{
  "mappings": {
    "properties": {
      "suggest": {
        "type": "completion",
        "contexts": [
          {                                 
            "name": "place_type",
            "type": "category"
          },
          {                                 
            "name": "location",
            "type": "geo",
            "precision": 4
          }
        ]
      }
    }
  }
}
PUT place_path_category
{
  "mappings": {
    "properties": {
      "suggest": {
        "type": "completion",
        "contexts": [
          {                           
            "name": "place_type",
            "type": "category",
            "path": "cat"
          },
          {                           
            "name": "location",
            "type": "geo",
            "precision": 4,
            "path": "loc"
          }
        ]
      },
      "loc": {
        "type": "geo_point"
      }
    }
  }
}

定义一个名为 place_typecategory 上下文,其中类别必须与建议一起发送。

定义一个名为 locationgeo 上下文,其中类别必须与建议一起发送。

定义了一个名为 place_typecategory 上下文,其中类别是从 cat 字段读取的。

定义一个名为 locationgeo 上下文,其中类别从 loc 字段读取。

添加上下文映射会增加完成字段的索引大小。完成索引完全驻留在堆内存中,您可以使用索引统计API监控完成字段的索引大小。

类别上下文
edit

The category 上下文允许您在索引时将一个或多个类别与建议关联起来。在查询时,可以根据其关联的类别对建议进行过滤和提升。

映射设置类似于上面的place_type字段。如果定义了path,则从文档中的该路径读取类别,否则必须像这样在suggest字段中发送:

PUT place/_doc/1
{
  "suggest": {
    "input": [ "timmy's", "starbucks", "dunkin donuts" ],
    "contexts": {
      "place_type": [ "cafe", "food" ]                    
    }
  }
}

这些建议将与咖啡馆食品类别相关联。

如果映射有一个 path,那么以下索引请求就足以添加类别:

PUT place_path_category/_doc/1
{
  "suggest": ["timmy's", "starbucks", "dunkin donuts"],
  "cat": ["cafe", "food"] 
}

这些建议将与咖啡馆食品类别相关联。

如果上下文映射引用另一个字段并且类别被显式索引,建议将使用两组类别进行索引。

分类查询
edit

建议可以通过一个或多个类别进行过滤。以下是通过多个类别过滤建议的示例:

POST place/_search?pretty
{
  "suggest": {
    "place_suggestion": {
      "prefix": "tim",
      "completion": {
        "field": "suggest",
        "size": 10,
        "contexts": {
          "place_type": [ "cafe", "restaurants" ]
        }
      }
    }
  }
}

如果在查询中设置了多个类别或类别上下文,它们将作为析取合并。这意味着建议匹配的条件是它们至少包含一个提供的上下文值。

某些类别的建议可以比其他类别提升得更高。 以下过滤器按类别筛选建议,并额外提升与某些类别相关的建议:

POST place/_search?pretty
{
  "suggest": {
    "place_suggestion": {
      "prefix": "tim",
      "completion": {
        "field": "suggest",
        "size": 10,
        "contexts": {
          "place_type": [                             
            { "context": "cafe" },
            { "context": "restaurants", "boost": 2 }
          ]
        }
      }
    }
  }
}

与类别 咖啡馆餐厅 相关的上下文查询过滤建议,并通过一个因子 2 增强了与 餐厅 相关的建议。

除了接受类别值外,上下文查询还可以由多个类别上下文子句组成。以下参数支持category上下文子句:

上下文

要过滤/提升的类别的值。 这是强制性的。

boost

建议的分数应提升的因子,分数是通过将提升值与建议权重相乘计算得出的,默认为1

前缀

类别值是否应作为前缀处理。例如,如果设置为true, 您可以通过指定类别前缀type来过滤类别type1type2等。 默认为false

如果一个建议条目匹配多个上下文,最终得分将计算为任何匹配上下文产生的最大得分。

地理位置上下文
edit

一个 geo 上下文允许你在索引时将一个或多个地理点或地理哈希与建议关联起来。在查询时,如果建议位于指定地理位置的某个距离内,则可以对其进行过滤和提升。

在内部,地理点以指定精度的geohash编码。

地理映射
edit

除了 path 设置外,geo 上下文映射还接受以下设置:

精度

这定义了要索引的地理哈希的精度,可以指定为距离值(5m10km 等),或作为原始地理哈希精度(1..12)。默认值为原始地理哈希精度值 6

索引时间 precision 设置设置了查询时可以使用的最大 geohash 精度。

索引地理上下文
edit

geo 上下文可以通过建议显式设置,或者通过 path 参数从文档中的地理点字段索引,类似于 category 上下文。将多个地理位置上下文与建议关联,将为每个地理位置索引建议。以下是为两个地理位置上下文索引建议的示例:

PUT place/_doc/1
{
  "suggest": {
    "input": "timmy's",
    "contexts": {
      "location": [
        {
          "lat": 43.6624803,
          "lon": -79.3863353
        },
        {
          "lat": 43.6624718,
          "lon": -79.3873227
        }
      ]
    }
  }
}
地理位置查询
edit

建议可以根据它们与一个或多个地理点的接近程度进行过滤和提升。以下过滤器筛选出位于由地理点的编码geohash表示的区域内的建议:

POST place/_search
{
  "suggest": {
    "place_suggestion": {
      "prefix": "tim",
      "completion": {
        "field": "suggest",
        "size": 10,
        "contexts": {
          "location": {
            "lat": 43.662,
            "lon": -79.380
          }
        }
      }
    }
  }
}

当查询时指定了一个精度较低的位置时,所有位于该区域内的建议都将被考虑。

如果在查询中设置了多个类别或类别上下文,它们将作为析取合并。这意味着建议匹配的条件是它们至少包含一个提供的上下文值。

位于由geohash表示的区域内的建议也可以比其他建议获得更高的提升,如下所示:

POST place/_search?pretty
{
  "suggest": {
    "place_suggestion": {
      "prefix": "tim",
      "completion": {
        "field": "suggest",
        "size": 10,
        "contexts": {
          "location": [             
                      {
              "lat": 43.6624803,
              "lon": -79.3863353,
              "precision": 2
            },
            {
              "context": {
                "lat": 43.6624803,
                "lon": -79.3863353
              },
              "boost": 2
            }
          ]
        }
      }
    }
  }
}

上下文查询过滤掉那些不符合地理定位的建议,该地理定位由一个精度为2的geohash表示,其坐标为(43.662, -79.380),并提升那些符合geohash表示的建议,其坐标为(43.6624803, -79.3863353),默认精度为6,提升因子为2

如果一个建议条目匹配多个上下文,最终得分将计算为任何匹配上下文产生的最大得分。

除了接受上下文值外,上下文查询还可以由多个上下文子句组成。以下参数支持geo上下文子句:

上下文

一个地理点对象或一个地理哈希字符串,用于过滤或提升建议。这是强制性的。

boost

建议的分数应提升的因子,分数是通过将提升值与建议权重相乘计算得出的,默认为1

精度

编码查询地理点时geohash的精度。 这可以指定为距离值(5m10km等), 或作为原始geohash精度(1..12)。 默认为索引时间精度级别。

邻居

接受一个精度值数组,在该精度值下应考虑相邻的地理哈希。 精度值可以是距离值(5m10km 等) 或原始地理哈希精度(1..12)。默认情况下, 为索引时间精度级别生成邻居。

精度字段不会导致距离匹配。 指定一个距离值,如10km,只会导致一个表示该大小的瓦片的geohash精度值。 精度将用于将搜索的地理点编码为用于完成匹配的geohash瓦片。 这样做的结果是,即使非常接近搜索点的点,如果位于该瓦片之外,也不会被匹配。 减少精度或增加距离可以降低这种情况发生的风险,但不能完全消除。

返回建议器的类型

edit

有时你需要知道建议器的准确类型,以便解析其结果。可以使用typed_keys参数来更改响应中建议器的名称,使其带有类型的前缀。

考虑以下包含两个建议器 termphrase 的示例:

POST _search?typed_keys
{
  "suggest": {
    "text" : "some test mssage",
    "my-first-suggester" : {
      "term" : {
        "field" : "message"
      }
    },
    "my-second-suggester" : {
      "phrase" : {
        "field" : "message"
      }
    }
  }
}

在响应中,建议器的名称将分别更改为 term#my-first-suggesterphrase#my-second-suggester,反映每个建议的类型:

{
  "suggest": {
    "term#my-first-suggester": [ 
      {
        "text": "some",
        "offset": 0,
        "length": 4,
        "options": []
      },
      {
        "text": "test",
        "offset": 5,
        "length": 4,
        "options": []
      },
      {
        "text": "mssage",
        "offset": 10,
        "length": 6,
        "options": [
          {
            "text": "message",
            "score": 0.8333333,
            "freq": 4
          }
        ]
      }
    ],
    "phrase#my-second-suggester": [ 
      {
        "text": "some test mssage",
        "offset": 0,
        "length": 16,
        "options": [
          {
            "text": "some test message",
            "score": 0.030227963
          }
        ]
      }
    ]
  },
  ...
}

名称 my-first-suggester 现在包含 term 前缀。

名称 my-second-suggester 现在包含 phrase 前缀。

多搜索 API

edit

通过单个API请求执行多个搜索。

GET my-index-000001/_msearch
{ }
{"query" : {"match" : { "message": "this is a test"}}}
{"index": "my-index-000002"}
{"query" : {"match_all" : {}}}

请求

edit

GET //_msearch

先决条件

edit
  • 如果启用了Elasticsearch安全功能,您必须具有目标数据流、索引或别名的读取 索引权限。对于跨集群搜索,请参阅远程集群

描述

edit

多搜索 API 通过单个 API 请求执行多个搜索。 请求的格式类似于批量 API 格式,并使用了换行符分隔的 JSON (NDJSON) 格式。

结构如下:

header\n
body\n
header\n
body\n

此结构专门优化以减少解析,如果特定搜索最终被重定向到另一个节点。

数据的最后一行必须以换行符 \n 结束。每个换行符前面可以有一个回车符 \r。当向此端点发送请求时,Content-Type 头应设置为 application/x-ndjson

路径参数

edit
<target>

(可选, 字符串) 逗号分隔的数据流、索引和别名列表,用于搜索。

如果请求体中的搜索未指定索引目标,此列表将作为回退。

通配符(*)表达式是支持的。要在集群中搜索所有数据流和索引,请省略此参数或使用 _all*

查询参数

edit
allow_no_indices
(可选, 布尔值) 如果为false,当任何通配符表达式、 索引别名_all值仅针对缺失或关闭的索引时,请求将返回错误。 即使请求针对其他打开的索引,此行为也适用。例如,如果一个请求针对foo*,bar*,但没有任何索引以bar开头,即使存在以foo开头的索引,请求也会返回错误。
ccs_minimize_roundtrips
(可选, 布尔值) 如果为true,则在协调节点和远程集群之间进行跨集群搜索请求时,网络往返次数将最小化。默认为true。请参阅 跨集群搜索如何处理网络延迟
expand_wildcards

(可选,字符串) 通配符模式可以匹配的索引类型。如果请求可以针对数据流,此参数确定通配符表达式是否匹配隐藏的数据流。支持逗号分隔的值,例如 open,hidden。有效值为:

all
匹配任何数据流或索引,包括 隐藏的 数据流和索引。
open
匹配开放的、非隐藏的索引。同时也匹配任何非隐藏的数据流。
closed
匹配关闭的、非隐藏的索引。同时也匹配任何非隐藏的数据流。数据流不能被关闭。
hidden
匹配隐藏的数据流和隐藏的索引。必须与 openclosed 或两者结合使用。
none
不接受通配符模式。

默认为 open

ignore_throttled

(可选,布尔值) 如果为 true,冻结时会忽略具体的、扩展的或别名的索引。默认为 true

[7.16.0] 在7.16.0中已弃用。

ignore_unavailable
(可选,布尔值) 如果为false,则当请求目标是一个缺失或关闭的索引时,请求将返回错误。默认为false
max_concurrent_searches
(可选, 整数) 多搜索 API 可以执行的最大并发搜索数。默认为 max(1, (# of 数据节点 * min(搜索线程池大小, 10)))
max_concurrent_shard_requests

(可选, 整数) 每个子搜索请求在每个节点上执行的最大并发分片请求数。默认为 5

您可以使用此参数来防止请求使集群过载。例如,默认请求会命中集群中的所有数据流和索引。如果每个节点的分片数量很高,这可能会导致分片请求被拒绝。

在某些场景下,并行性并不是通过并发请求实现的。在这些情况下,此参数的低值可能会导致性能不佳。例如,在预期并发搜索请求数量非常低的环境中,此参数的较高值可能会提高性能。

pre_filter_shard_size

(可选, 整数) 定义一个阈值,如果搜索请求扩展到的分片数量超过该阈值,则强制执行预过滤往返以基于查询重写预过滤搜索分片。如果例如某个分片无法基于其重写方法匹配任何文档,则此过滤往返可以显著限制分片数量,即,如果日期过滤器是强制匹配的,但分片边界和查询是不相交的。 当未指定时,如果满足以下任一条件,则执行预过滤阶段:

  • 请求目标超过 128 个分片。
  • 请求目标一个或多个只读索引。
  • 查询的主排序目标是一个索引字段。
rest_total_hits_as_int
(可选, 布尔值) 如果为truehits.total将在响应中作为整数返回。默认为false,这将返回一个对象。
routing
(可选, 字符串) 自定义 路由值 用于将搜索操作路由到特定分片。
search_type

(可选,字符串) 指示在评分返回的文档时是否应使用全局术语和文档频率。

选项包括:

query_then_fetch
(默认) 文档使用分片的本地术语和文档频率进行评分。 这通常更快但准确性较低。
dfs_query_then_fetch
文档使用所有分片的全局术语和文档频率进行评分。 这通常较慢但更准确。
typed_keys
(可选, 布尔值) 指定在响应中聚合和建议器的名称是否应以其各自类型为前缀。

请求体

edit

请求体包含一个以换行符分隔的搜索

和搜索 对象列表。

<header>

(必需, 对象) 用于限制或更改搜索的参数。

此对象是每个搜索体所必需的,但可以是空的({})或空白行。

Properties of
objects
allow_no_indices

(可选,布尔值) 如果为true,则当通配符表达式或_all值仅检索到缺失或关闭的索引时,请求不会返回错误。

此参数也适用于指向缺失或索引的别名

expand_wildcards

(可选,字符串) 通配符模式可以匹配的索引类型。如果请求可以针对数据流,此参数确定通配符表达式是否匹配隐藏的数据流。支持逗号分隔的值,例如 open,hidden。有效值为:

all
匹配任何数据流或索引,包括隐藏的。
open
匹配开放的、非隐藏的索引。也匹配任何非隐藏的数据流。
closed
匹配关闭的、非隐藏的索引。也匹配任何非隐藏的数据流。数据流不能被关闭。
hidden
匹配隐藏的数据流和隐藏的索引。必须与openclosed或两者结合使用。
none
不接受通配符模式。

默认为 open

ignore_unavailable
(可选, 布尔值) 如果为true,则缺失或关闭的索引中的文档不会包含在响应中。默认为false
index

(可选,字符串或字符串数组) 要搜索的数据流、索引和别名。支持通配符 (*)。可以通过数组指定多个目标。

如果未指定此参数,则使用 请求路径参数作为回退。

preference
(可选, 字符串) 用于执行搜索的节点或分片。默认为随机。
request_cache
(可选, 布尔值) 如果为true,则可以为此搜索使用请求缓存。默认为索引级设置。参见分片请求缓存设置
routing
(可选, 字符串) 用于将搜索操作路由到特定分片的自定义路由值
search_type

(可选,字符串) 指示在评分返回的文档时是否应使用全局术语和文档频率。

选项包括:

query_then_fetch
(默认) 文档使用分片的本地术语和文档频率进行评分。这通常更快但不太准确。
dfs_query_then_fetch
文档使用所有分片的全局术语和文档频率进行评分。这通常较慢但更准确。
<body>

(可选, 对象) 包含搜索请求的参数:

Properties of objects
aggregations
(可选, 聚合对象) 您希望在搜索期间运行的聚合。请参阅 聚合
query
(可选, 查询DSL对象) 您希望在搜索期间运行的查询。与该查询匹配的命中将在响应中返回。
from
(可选, 整数) 返回命中的起始偏移量。默认为 0
size
(可选, 整数) 返回的命中数量。默认为 10

响应体

edit
responses
(数组) 包含每个搜索请求的搜索响应和状态码,与其在原始多搜索请求中的顺序相匹配。如果某个特定的搜索请求完全失败,将返回一个包含 error 消息和相应状态码的对象,以替代实际的搜索响应。

示例

edit

头部包括数据流、索引和别名以进行搜索。头部还指示了search_typepreferencerouting。主体包括典型的搜索主体请求(包括queryaggregationsfromsize等)。

$ cat requests
{"index" : "test"}
{"query" : {"match_all" : {}}, "from" : 0, "size" : 10}
{"index" : "test", "search_type" : "dfs_query_then_fetch"}
{"query" : {"match_all" : {}}}
{}
{"query" : {"match_all" : {}}}

{"query" : {"match_all" : {}}}
{"search_type" : "dfs_query_then_fetch"}
{"query" : {"match_all" : {}}}
$ curl -H "Content-Type: application/x-ndjson" -XGET localhost:9200/_msearch --data-binary "@requests"; echo

注意,上述内容包含一个空标题的示例(也可以没有任何内容),这也是支持的。

该端点还允许您在请求路径中搜索数据流、索引和别名。在这种情况下,它将作为默认目标,除非在头部的 index 参数中明确指定。例如:

GET my-index-000001/_msearch
{}
{"query" : {"match_all" : {}}, "from" : 0, "size" : 10}
{}
{"query" : {"match_all" : {}}}
{"index" : "my-index-000002"}
{"query" : {"match_all" : {}}}

上述操作将对 my-index-000001 索引执行搜索,适用于请求体中未定义 index 目标的所有请求。最后一次搜索将在 my-index-000002 索引上执行。

可以在全局范围内以类似的方式设置search_type,以应用于所有搜索请求。

安全性

edit

请参阅基于URL的访问控制

部分响应

edit

为了确保快速响应,如果一个或多个分片失败,多搜索 API 将返回部分结果。更多信息请参见 分片失败

搜索取消

edit

多重搜索可以通过标准的任务取消机制来取消,并且在执行请求时使用的HTTP连接被客户端关闭时也会自动取消。重要的是,发送请求的HTTP客户端在请求超时或中止时关闭连接。取消msearch请求也会取消所有相应的子搜索请求。

计数 API

edit

获取搜索查询的匹配数量。

GET /my-index-000001/_count?q=user:kimchy

在请求体中发送的查询必须嵌套在query键中,与搜索API的工作方式相同。

请求

edit

GET //_count

先决条件

edit
  • 如果启用了Elasticsearch安全功能,您必须对目标数据流、索引或别名具有权限。 索引权限

描述

edit

count API 允许你执行一个查询并获取该查询的匹配数量。查询可以通过简单查询字符串作为参数提供,或者使用请求体中定义的 Query DSL

count API 支持 多目标语法。您可以在多个数据流和索引上运行单个 count API 搜索。

该操作会在所有分片上进行广播。对于每个分片ID组,会选择一个副本并在其上执行。这意味着副本增加了计数的可扩展性。

路径参数

edit
<target>
(可选,字符串) 要搜索的数据流、索引和别名的逗号分隔列表。支持通配符 (*)。要搜索所有数据流和索引,请省略此参数或使用 *_all

查询参数

edit
allow_no_indices

(可选, 布尔值) 如果为false,当任何通配符表达式、 索引别名_all值仅针对缺失或关闭的索引时,请求将返回错误。 即使请求针对其他打开的索引,此行为也适用。例如,如果一个请求针对foo*,bar*,但没有任何索引以bar开头,即使存在以foo开头的索引,请求也会返回错误。

默认为 true

analyzer

(可选, 字符串) 用于查询字符串的分析器。

此参数只能在指定了 q 查询字符串参数时使用。

analyze_wildcard

(可选,布尔值) 如果为 true,通配符和前缀查询会被分析。 默认为 false

此参数只能在指定了 q 查询字符串参数时使用。

default_operator

(可选,字符串) 查询字符串查询的默认操作符:AND 或 OR。 默认为 OR

此参数只能在指定了 q 查询字符串参数时使用。

df

(可选,字符串) 在查询字符串中没有给出字段前缀时,用作默认字段的字段。

此参数只能在指定了 q 查询字符串参数时使用。

expand_wildcards

(可选,字符串) 通配符模式可以匹配的索引类型。如果请求可以针对数据流,此参数确定通配符表达式是否匹配隐藏的数据流。支持逗号分隔的值,例如 open,hidden。有效值为:

all
匹配任何数据流或索引,包括 隐藏的 数据流和索引。
open
匹配开放的、非隐藏的索引。同时也匹配任何非隐藏的数据流。
closed
匹配关闭的、非隐藏的索引。同时也匹配任何非隐藏的数据流。数据流不能被关闭。
hidden
匹配隐藏的数据流和隐藏的索引。必须与 openclosed 或两者结合使用。
none
不接受通配符模式。

默认为 open

ignore_throttled

(可选,布尔值) 如果为 true,冻结时会忽略具体的、扩展的或别名的索引。默认为 true

[7.16.0] 在7.16.0中已弃用。

ignore_unavailable
(可选,布尔值) 如果为false,则当请求目标是一个缺失或关闭的索引时,请求将返回错误。默认为false
lenient

(可选,布尔值) 如果为 true,查询字符串中基于格式的查询失败(例如向数值字段提供文本)将被忽略。默认为 false

此参数只能在指定了 q 查询字符串参数时使用。

min_score
(可选, 浮点数) 设置文档必须具有的最小 _score 值,以便包含在结果中。
preference
(可选,字符串) 指定操作应在其上执行的节点或分片。默认情况下是随机的。
q
(可选,字符串) 使用Lucene查询字符串语法的查询。
routing
(可选, 字符串) 自定义值,用于将操作路由到特定分片。
terminate_after

(可选,整数) 每个分片收集的最大文档数。如果查询达到此限制,Elasticsearch 会提前终止查询。Elasticsearch 在排序之前收集文档。

谨慎使用。Elasticsearch将此参数应用于处理请求的每个分片。如果可能,让Elasticsearch自动执行早期终止。避免为针对具有跨多个数据层的后备索引的数据流请求指定此参数。

请求体

edit
query
(可选, 查询对象) 使用 查询DSL定义搜索定义。

示例

edit
PUT /my-index-000001/_doc/1?refresh
{
  "user.id": "kimchy"
}

GET /my-index-000001/_count?q=user:kimchy

GET /my-index-000001/_count
{
  "query" : {
    "term" : { "user.id" : "kimchy" }
  }
}

上述两个示例都做同样的事情:统计在 my-index-000001 中具有 user.idkimchy 的文档数量。API 返回以下响应:

{
  "count": 1,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  }
}

查询是可选的,当未提供时,它将使用 match_all 来计数所有文档。

验证 API

edit

验证一个可能代价高昂的查询而不执行它。

GET my-index-000001/_validate/query?q=user.id:kimchy

请求

edit

GET //_validate/

先决条件

edit
  • 如果启用了Elasticsearch安全功能,您必须对目标数据流、索引或别名具有权限。 索引权限

描述

edit

validate API 允许您在不执行的情况下验证一个可能代价高昂的查询。查询可以作为路径参数或请求体发送。

路径参数

edit
<target>
(可选,字符串) 要搜索的数据流、索引和别名的逗号分隔列表。支持通配符 (*)。要搜索所有数据流或索引,请省略此参数或使用 *_all
query
(可选, 查询对象) 使用 查询DSL定义搜索定义。

查询参数

edit
all_shards
(可选,布尔值) 如果为true,验证将在所有分片上执行,而不是每个索引的一个随机分片。默认为false
allow_no_indices

(可选, 布尔值) 如果为false,当任何通配符表达式、 索引别名_all值仅针对缺失或关闭的索引时,请求将返回错误。 即使请求针对其他打开的索引,此行为也适用。例如,如果一个请求针对foo*,bar*,但没有任何索引以bar开头,即使存在以foo开头的索引,请求也会返回错误。

默认为 false

analyzer

(可选, 字符串) 用于查询字符串的分析器。

此参数只能在指定了 q 查询字符串参数时使用。

analyze_wildcard

(可选,布尔值) 如果为 true,通配符和前缀查询会被分析。 默认为 false

此参数只能在指定了 q 查询字符串参数时使用。

default_operator

(可选,字符串) 查询字符串查询的默认操作符:AND 或 OR。 默认为 OR

此参数只能在指定了 q 查询字符串参数时使用。

df

(可选,字符串) 在查询字符串中没有给出字段前缀时,用作默认字段的字段。

此参数只能在指定了 q 查询字符串参数时使用。

expand_wildcards

(可选,字符串) 通配符模式可以匹配的索引类型。如果请求可以针对数据流,此参数确定通配符表达式是否匹配隐藏的数据流。支持逗号分隔的值,例如 open,hidden。有效值为:

all
匹配任何数据流或索引,包括 隐藏的 数据流和索引。
open
匹配开放的、非隐藏的索引。同时也匹配任何非隐藏的数据流。
closed
匹配关闭的、非隐藏的索引。同时也匹配任何非隐藏的数据流。数据流不能被关闭。
hidden
匹配隐藏的数据流和隐藏的索引。必须与 openclosed 或两者结合使用。
none
不接受通配符模式。
explain
(可选,布尔值) 如果 true,响应会在发生错误时返回详细信息。默认为 false
ignore_unavailable
(可选,布尔值) 如果为false,则当请求目标是一个缺失或关闭的索引时,请求将返回错误。默认为false
lenient

(可选,布尔值) 如果为 true,查询字符串中基于格式的查询失败(例如向数值字段提供文本)将被忽略。默认为 false

此参数只能在指定了 q 查询字符串参数时使用。

rewrite
(可选,布尔值) 如果为 true,则返回更详细的解释,显示将执行的实际 Lucene 查询。默认为 false
q
(可选,字符串) 使用Lucene查询字符串语法的查询。

示例

edit
PUT my-index-000001/_bulk?refresh
{"index":{"_id":1}}
{"user" : { "id": "kimchy" }, "@timestamp" : "2099-11-15T14:12:12", "message" : "trying out Elasticsearch"}
{"index":{"_id":2}}
{"user" : { "id": "kimchi" }, "@timestamp" : "2099-11-15T14:12:13", "message" : "My user ID is similar to kimchy!"}

当发送一个有效的查询时:

GET my-index-000001/_validate/query?q=user.id:kimchy

响应包含 valid:true

{"valid":true,"_shards":{"total":1,"successful":1,"failed":0}}

查询也可以在请求体中发送:

GET my-index-000001/_validate/query
{
  "query" : {
    "bool" : {
      "must" : {
        "query_string" : {
          "query" : "*:*"
        }
      },
      "filter" : {
        "term" : { "user.id" : "kimchy" }
      }
    }
  }
}

在请求体中发送的查询必须嵌套在query键中,与搜索API的工作方式相同

如果查询无效,valid 将为 false。这里查询无效,因为 Elasticsearch 知道 post_date 字段应为日期,由于动态映射,而 foo 不能正确解析为日期:

GET my-index-000001/_validate/query
{
  "query": {
    "query_string": {
      "query": "@timestamp:foo",
      "lenient": false
    }
  }
}
{"valid":false,"_shards":{"total":1,"successful":1,"failed":0}}

解释参数

edit

可以指定一个 explain 参数来获取有关查询失败原因的更详细信息:

GET my-index-000001/_validate/query?explain=true
{
  "query": {
    "query_string": {
      "query": "@timestamp:foo",
      "lenient": false
    }
  }
}

API返回以下响应:

{
  "valid" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "failed" : 0
  },
  "explanations" : [ {
    "index" : "my-index-000001",
    "valid" : false,
    "error" : "my-index-000001/IAEc2nIXSSunQA_suI0MLw] QueryShardException[failed to create query:...failed to parse date field [foo]"
  } ]
}

重写参数

edit

当查询有效时,解释默认显示该查询的字符串表示。当rewrite设置为true时,解释会更加详细,展示将要执行的实际Lucene查询。

GET my-index-000001/_validate/query?rewrite=true
{
  "query": {
    "more_like_this": {
      "like": {
        "_id": "2"
      },
      "boost_terms": 1
    }
  }
}

API返回以下响应:

{
   "valid": true,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "explanations": [
      {
         "index": "my-index-000001",
         "valid": true,
         "explanation": "((user:terminator^3.71334 plot:future^2.763601 plot:human^2.8415773 plot:sarah^3.4193945 plot:kyle^3.8244398 plot:cyborg^3.9177752 plot:connor^4.040236 plot:reese^4.7133346 ... )~6) -ConstantScore(_id:2)) #(ConstantScore(_type:_doc))^0.0"
      }
   ]
}

重写和all_shards参数

edit

默认情况下,请求仅在一个随机选择的分片上执行。查询的详细解释可能取决于所命中的分片,因此可能因请求而异。因此,在查询重写的情况下,应使用all_shards参数从所有可用分片获取响应。

GET my-index-000001/_validate/query?rewrite=true&all_shards=true
{
  "query": {
    "match": {
      "user.id": {
        "query": "kimchy",
        "fuzziness": "auto"
      }
    }
  }
}

API返回以下响应:

{
  "valid": true,
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "explanations": [
    {
      "index": "my-index-000001",
      "shard": 0,
      "valid": true,
      "explanation": "(user.id:kimchi)^0.8333333 user.id:kimchy"
    }
  ]
}

Terms enum API

edit

术语枚举 API 可用于发现索引中与部分字符串匹配的术语。支持的字段类型有 keyword, constant_keyword, flattened, versionip。此功能用于自动完成:

POST stackoverflow/_terms_enum
{
    "field" : "tags",
    "string" : "kiba"
}

API返回以下响应:

{
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "terms": [
    "kibana"
  ],
  "complete" : true
}

如果complete标志为false,返回的terms集可能是不完整的,应视为近似值。这可能由于一些原因发生,例如请求超时或节点错误。

术语枚举 API 可能会从已删除的文档中返回术语。已删除的文档最初仅被标记为已删除。直到它们的段被 合并时,文档才会实际删除。在此之前,术语枚举 API 将返回这些文档中的术语。

请求

edit

GET //_terms_enum

描述

edit

terms_enum API 可用于发现索引中以提供的字符串开头的术语。它专为在自动完成场景中使用的低延迟查找而设计。

路径参数

edit
<target>
(必需,字符串) 要搜索的数据流、索引和别名的逗号分隔列表。支持通配符 (*)。要搜索所有数据流或索引,请省略此参数或使用 *_all

请求体

edit
field
(必填, 字符串) 匹配的字段
string
(可选,字符串) 要匹配索引词开头的字符串。如果未提供,则认为该字段中的所有词都被考虑。

前缀字符串不能大于可能的最大关键字值,即Lucene的词条字节长度限制为32766

size
(可选, 整数) 返回多少个匹配的词条。默认为10
timeout
(可选, 时间值) 收集结果的最大时间长度。默认为 "1s"(一秒)。 如果超时,响应中的 complete 标志将设置为 false,结果可能是部分或空的。
case_insensitive
(可选,布尔值) 当为true时,提供的搜索字符串在匹配索引项时忽略大小写。 默认为false。
index_filter
(可选, 查询对象 允许在提供的查询重写为 match_none 时过滤索引分片。
search_after
(可选, 字符串) 索引中应在之后返回的术语的字符串。如果一个请求的最后一个结果作为search_after参数传递给后续请求,则允许分页形式。

解释 API

edit

返回有关特定文档为何匹配(或不匹配)查询的信息。

GET /my-index-000001/_explain/0
{
  "query" : {
    "match" : { "message" : "elasticsearch" }
  }
}

请求

edit

GET //_explain/

POST //_explain/

先决条件

edit
  • 如果启用了Elasticsearch安全功能,您必须对目标索引具有read 索引权限

描述

edit

explain API 计算一个查询和一个特定文档的得分解释。这可以提供有用的反馈,说明一个文档是否匹配或未匹配特定查询。

路径参数

edit
<id>
(必需,整数) 定义文档ID。
<index>

(必需,字符串) 用于限制请求的索引名称。

只能为此参数提供一个索引名称。

查询参数

edit
analyzer

(可选, 字符串) 用于查询字符串的分析器。

此参数只能在指定了 q 查询字符串参数时使用。

analyze_wildcard

(可选,布尔值) 如果为 true,通配符和前缀查询会被分析。 默认为 false

此参数只能在指定了 q 查询字符串参数时使用。

default_operator

(可选,字符串) 查询字符串查询的默认操作符:AND 或 OR。 默认为 OR

此参数只能在指定了 q 查询字符串参数时使用。

df

(可选,字符串) 在查询字符串中没有给出字段前缀时,用作默认字段的字段。

此参数只能在指定了 q 查询字符串参数时使用。

lenient

(可选,布尔值) 如果为 true,查询字符串中基于格式的查询失败(例如向数值字段提供文本)将被忽略。默认为 false

此参数只能在指定了 q 查询字符串参数时使用。

preference
(可选,字符串) 指定操作应在其上执行的节点或分片。默认情况下是随机的。
q
(可选,字符串) 使用Lucene查询字符串语法的查询。
stored_fields
(可选,字符串) 以逗号分隔的存储字段列表,返回在响应中。
routing
(可选, 字符串) 自定义值,用于将操作路由到特定分片。
_source
(可选,字符串) 返回 _source 字段与否,或者返回的字段列表。
_source_excludes

(可选,字符串) 一个逗号分隔的列表,用于从响应中排除源字段

您也可以使用此参数从_source_includes查询参数中指定的子集中排除字段。

如果 _source 参数为 false,则忽略此参数。

_source_includes

(可选,字符串) 一个逗号分隔的源字段列表,用于包含在响应中。

如果指定了此参数,则仅返回这些源字段。您可以使用_source_excludes查询参数从此子集中排除字段。

如果 _source 参数为 false,则忽略此参数。

请求体

edit
query
(可选, 查询对象) 使用 查询DSL定义搜索定义。

示例

edit
GET /my-index-000001/_explain/0
{
  "query" : {
    "match" : { "message" : "elasticsearch" }
  }
}

API返回以下响应:

{
   "_index":"my-index-000001",
   "_id":"0",
   "matched":true,
   "explanation":{
      "value":1.6943598,
      "description":"weight(message:elasticsearch in 0) [PerFieldSimilarity], result of:",
      "details":[
         {
            "value":1.6943598,
            "description":"score(freq=1.0), computed as boost * idf * tf from:",
            "details":[
               {
                  "value":2.2,
                  "description":"boost",
                  "details":[]
               },
               {
                  "value":1.3862944,
                  "description":"idf, computed as log(1 + (N - n + 0.5) / (n + 0.5)) from:",
                  "details":[
                     {
                        "value":1,
                        "description":"n, number of documents containing term",
                        "details":[]
                     },
                     {
                        "value":5,
                        "description":"N, total number of documents with field",
                        "details":[]
                     }
                  ]
               },
               {
                  "value":0.5555556,
                  "description":"tf, computed as freq / (freq + k1 * (1 - b + b * dl / avgdl)) from:",
                  "details":[
                     {
                        "value":1.0,
                        "description":"freq, occurrences of term within document",
                        "details":[]
                     },
                     {
                        "value":1.2,
                        "description":"k1, term saturation parameter",
                        "details":[]
                     },
                     {
                        "value":0.75,
                        "description":"b, length normalization parameter",
                        "details":[]
                     },
                     {
                        "value":3.0,
                        "description":"dl, length of field",
                        "details":[]
                     },
                     {
                        "value":5.4,
                        "description":"avgdl, average length of field",
                        "details":[]
                     }
                  ]
               }
            ]
         }
      ]
   }
}

还有一种更简单的方式来通过 q 参数指定查询。指定的 q 参数值会被解析,就像使用了 query_string 查询一样。以下是在 explain API 中使用 q 参数的示例:

GET /my-index-000001/_explain/0?q=message:search

API返回的结果与之前的请求相同。

配置文件 API

edit

Profile API 是一个调试工具,并且会增加搜索执行的显著开销。

提供关于搜索请求中各个组件执行情况的详细时间信息。

描述

edit

Profile API 让用户深入了解搜索请求在低级别是如何执行的,以便用户可以理解为什么某些请求较慢,并采取措施来改进它们。请注意,Profile API,除了其他事项外,不测量网络延迟、请求在队列中花费的时间,或协调节点上合并分片响应所花费的时间。

Profile API 的输出非常详细,特别是对于跨多个分片执行的复杂请求。建议对响应进行美化打印,以帮助理解输出。

示例

edit

任何 _search 请求都可以通过添加一个顶级的 profile 参数来进行分析:

GET /my-index-000001/_search
{
  "profile": true,
  "query" : {
    "match" : { "message" : "GET /search" }
  }
}

将顶级 profile 参数设置为 true 将启用搜索的分析功能。

API返回以下结果:

{
  "took": 25,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 5,
      "relation": "eq"
    },
    "max_score": 0.17402273,
    "hits": [...] 
  },
  "profile": {
    "shards": [
      {
        "id": "[q2aE02wS1R8qQFnYu6vDVQ][my-index-000001][0]",
        "node_id": "q2aE02wS1R8qQFnYu6vDVQ",
        "shard_id": 0,
        "index": "my-index-000001",
        "cluster": "(local)",
        "searches": [
          {
            "query": [
              {
                "type": "BooleanQuery",
                "description": "message:get message:search",
                "time_in_nanos" : 11972972,
                "breakdown" : {
                  "set_min_competitive_score_count": 0,
                  "match_count": 5,
                  "shallow_advance_count": 0,
                  "set_min_competitive_score": 0,
                  "next_doc": 39022,
                  "match": 4456,
                  "next_doc_count": 5,
                  "score_count": 5,
                  "compute_max_score_count": 0,
                  "compute_max_score": 0,
                  "advance": 84525,
                  "advance_count": 1,
                  "score": 37779,
                  "build_scorer_count": 2,
                  "create_weight": 4694895,
                  "shallow_advance": 0,
                  "create_weight_count": 1,
                  "build_scorer": 7112295,
                  "count_weight": 0,
                  "count_weight_count": 0
                },
                "children": [
                  {
                    "type": "TermQuery",
                    "description": "message:get",
                    "time_in_nanos": 3801935,
                    "breakdown": {
                      "set_min_competitive_score_count": 0,
                      "match_count": 0,
                      "shallow_advance_count": 3,
                      "set_min_competitive_score": 0,
                      "next_doc": 0,
                      "match": 0,
                      "next_doc_count": 0,
                      "score_count": 5,
                      "compute_max_score_count": 3,
                      "compute_max_score": 32487,
                      "advance": 5749,
                      "advance_count": 6,
                      "score": 16219,
                      "build_scorer_count": 3,
                      "create_weight": 2382719,
                      "shallow_advance": 9754,
                      "create_weight_count": 1,
                      "build_scorer": 1355007,
                      "count_weight": 0,
                      "count_weight_count": 0
                    }
                  },
                  {
                    "type": "TermQuery",
                    "description": "message:search",
                    "time_in_nanos": 205654,
                    "breakdown": {
                      "set_min_competitive_score_count": 0,
                      "match_count": 0,
                      "shallow_advance_count": 3,
                      "set_min_competitive_score": 0,
                      "next_doc": 0,
                      "match": 0,
                      "next_doc_count": 0,
                      "score_count": 5,
                      "compute_max_score_count": 3,
                      "compute_max_score": 6678,
                      "advance": 12733,
                      "advance_count": 6,
                      "score": 6627,
                      "build_scorer_count": 3,
                      "create_weight": 130951,
                      "shallow_advance": 2512,
                      "create_weight_count": 1,
                      "build_scorer": 46153,
                      "count_weight": 0,
                      "count_weight_count": 0
                    }
                  }
                ]
              }
            ],
            "rewrite_time": 451233,
            "collector": [
              {
                "name": "QueryPhaseCollector",
                "reason": "search_query_phase",
                "time_in_nanos": 775274,
                "children" : [
                  {
                    "name": "SimpleTopScoreDocCollector",
                    "reason": "search_top_hits",
                    "time_in_nanos": 775274
                  }
                ]
              }
            ]
          }
        ],
        "aggregations": [],
        "fetch": {
          "type": "fetch",
          "description": "",
          "time_in_nanos": 660555,
          "breakdown": {
            "next_reader": 7292,
            "next_reader_count": 1,
            "load_stored_fields": 299325,
            "load_stored_fields_count": 5,
            "load_source": 3863,
            "load_source_count": 5
          },
          "debug": {
            "stored_fields": ["_id", "_routing", "_source"]
          },
          "children": [
            {
              "type" : "FetchFieldsPhase",
              "description" : "",
              "time_in_nanos" : 238762,
              "breakdown" : {
                "process_count" : 5,
                "process" : 227914,
                "next_reader" : 10848,
                "next_reader_count" : 1
              }
            },
            {
              "type": "FetchSourcePhase",
              "description": "",
              "time_in_nanos": 20443,
              "breakdown": {
                "next_reader": 745,
                "next_reader_count": 1,
                "process": 19698,
                "process_count": 5
              },
              "debug": {
                "fast_path": 5
              }
            },
            {
              "type": "StoredFieldsPhase",
              "description": "",
              "time_in_nanos": 5310,
              "breakdown": {
                "next_reader": 745,
                "next_reader_count": 1,
                "process": 4445,
                "process_count": 5
              }
            }
          ]
        }
      }
    ]
  }
}

搜索结果已返回,但为了简洁起见,这里省略了。

即使是一个简单的查询,响应也相对复杂。让我们在进入更复杂的示例之前,逐部分进行解析。

配置文件响应的整体结构如下:

{
   "profile": {
        "shards": [
           {
              "id": "[q2aE02wS1R8qQFnYu6vDVQ][my-index-000001][0]",  
              "node_id": "q2aE02wS1R8qQFnYu6vDVQ",
              "shard_id": 0,
              "index": "my-index-000001",
              "cluster": "(local)",             
              "searches": [
                 {
                    "query": [...],             
                    "rewrite_time": 51443,      
                    "collector": [...]          
                 }
              ],
              "aggregations": [...],            
              "fetch": {...}                    
           }
        ]
     }
}

每个参与响应的分片都会返回一个配置文件,并通过唯一ID进行标识。

如果查询是在本地集群上运行的,则复合ID中省略了集群名称,并在此处标记为“(local)”。对于在使用跨集群搜索的远程集群上运行的配置文件,“id”值可能类似于[q2aE02wS1R8qQFnYu6vDVQ][remote1:my-index-000001][0],而“cluster”值将是remote1

查询时间和其他调试信息。

累计重写时间。

每个收集器的名称和调用时间。

聚合时间、调用次数和调试信息。

获取时间信息和调试信息。

因为搜索请求可能在一个或多个索引的分片上执行,并且搜索可能覆盖一个或多个索引,所以配置文件响应中的顶级元素是一个shard对象数组。每个分片对象列出了其id,该ID唯一标识分片。ID的格式是[nodeID][clusterName:indexName][shardID]。如果搜索是在本地集群上运行的,则不会添加集群名称,格式为[nodeID][indexName][shardID]

配置文件本身可能包含一个或多个“搜索”,其中搜索是对底层Lucene索引执行的查询。大多数用户提交的搜索请求只会对Lucene索引执行一个搜索。但偶尔会执行多个搜索,例如包含全局聚合(这需要为全局上下文执行一个次要的“match_all”查询)。

在每个search对象中,将会有两个包含分析信息的数组:一个query数组和一个collector数组。与search对象一起的还有一个aggregations对象,其中包含聚合的分析信息。在未来,可能会添加更多部分,例如suggesthighlight等。

还将有一个 rewrite 指标,显示重写查询所花费的总时间(以纳秒为单位)。

与其他统计API一样,Profile API支持人类可读的输出。这可以通过在查询字符串中添加?human=true来启用。在这种情况下,输出包含额外的time字段,其中包含四舍五入的、人类可读的时间信息(例如"time": "391,9ms""time": "123.3micros")。

查询分析

edit

Profile API 提供的详细信息直接暴露了 Lucene 类名和概念,这意味着要完全解释结果需要相当深入的 Lucene 知识。本页面试图提供一个关于 Lucene 如何执行查询的速成课程,以便您可以使用 Profile API 成功诊断和调试查询,但这只是一个概述。要完全理解,请参阅 Lucene 的文档,并在某些情况下参考代码。

尽管如此,通常不需要完全理解查询的内部机制就能修复一个慢查询。通常只需要看到查询的某个特定部分很慢,而不一定需要理解为什么查询的advance阶段是导致慢的原因,例如。

查询 部分

edit

The query section contains detailed timing of the query tree executed by Lucene on a particular shard. The overall structure of this query tree will resemble your original Elasticsearch query, but may be slightly (or sometimes very) different. It will also use similar but not always identical naming. Using our previous match query example, let’s analyze the query section:

"query": [
    {
       "type": "BooleanQuery",
       "description": "message:get message:search",
       "time_in_nanos": "11972972",
       "breakdown": {...},               
       "children": [
          {
             "type": "TermQuery",
             "description": "message:get",
             "time_in_nanos": "3801935",
             "breakdown": {...}
          },
          {
             "type": "TermQuery",
             "description": "message:search",
             "time_in_nanos": "205654",
             "breakdown": {...}
          }
       ]
    }
]

为了简化,分解时间被省略了。

根据配置文件结构,我们可以看到我们的 match 查询被 Lucene 重写为一个包含两个子句(都包含一个 TermQuery)的 BooleanQuery。type 字段显示了 Lucene 类名,并且通常与 Elasticsearch 中的等效名称一致。description 字段显示了 Lucene 对查询的解释文本,并且是为了帮助区分查询的不同部分(例如,message:getmessage:search 都是 TermQuery,否则它们看起来会相同)。

字段 time_in_nanos 显示,整个 BooleanQuery 执行大约花费了 ~11.9ms。记录的时间包括所有子查询的时间。

字段 breakdown 将提供关于时间如何花费的详细统计信息,我们稍后会详细讨论。最后,数组 children 列出了可能存在的任何子查询。因为我们搜索了两个值(“get search”),我们的 BooleanQuery 包含了两个子 TermQueries。它们具有相同的信息(类型、时间、分解等)。子查询允许拥有它们自己的子查询。

时间分解

edit

组件 breakdown 列出了关于低级 Lucene 执行的详细时间统计信息:

"breakdown": {
  "set_min_competitive_score_count": 0,
  "match_count": 5,
  "shallow_advance_count": 0,
  "set_min_competitive_score": 0,
  "next_doc": 39022,
  "match": 4456,
  "next_doc_count": 5,
  "score_count": 5,
  "compute_max_score_count": 0,
  "compute_max_score": 0,
  "advance": 84525,
  "advance_count": 1,
  "score": 37779,
  "build_scorer_count": 2,
  "create_weight": 4694895,
  "shallow_advance": 0,
  "create_weight_count": 1,
  "build_scorer": 7112295,
  "count_weight": 0,
  "count_weight_count": 0
}

时间以挂钟纳秒列出,完全没有归一化。关于整体time_in_nanos的所有注意事项在这里都适用。分解的目的是让你了解A) Lucene中的哪些机制实际上在消耗时间,以及B)各个组件之间时间差异的大小。与总时间一样,分解时间包括所有子时间。

统计数据的含义如下:

所有参数:
edit

create_weight

在Lucene中,查询必须能够在多个IndexSearchers(可以将其视为针对特定Lucene索引执行搜索的引擎)之间重用。这使得Lucene处于一个棘手的位置,因为许多查询需要累积与正在使用的索引相关的临时状态/统计信息,但查询契约要求它必须是不可变的。

为了解决这个问题,Lucene要求每个查询生成一个Weight对象,该对象充当临时上下文对象,用于保存与此特定(IndexSearcher,Query)元组相关的状态。weight指标显示了此过程所需的时间。

build_scorer

此参数显示为查询构建评分器所需的时间。评分器是遍历匹配文档并生成每个文档分数的机制(例如,“foo”与文档的匹配程度如何?)。请注意,这记录了生成评分器对象所需的时间,而不是实际对文档进行评分的时间。某些查询的评分器初始化速度可能更快或更慢,具体取决于优化、复杂性等因素。

如果启用了缓存和/或查询适用,这也可能显示与缓存相关的计时信息。

next_doc

Lucene 方法 next_doc 返回与查询匹配的下一个文档的文档 ID。此统计信息显示 确定哪个文档是下一个匹配项所需的时间,此过程根据查询的性质而有很大差异。Next_doc 是 advance() 的一种专门形式, 对于 Lucene 中的许多查询来说更加方便。它等同于 advance(docId() + 1)

advance

advance 是 next_doc 的“低级”版本:它的目的是找到下一个匹配的文档,但要求调用查询执行额外的任务,例如识别并跳过跳过项等。 然而,并非所有查询都可以使用 next_doc,因此 advance 也为这些查询计时。

合取(例如布尔查询中的 must 子句)是 advance 的典型消费者

匹配

一些查询,例如短语查询,使用“两阶段”过程来匹配文档。首先,文档被“近似”匹配,如果它近似匹配,则使用更严格(且更昂贵)的过程进行第二次检查。第二阶段验证是match统计量所衡量的。

例如,短语查询首先通过确保短语中的所有术语都存在于文档中来近似检查文档。如果所有术语都存在,它然后执行第二阶段验证,以确保术语按顺序排列以形成短语,这比仅检查术语的存在相对更昂贵。

因为这种两阶段过程仅由少数查询使用,所以match统计量通常为零

分数

这记录了通过其评分器对特定文档进行评分所花费的时间

*_count

记录特定方法的调用次数。例如,"next_doc_count": 2, 表示nextDoc()方法在两个不同的文档上调用了。这可以用来帮助判断查询的选择性,通过比较不同查询组件之间的计数。

收集器 部分

edit

响应的Collectors部分显示了高级执行细节。 Lucene通过定义一个“Collector”来工作,该Collector负责协调匹配文档的遍历、评分和收集。Collectors也是单个查询可以记录聚合结果、执行无作用域的“全局”查询、执行查询后过滤等的方式。

查看前面的示例:

"collector": [
  {
    "name": "QueryPhaseCollector",
    "reason": "search_query_phase",
    "time_in_nanos": 775274,
    "children" : [
      {
        "name": "SimpleTopScoreDocCollector",
        "reason": "search_top_hits",
        "time_in_nanos": 775274
      }
    ]
  }
]

我们看到了一个名为 QueryPhaseCollector 的顶级收集器,它包含一个子收集器 SimpleTopScoreDocCollectorSimpleTopScoreDocCollector 是 Elasticsearch 使用的默认 “评分和排序” Collectorreason 字段尝试 提供类名的简单英文描述。time_in_nanos 类似于查询树中的时间:一个包括所有子项的挂钟时间。同样,children 列出了所有子收集器。当请求聚合时, QueryPhaseCollector 将包含一个额外的子收集器,其原因字段为 aggregation,该收集器执行聚合操作。

需要注意的是,Collector 时间与 Query 时间是独立的。它们是独立计算、组合和归一化的!由于 Lucene 执行的性质,无法将 Collectors 的时间“合并”到 Query 部分,因此它们显示在单独的部分中。

作为参考,各种收集器的原因如下:

search_top_hits

一个用于评分和排序文档的收集器。这是最常见的收集器,将在大多数简单搜索中使用。

search_count

一个仅统计与查询匹配的文档数量的收集器,但不获取文档的源。 当指定 size: 0 时可以看到这种情况

搜索查询阶段

一个收集器,它在查询阶段同时包含收集顶部命中和聚合的功能。 它支持在找到n个匹配文档后终止搜索执行(当指定terminate_after时),以及仅返回得分大于n的匹配文档(当提供min_score时)。此外,它能够根据提供的post_filter过滤匹配的顶部命中。

search_timeout

一个在指定时间段后停止执行的收集器。当指定了timeout顶级参数时,会出现这种情况。

聚合

Elasticsearch用于对查询范围运行聚合的收集器。一个单一的aggregation收集器用于收集所有聚合的文档,因此您将在名称中看到聚合列表。

全局聚合

一个对全局查询范围执行聚合的收集器,而不是对指定查询执行聚合。 因为全局范围必然与执行的查询不同,所以它必须执行自己的 match_all 查询(您将在查询部分看到添加的内容)以收集整个数据集

重写 部分

edit

Lucene中的所有查询都会经历一个“重写”过程。一个查询(及其子查询)可能会被重写一次或多次,并且这个过程会一直持续,直到查询停止变化。这个过程允许Lucene执行优化,例如删除冗余子句,用更高效的执行路径替换一个查询等。例如,一个Boolean → Boolean → TermQuery可以被重写为一个TermQuery,因为在这种情况下所有的Boolean都是不必要的。

重写过程复杂且难以展示,因为查询可能会发生剧烈变化。与其展示中间结果,不如简单地显示总重写时间(以纳秒为单位)。该值是累积的,包含所有正在重写的查询的总时间。

一个更复杂的例子

edit

为了演示一个稍微更复杂的查询及其相关结果,我们可以分析以下查询:

GET /my-index-000001/_search
{
  "profile": true,
  "query": {
    "term": {
      "user.id": {
        "value": "elkbee"
      }
    }
  },
  "aggs": {
    "my_scoped_agg": {
      "terms": {
        "field": "http.response.status_code"
      }
    },
    "my_global_agg": {
      "global": {},
      "aggs": {
        "my_level_agg": {
          "terms": {
            "field": "http.response.status_code"
          }
        }
      }
    }
  },
  "post_filter": {
    "match": {
      "message": "search"
    }
  }
}

这个示例包含:

  • 一个查询
  • 一个范围聚合
  • 一个全局聚合
  • 一个后置过滤器

API返回以下结果:

{
  ...
  "profile": {
    "shards": [
      {
        "id": "[P6xvulHtQRWuD4YnubWb7A][my-index-000001][0]",
        "node_id": "P6xvulHtQRWuD4YnubWb7A",
        "shard_id": 0,
        "index": "my-index-000001",
        "cluster": "(local)",
        "searches": [
          {
            "query": [
              {
                "type": "TermQuery",
                "description": "message:search",
                "time_in_nanos": 141618,
                "breakdown": {
                  "set_min_competitive_score_count": 0,
                  "match_count": 0,
                  "shallow_advance_count": 0,
                  "set_min_competitive_score": 0,
                  "next_doc": 0,
                  "match": 0,
                  "next_doc_count": 0,
                  "score_count": 0,
                  "compute_max_score_count": 0,
                  "compute_max_score": 0,
                  "advance": 3942,
                  "advance_count": 4,
                  "count_weight_count": 0,
                  "score": 0,
                  "build_scorer_count": 2,
                  "create_weight": 38380,
                  "shallow_advance": 0,
                  "count_weight": 0,
                  "create_weight_count": 1,
                  "build_scorer": 99296
                }
              },
              {
                "type": "TermQuery",
                "description": "user.id:elkbee",
                "time_in_nanos": 163081,
                "breakdown": {
                  "set_min_competitive_score_count": 0,
                  "match_count": 0,
                  "shallow_advance_count": 0,
                  "set_min_competitive_score": 0,
                  "next_doc": 2447,
                  "match": 0,
                  "next_doc_count": 4,
                  "score_count": 4,
                  "compute_max_score_count": 0,
                  "compute_max_score": 0,
                  "advance": 3552,
                  "advance_count": 1,
                  "score": 5027,
                  "count_weight_count": 0,
                  "build_scorer_count": 2,
                  "create_weight": 107840,
                  "shallow_advance": 0,
                  "count_weight": 0,
                  "create_weight_count": 1,
                  "build_scorer": 44215
                }
              }
            ],
            "rewrite_time": 4769,
            "collector": [
              {
                "name": "QueryPhaseCollector",
                "reason": "search_query_phase",
                "time_in_nanos": 1945072,
                "children": [
                  {
                    "name": "SimpleTopScoreDocCollector",
                    "reason": "search_top_hits",
                    "time_in_nanos": 22577
                  },
                  {
                    "name": "AggregatorCollector: [my_scoped_agg, my_global_agg]",
                    "reason": "aggregation",
                    "time_in_nanos": 867617
                  }
                ]
              }
            ]
          }
        ],
        "aggregations": [...], 
        "fetch": {...}
      }
    ]
  }
}

已省略"aggregations"部分,因为它将在下一节中进行介绍。

如您所见,输出比之前要详细得多。查询的所有主要部分都得到了体现:

  1. 第一个 TermQuery (user.id:elkbee) 表示主要的 term 查询。
  2. 第二个 TermQuery (message:search) 表示 post_filter 查询。

Collector树相当简单,展示了如何使用一个包含正常评分SimpleTopScoreDocCollector的QueryPhaseCollector来收集顶部命中,以及使用BucketCollectorWrapper来运行所有范围聚合。

理解MultiTermQuery输出

edit

需要特别注意的是MultiTermQuery查询类。 这包括通配符、正则表达式和模糊查询。这些查询会发出非常 详细的响应,并且结构化程度不高。

本质上,这些查询会根据每个段落进行自我重写。如果你想象通配符查询 b*,它在技术上可以匹配任何以字母 "b" 开头的词条。枚举所有可能的组合是不可能的,因此 Lucene 会在评估段落的上下文中重写查询,例如,一个段落可能包含词条 [bar, baz],因此查询会重写为 "bar" 和 "baz" 的布尔查询组合。另一个段落可能只有词条 [bakery],因此查询会重写为 "bakery" 的单个词条查询。

由于这种动态的分段重写,清晰的树结构变得扭曲,不再遵循清晰的“血统”来展示一个查询如何重写为下一个查询。目前,我们所能做的就是道歉,并建议您如果觉得太混乱,可以折叠该查询的子节点的详细信息。幸运的是,所有的计时统计数据都是正确的,只是响应中的物理布局不正确,因此如果您发现详细信息太难解释,只需分析顶层的MultiTermQuery并忽略其子节点即可。

希望这个问题在未来的迭代中能得到解决,但它是一个棘手的问题,目前仍在解决中。:)

分析聚合

edit
聚合 部分
edit

The aggregations section contains detailed timing of the aggregation tree executed by a particular shard. The overall structure of this aggregation tree will resemble your original Elasticsearch request. Let’s execute the previous query again and look at the aggregation profile this time:

GET /my-index-000001/_search
{
  "profile": true,
  "query": {
    "term": {
      "user.id": {
        "value": "elkbee"
      }
    }
  },
  "aggs": {
    "my_scoped_agg": {
      "terms": {
        "field": "http.response.status_code"
      }
    },
    "my_global_agg": {
      "global": {},
      "aggs": {
        "my_level_agg": {
          "terms": {
            "field": "http.response.status_code"
          }
        }
      }
    }
  },
  "post_filter": {
    "match": {
      "message": "search"
    }
  }
}

这将生成以下聚合配置文件输出:

{
  "profile": {
    "shards": [
      {
        "aggregations": [
          {
            "type": "NumericTermsAggregator",
            "description": "my_scoped_agg",
            "time_in_nanos": 79294,
            "breakdown": {
              "reduce": 0,
              "build_aggregation": 30885,
              "build_aggregation_count": 1,
              "initialize": 2623,
              "initialize_count": 1,
              "reduce_count": 0,
              "collect": 45786,
              "collect_count": 4,
              "build_leaf_collector": 18211,
              "build_leaf_collector_count": 1,
              "post_collection": 929,
              "post_collection_count": 1
            },
            "debug": {
              "total_buckets": 1,
              "result_strategy": "long_terms",
              "built_buckets": 1
            }
          },
          {
            "type": "GlobalAggregator",
            "description": "my_global_agg",
            "time_in_nanos": 104325,
            "breakdown": {
              "reduce": 0,
              "build_aggregation": 22470,
              "build_aggregation_count": 1,
              "initialize": 12454,
              "initialize_count": 1,
              "reduce_count": 0,
              "collect": 69401,
              "collect_count": 4,
              "build_leaf_collector": 8150,
              "build_leaf_collector_count": 1,
              "post_collection": 1584,
              "post_collection_count": 1
            },
            "debug": {
              "built_buckets": 1
            },
            "children": [
              {
                "type": "NumericTermsAggregator",
                "description": "my_level_agg",
                "time_in_nanos": 76876,
                "breakdown": {
                  "reduce": 0,
                  "build_aggregation": 13824,
                  "build_aggregation_count": 1,
                  "initialize": 1441,
                  "initialize_count": 1,
                  "reduce_count": 0,
                  "collect": 61611,
                  "collect_count": 4,
                  "build_leaf_collector": 5564,
                  "build_leaf_collector_count": 1,
                  "post_collection": 471,
                  "post_collection_count": 1
                },
                "debug": {
                  "total_buckets": 1,
                  "result_strategy": "long_terms",
                  "built_buckets": 1
                }
              }
            ]
          }
        ]
      }
    ]
  }
}

从配置文件结构中我们可以看到,my_scoped_agg 在内部被运行作为一个 NumericTermsAggregator(因为它所聚合的字段,http.response.status_code,是一个数值字段)。在同一层级,我们看到了一个 GlobalAggregator,它来自 my_global_agg。然后该聚合有一个子 NumericTermsAggregator,它来自对 http.response.status_code 的第二个聚合项。

字段 time_in_nanos 显示了每个聚合执行的时间,并且包括所有子聚合的时间。虽然总时间是有用的,但字段 breakdown 将提供关于时间如何花费的详细统计信息。

某些聚合可能会返回专家调试信息,这些信息描述了聚合底层执行的特性,这些特性对于那些在聚合上进行开发的人来说是有用的,但我们不期望这些信息对其他人有用。它们在不同版本、聚合和聚合执行策略之间可能会有很大的差异。

时间分解

edit

组件列出了关于低级执行的详细统计信息:

"breakdown": {
  "reduce": 0,
  "build_aggregation": 30885,
  "build_aggregation_count": 1,
  "initialize": 2623,
  "initialize_count": 1,
  "reduce_count": 0,
  "collect": 45786,
  "collect_count": 4,
  "build_leaf_collector": 18211,
  "build_leaf_collector_count": 1
}

breakdown组件中的每个属性都对应于聚合的内部方法。例如,build_leaf_collector属性测量运行聚合的getLeafCollector()方法所花费的纳秒数。以_count结尾的属性记录特定方法的调用次数。例如,"collect_count": 2表示聚合在两个不同的文档上调用了collect()方法。reduce属性保留供将来使用,并且始终返回0

时间以挂钟纳秒列出,完全没有归一化。关于整体时间的所有注意事项在这里都适用。分解的目的是让你了解A) Elasticsearch中实际消耗时间的机制,以及B) 各个组件之间时间差异的大小。与整体时间一样,分解时间包括所有子时间。

性能分析获取

edit

所有获取了文档的分片在分析中都会有一个fetch部分。 让我们执行一个小搜索并查看获取分析:

GET /my-index-000001/_search?filter_path=profile.shards.fetch
{
  "profile": true,
  "query": {
    "term": {
      "user.id": {
        "value": "elkbee"
      }
    }
  }
}

这里是获取配置文件:

{
  "profile": {
    "shards": [
      {
        "fetch": {
          "type": "fetch",
          "description": "",
          "time_in_nanos": 660555,
          "breakdown": {
            "next_reader": 7292,
            "next_reader_count": 1,
            "load_stored_fields": 299325,
            "load_stored_fields_count": 5,
            "load_source": 3863,
            "load_source_count": 5
          },
          "debug": {
            "stored_fields": ["_id", "_routing", "_source"]
          },
          "children": [
            {
              "type" : "FetchFieldsPhase",
              "description" : "",
              "time_in_nanos" : 238762,
              "breakdown" : {
                "process_count" : 5,
                "process" : 227914,
                "next_reader" : 10848,
                "next_reader_count" : 1
              }
            },
            {
              "type": "FetchSourcePhase",
              "description": "",
              "time_in_nanos": 20443,
              "breakdown": {
                "next_reader": 745,
                "next_reader_count": 1,
                "process": 19698,
                "process_count": 5
              },
              "debug": {
                "fast_path": 4
              }
            },
            {
              "type": "StoredFieldsPhase",
              "description": "",
              "time_in_nanos": 5310,
              "breakdown": {
                "next_reader": 745,
                "next_reader_count": 1,
                "process": 4445,
                "process_count": 5
              }
            }
          ]
        }
      }
    ]
  }
}

由于这是关于Elasticsearch执行获取方式的调试信息,它可能会在不同的请求和版本之间发生变化。即使是补丁版本也可能改变这里的输出。这种不一致性正是它对调试有用的原因。

无论如何!time_in_nanos 测量获取阶段的全部时间。 breakdown 统计并计时我们在 next_reader 中的每个准备工作和在 load_stored_fields 中加载存储字段所花费的时间。 Debug 包含杂项非计时信息,特别是 stored_fields 列出了获取必须加载的存储字段。如果它是一个空列表,那么获取将完全跳过加载存储字段。

The children section lists the sub-phases that do the actual fetching work and the breakdown has counts and timings for the per-segment preparation in next_reader and the per document fetching in process.

我们努力预先加载所有在获取过程中需要的存储字段。这通常会使_source阶段每命中一次花费几微秒。在这种情况下,_source阶段的真正成本隐藏在分解的load_stored_fields组件中。通过设置"_source": false, "stored_fields": ["_none_"],可以完全跳过加载存储字段。

分析DFS

edit

DFS阶段在查询阶段之前运行,以收集与查询相关的全局信息。它目前用于两种情况:

  1. search_type 设置为 dfs_query_then_fetch 并且索引有多个分片时。
  2. 当搜索请求包含一个 knn 部分时。

这两种情况都可以通过在搜索请求中将profile设置为true来进行分析。

分析DFS统计信息
edit

search_type 设置为 dfs_query_then_fetch 并且索引有多个分片时,dfs 阶段会收集术语统计信息以提高搜索结果的相关性。

以下是将 profile 设置为 true 的搜索示例,该搜索使用 dfs_query_then_fetch

让我们首先设置一个具有多个分片和索引的索引,并使用不同值在keyword字段上索引一对文档。

PUT my-dfs-index
{
  "settings": {
    "number_of_shards": 2, 
    "number_of_replicas": 1
  },
  "mappings": {
      "properties": {
        "my-keyword": { "type": "keyword" }
      }
    }
}

POST my-dfs-index/_bulk?refresh=true
{ "index" : { "_id" : "1" } }
{ "my-keyword" : "a" }
{ "index" : { "_id" : "2" } }
{ "my-keyword" : "b" }

使用多个分片创建了my-dfs-index

设置索引后,我们现在可以分析搜索查询的dfs阶段。在这个示例中,我们使用了一个术语查询。

GET /my-dfs-index/_search?search_type=dfs_query_then_fetch&pretty&size=0 
{
  "profile": true, 
  "query": {
    "term": {
      "my-keyword": {
        "value": "a"
      }
    }
  }
}

search_type URL 参数设置为 dfs_query_then_fetch,以确保运行 DFS 阶段。

参数 profile 设置为 true

在响应中,我们看到了一个包含每个分片的dfs部分的配置文件,以及搜索阶段其余部分的配置文件输出。其中一个分片的dfs部分如下所示:

"dfs" : {
    "statistics" : {
        "type" : "statistics",
        "description" : "collect term statistics",
        "time_in_nanos" : 236955,
        "breakdown" : {
            "term_statistics" : 4815,
            "collection_statistics" : 27081,
            "collection_statistics_count" : 1,
            "create_weight" : 153278,
            "term_statistics_count" : 1,
            "rewrite_count" : 0,
            "create_weight_count" : 1,
            "rewrite" : 0
        }
    }
}

在响应的 dfs.statistics 部分,我们看到了一个 time_in_nanos, 这是为这个分片收集术语统计所需的总时间,以及各个部分的进一步细分。

分析kNN搜索
edit

k-近邻 (kNN)搜索运行期间,dfs阶段进行。

以下是将 profile 设置为 true 的搜索示例,该搜索包含一个 knn 部分:

让我们首先设置一个包含多个密集向量的索引。

PUT my-knn-index
{
  "mappings": {
    "properties": {
      "my-vector": {
        "type": "dense_vector",
        "dims": 3,
        "index": true,
        "similarity": "l2_norm"
      }
    }
  }
}

POST my-knn-index/_bulk?refresh=true
{ "index": { "_id": "1" } }
{ "my-vector": [1, 5, -20] }
{ "index": { "_id": "2" } }
{ "my-vector": [42, 8, -15] }
{ "index": { "_id": "3" } }
{ "my-vector": [15, 11, 23] }

设置索引后,我们现在可以分析一个kNN搜索查询。

POST my-knn-index/_search
{
  "profile": true, 
  "knn": {
    "field": "my-vector",
    "query_vector": [-5, 9, -12],
    "k": 3,
    "num_candidates": 100
  }
}

参数 profile 设置为 true

在响应中,我们看到一个包含 knn 部分的配置文件,该部分作为每个分片的 dfs 部分的一部分,以及搜索阶段其余部分的配置文件输出。

一个分片的 dfs.knn 部分如下所示:

"dfs" : {
    "knn" : [
        {
        "vector_operations_count" : 4,
        "query" : [
            {
                "type" : "DocAndScoreQuery",
                "description" : "DocAndScore[100]",
                "time_in_nanos" : 444414,
                "breakdown" : {
                  "set_min_competitive_score_count" : 0,
                  "match_count" : 0,
                  "shallow_advance_count" : 0,
                  "set_min_competitive_score" : 0,
                  "next_doc" : 1688,
                  "match" : 0,
                  "next_doc_count" : 3,
                  "score_count" : 3,
                  "compute_max_score_count" : 0,
                  "compute_max_score" : 0,
                  "advance" : 4153,
                  "advance_count" : 1,
                  "score" : 2099,
                  "build_scorer_count" : 2,
                  "create_weight" : 128879,
                  "shallow_advance" : 0,
                  "create_weight_count" : 1,
                  "build_scorer" : 307595,
                  "count_weight": 0,
                  "count_weight_count": 0
                }
            }
        ],
        "rewrite_time" : 1275732,
        "collector" : [
            {
                "name" : "SimpleTopScoreDocCollector",
                "reason" : "search_top_hits",
                "time_in_nanos" : 17163
            }
        ]
    }   ]
}

在响应的 dfs.knn 部分中,我们可以看到 查询重写收集器 的时间输出。与其他许多查询不同,kNN 搜索在查询重写期间完成了大部分工作。这意味着 rewrite_time 表示 kNN 搜索所花费的时间。属性 vector_operations_count 表示在 kNN 搜索期间执行的向量操作的总数。

分析注意事项

edit

与任何分析器一样,Profile API 在搜索执行过程中引入了不可忽视的开销。对低级方法调用(如 collectadvancenext_doc)进行检测的行为可能会相当昂贵,因为这些方法是在紧密循环中调用的。因此,不应默认在生产环境中启用分析,也不应将其与未分析的查询时间进行比较。分析只是一个诊断工具。

也有一些情况下,特殊的Lucene优化被禁用,因为它们不适合进行性能分析。这可能导致某些查询报告的相对时间比未进行性能分析的查询更长,但通常与性能分析查询中的其他组件相比,不应产生显著影响。

限制

edit
  • 分析当前不测量网络开销。
  • 分析也不考虑在队列中花费的时间,协调节点上合并分片响应的时间,或构建全局序号(一种用于加速搜索的内部数据结构)等额外工作的时间。
  • 当前无法获取建议的分析统计信息。
  • 当前无法获取聚合的reduce阶段的分析信息。
  • 分析器正在检测可能会随版本变化而改变的内部结构。生成的JSON应被视为大部分不稳定,特别是debug部分的内容。

字段能力 API

edit

允许您检索多个索引中字段的功能。 对于数据流,API返回流的后备索引中的字段功能。

GET /_field_caps?fields=rating

请求

edit

GET /_field_caps?fields=

POST /_field_caps?fields=

GET //_field_caps?fields=

POST //_field_caps?fields=

先决条件

edit
  • 如果启用了Elasticsearch安全功能,您必须拥有目标数据流、索引或别名的view_index_metadatareadmanage 索引权限

描述

edit

字段功能 API 返回多个索引之间字段功能的信息。

字段功能 API 返回 运行时字段 就像返回任何其他字段一样。例如,一个类型为 keyword 的运行时字段会像属于 keyword 家族的任何其他字段一样返回。

路径参数

edit
<target>
(可选,字符串) 用于限制请求的逗号分隔的数据流、索引和别名列表。支持通配符 (*)。要针对所有数据流和索引,请省略此参数或使用 *_all

查询参数

edit
fields
(必需,字符串) 用于检索功能的字段列表,以逗号分隔。支持通配符 (*) 表达式。
allow_no_indices

(可选, 布尔值) 如果为false,当任何通配符表达式、 索引别名_all值仅针对缺失或关闭的索引时,请求将返回错误。 即使请求针对其他打开的索引,此行为也适用。例如,如果一个请求针对foo*,bar*,但没有任何索引以bar开头,即使存在以foo开头的索引,请求也会返回错误。

默认为 true

expand_wildcards

(可选,字符串) 通配符模式可以匹配的索引类型。如果请求可以针对数据流,此参数确定通配符表达式是否匹配隐藏的数据流。支持逗号分隔的值,例如 open,hidden。有效值为:

all
匹配任何数据流或索引,包括 隐藏的 数据流和索引。
open
匹配开放的、非隐藏的索引。同时也匹配任何非隐藏的数据流。
closed
匹配关闭的、非隐藏的索引。同时也匹配任何非隐藏的数据流。数据流不能被关闭。
hidden
匹配隐藏的数据流和隐藏的索引。必须与 openclosed 或两者结合使用。
none
不接受通配符模式。

默认为 open

ignore_unavailable
(可选,布尔值) 如果为false,则当请求目标是一个缺失或关闭的索引时,请求将返回错误。默认为false
include_unmapped
(可选,布尔值) 如果为true,则在响应中包含在一个索引中映射但在另一个索引中未映射的未映射字段。没有任何映射的字段永远不会被包含。 默认为false
include_empty_fields
(可选,布尔值) 如果为false,则从未在任何分片中具有值的字段不会包含在响应中。非空字段始终包含在内。此标志不考虑删除和更新。如果某个字段曾经非空且包含该字段的所有文档都被删除或该字段被更新移除,即使标志为false,它仍将返回。 默认为true
filters

(可选, 字符串) 以逗号分隔的过滤器列表,应用于响应。

有效值为 filters
+metadata
仅包含元数据字段
-metadata
排除元数据字段
-parent
排除父字段
-nested
排除嵌套字段
-multifield
排除多字段
types
(可选,字符串) 要包含的字段类型的逗号分隔列表。任何不匹配这些类型的字段将从结果中排除。默认为空,表示返回所有字段类型。有关字段能力请求和响应中的字段类型的更多信息,请参见这里

请求体

edit
index_filter
(可选, 查询对象 允许在提供的查询在每个分片上重写为 match_none 时过滤索引。
runtime_mappings
(可选, 对象) 定义请求中的临时运行时字段,类似于在搜索请求中的定义方式。这些字段仅作为查询的一部分存在,并且优先于索引映射中定义的同名字段。

响应体

edit

响应中使用的类型描述了字段类型的家族。 通常,类型家族与映射中声明的字段类型相同, 但为了简化问题,某些行为相同的字段类型使用类型家族来描述。例如,keywordconstant_keywordwildcard 字段类型都被描述为 keyword 类型家族。

metadata_field
该字段是否注册为元数据字段
searchable
此字段是否在所有索引中被索引以进行搜索。
aggregatable
此字段是否可以在所有索引上进行聚合。
time_series_dimension
此字段是否在所有索引上用作时间序列维度。 对于非时间序列索引,此字段不存在。
time_series_metric
包含指标类型,如果该字段在所有索引中用作时间序列指标,如果不作为指标使用则不存在。对于非时间序列索引,此字段不包含在内。
indices
此字段具有相同类型系列的索引列表,如果所有索引对此字段都具有相同的类型系列,则为空。
non_searchable_indices
此字段不可搜索的索引列表,如果所有索引对该字段的定义相同,则为空。
non_aggregatable_indices
此字段不可聚合的索引列表,如果所有索引对该字段的定义相同,则为空。
non_dimension_indices
[预览] 此功能处于技术预览阶段,可能会在未来的版本中进行更改或移除。Elastic 将努力修复任何问题,但技术预览中的功能不受官方 GA 功能支持 SLA 的约束。 如果此列表出现在响应中,则某些索引将该字段标记为维度,而其他索引(即此列表中的索引)则没有。
metric_conflicts_indices
[预览] 此功能处于技术预览阶段,可能会在未来的版本中进行更改或移除。Elastic 将努力修复任何问题,但技术预览中的功能不受官方 GA 功能支持 SLA 的约束。 如果这些索引在此字段上没有相同的 time_series_metric 值,则此字段所在的索引列表。
meta
将所有索引的元数据合并为一个字符串键到值数组的映射。 值长度为1表示所有索引对于此键具有相同的值, 而长度为2或更多表示并非所有索引对于此键具有相同的值。

示例

edit

请求可以限制为特定的数据流和索引:

GET my-index-000001/_field_caps?fields=rating

下一个示例 API 调用请求关于 ratingtitle 字段的信息:

GET _field_caps?fields=rating,title

API返回以下响应:

{
  "indices": [ "index1", "index2", "index3", "index4", "index5" ],
  "fields": {
    "rating": {                                   
      "long": {
        "metadata_field": false,
        "searchable": true,
        "aggregatable": false,
        "indices": [ "index1", "index2" ],
        "non_aggregatable_indices": [ "index1" ]  
      },
      "keyword": {
        "metadata_field": false,
        "searchable": false,
        "aggregatable": true,
        "indices": [ "index3", "index4" ],
        "non_searchable_indices": [ "index4" ]    
      }
    },
    "title": {                                    
      "text": {
        "metadata_field": false,
        "searchable": true,
        "aggregatable": false
      }
    }
  }
}

字段 ratingindex1index2 中定义为 long,在 index3index4 中定义为 keyword

字段 ratingindex1 中不可聚合。

字段 ratingindex4 中不可搜索。

字段 title 在所有索引中被定义为 text

默认情况下,未映射的字段会被忽略。您可以通过在请求中添加一个名为 include_unmapped 的参数来将其包含在响应中:

GET _field_caps?fields=rating,title&include_unmapped

在哪种情况下,响应将包含每个字段的条目,这些字段在某些索引中存在但在所有索引中不存在:

{
  "indices": [ "index1", "index2", "index3" ],
  "fields": {
    "rating": {
      "long": {
        "metadata_field": false,
        "searchable": true,
        "aggregatable": false,
        "indices": [ "index1", "index2" ],
        "non_aggregatable_indices": [ "index1" ]
      },
      "keyword": {
        "metadata_field": false,
        "searchable": false,
        "aggregatable": true,
        "indices": [ "index3", "index4" ],
        "non_searchable_indices": [ "index4" ]
      },
      "unmapped": {                               
        "metadata_field": false,
        "indices": [ "index5" ],
        "searchable": false,
        "aggregatable": false
      }
    },
    "title": {
      "text": {
        "metadata_field": false,
        "indices": [ "index1", "index2", "index3", "index4" ],
        "searchable": true,
        "aggregatable": false
      },
      "unmapped": {                               
        "metadata_field": false,
        "indices": [ "index5" ],
        "searchable": false,
        "aggregatable": false
      }
    }
  }
}

index5 中,rating 字段是未映射的。

index5 中,title 字段是未映射的。

也可以使用查询来过滤索引:

POST my-index-*/_field_caps?fields=rating
{
  "index_filter": {
    "range": {
      "@timestamp": {
        "gte": "2018"
      }
    }
  }
}

在哪些情况下,会将提供的过滤器重写为每个分片上的 match_none 的索引从响应中过滤掉。

过滤是基于尽力而为的原则进行的,它使用索引统计信息和映射来重写查询为match_none,而不是完全执行请求。例如,一个range查询在一个date字段上可以重写为match_none,如果分片内的所有文档(包括已删除的文档)都在提供的范围之外。然而,并非所有查询都可以重写为match_none,因此即使提供的过滤器没有匹配到任何文档,此API仍可能返回一个索引。

排名评估 API

edit

允许您评估在一组典型搜索查询中排序搜索结果的质量。

请求

edit

GET //_rank_eval

POST //_rank_eval

先决条件

edit
  • 如果启用了Elasticsearch安全功能,您必须对目标数据流、索引或别名具有权限。 索引权限

描述

edit

排名评估 API 允许您评估在一组典型搜索查询上的搜索结果质量。给定这组查询和一个手动评分的文档列表,_rank_eval 端点会计算并返回典型的信息检索指标,如 平均倒数排名精确度折现累积增益

搜索质量评估从查看您的搜索应用程序的用户以及他们正在搜索的内容开始。用户有一个特定的信息需求;例如,他们在网店中寻找礼物或想要为他们的下一个假期预订航班。他们通常会在搜索框或其他网页表单中输入一些搜索词。所有这些信息,连同关于用户的元信息(例如浏览器、位置、之前的偏好等),然后被转换为对底层搜索系统的查询。

搜索工程师面临的挑战是调整从用户输入到具体查询的翻译过程,以确保搜索结果包含与用户信息需求最相关的信息。这只有在搜索结果质量通过代表性用户查询测试套件不断评估的情况下才能实现,以确保对某一特定查询的排名改进不会对其他类型查询的排名产生负面影响。

为了开始进行搜索质量评估,您需要三个基本的东西:

  1. 您希望评估查询性能的文档集合,通常是一个或多个数据流或索引。
  2. 用户输入到系统中的一组典型搜索请求。
  3. 一组文档评级,表示文档相对于搜索请求的相关性。

需要注意的是,每个测试查询都需要一组文档评级,并且相关性判断是基于输入查询的用户的 信息需求。

排名评估API提供了一种便捷的方式,可以在排名评估请求中使用这些信息来计算不同的搜索评估指标。这为您提供了对整体搜索质量的初步估计,以及在优化应用程序中查询生成的各个方面时可以参考的衡量标准。

路径参数

edit
<target>
(可选,字符串) 用于限制请求的逗号分隔的数据流、索引和别名列表。支持通配符 (*)。要针对所有数据流和索引,请省略此参数或使用 *_all

查询参数

edit
allow_no_indices

(可选, 布尔值) 如果为false,当任何通配符表达式、 索引别名_all值仅针对缺失或关闭的索引时,请求将返回错误。 即使请求针对其他打开的索引,此行为也适用。例如,如果一个请求针对foo*,bar*,但没有任何索引以bar开头,即使存在以foo开头的索引,请求也会返回错误。

默认为 true

expand_wildcards

(可选,字符串) 通配符模式可以匹配的索引类型。如果请求可以针对数据流,此参数确定通配符表达式是否匹配隐藏的数据流。支持逗号分隔的值,例如 open,hidden。有效值为:

all
匹配任何数据流或索引,包括 隐藏的 数据流和索引。
open
匹配开放的、非隐藏的索引。同时也匹配任何非隐藏的数据流。
closed
匹配关闭的、非隐藏的索引。同时也匹配任何非隐藏的数据流。数据流不能被关闭。
hidden
匹配隐藏的数据流和隐藏的索引。必须与 openclosed 或两者结合使用。
none
不接受通配符模式。

默认为 open

ignore_unavailable
(可选,布尔值) 如果为false,则当请求目标是一个缺失或关闭的索引时,请求将返回错误。默认为false

示例

edit

在其最基本的形式中,对_rank_eval端点的请求有两个部分:

GET /my-index-000001/_rank_eval
{
  "requests": [ ... ],                            
  "metric": {                                     
    "mean_reciprocal_rank": { ... }               
  }
}

一组典型的搜索请求,以及它们提供的评分

计算评估指标的定义

一个特定的指标及其参数

请求部分包含几个典型的搜索请求,这些请求适用于您的应用程序,并附有每个特定搜索请求的文档评级。

GET /my-index-000001/_rank_eval
{
  "requests": [
    {
      "id": "amsterdam_query",                                  
      "request": {                                              
          "query": { "match": { "text": "amsterdam" } }
      },
      "ratings": [                                              
        { "_index": "my-index-000001", "_id": "doc1", "rating": 0 },
        { "_index": "my-index-000001", "_id": "doc2", "rating": 3 },
        { "_index": "my-index-000001", "_id": "doc3", "rating": 1 }
      ]
    },
    {
      "id": "berlin_query",
      "request": {
        "query": { "match": { "text": "berlin" } }
      },
      "ratings": [
        { "_index": "my-index-000001", "_id": "doc1", "rating": 1 }
      ]
    }
  ]
}

搜索请求的ID,用于稍后对结果详细信息进行分组。

正在评估的查询。

文档评级的列表。每个条目包含以下参数:

  • _index: 文档的索引。对于数据流,这应该是文档的后备索引。
  • _id: 文档ID。
  • rating: 文档与此次搜索请求的相关性。

文档的评分可以是任何表示用户定义的相关性尺度的整数值。对于某些指标,仅提供二元评分(例如0表示不相关,1表示相关)就足够了,而其他指标可以使用更细粒度的评分。

基于模板的排序评估

edit

作为每次测试请求提供单一查询的替代方案,可以在评估请求中指定查询模板并在之后引用它们。这样,具有相似结构但仅在参数上有所不同的查询就不必在requests部分中重复出现。在典型的搜索系统中,用户的输入通常会填充到一小部分查询模板中,这有助于使评估请求更加简洁。

GET /my-index-000001/_rank_eval
{
   [...]
  "templates": [
     {
        "id": "match_one_field_query",  
        "template": { 
            "inline": {
                "query": {
                  "match": { "{{field}}": { "query": "{{query_string}}" }}
                }
            }
        }
     }
  ],
  "requests": [
      {
         "id": "amsterdam_query",
         "ratings": [ ... ],
         "template_id": "match_one_field_query", 
         "params": { 
            "query_string": "amsterdam",
            "field": "text"
          }
     },
    [...]
}

模板ID

要使用的模板定义

对先前定义的模板的引用

用于填充模板的参数

您还可以使用存储的搜索模板

GET /my_index/_rank_eval
{
   [...]
  "templates": [
     {
        "id": "match_one_field_query",  
        "template": { 
            "id": "match_one_field_query"
        }
     }
  ],
  "requests": [...]
}

用于请求的模板ID

存储在集群状态中的模板ID

可用的评估指标

edit

The metric 部分决定了将使用哪种可用的评估指标。支持以下指标:

K处的精度 (P@k)
edit

此指标衡量前k个搜索结果中相关结果的比例。 它是著名的 精确度 指标的一种形式,仅关注前k个文档。它是前k个结果中相关文档的比例。精确度为10(P@10)值为0.6,则意味着在用户的信息需求下,前10个命中结果中有6个是相关的。

P@k 作为一个简单的评估指标效果很好,它具有易于理解和解释的优点。集合中的文档需要根据当前查询被评定为相关或不相关。P@k 是一个基于集合的指标,不考虑相关文档在前 k 个结果中的位置,因此包含一个相关结果在第 10 位的十个结果的排名与包含一个相关结果在第 1 位的十个结果的排名同样好。

GET /my-index-000001/_rank_eval
{
  "requests": [
    {
      "id": "JFK query",
      "request": { "query": { "match_all": {} } },
      "ratings": []
    } ],
  "metric": {
    "precision": {
      "k": 20,
      "relevant_rating_threshold": 1,
      "ignore_unlabeled": false
    }
  }
}

指标 precision 接受以下可选参数

Parameter Description

k

设置每个查询检索的最大文档数量。此值将代替查询中的通常size参数。默认为10。

相关评分阈值

设置评分阈值,高于该阈值的文档被认为是“相关的”。默认为1

ignore_unlabeled

控制搜索结果中未标记文档的计数方式。 如果设置为true,未标记的文档将被忽略,既不计为相关也不计为不相关。设置为false(默认值),它们将被视为不相关。

K处的召回率 (R@k)
edit

此指标衡量前k个搜索结果中相关结果的总数。它是著名的召回率指标的一种形式。它是前k个结果中相关文档的比例,相对于所有可能的相关结果。召回率在10(R@10)值为0.5,则意味着在用户的8个相关文档中,有4个在10个最高命中结果中被检索到。

R@k 作为一个简单的评估指标效果很好,它具有易于理解和解释的优点。集合中的文档需要根据当前查询被评定为相关或不相关。R@k 是一个基于集合的指标,不考虑相关文档在前 k 个结果中的位置,因此包含一个相关结果在第 10 位的十个结果的排名与包含一个相关结果在第 1 位的十个结果的排名同样好。

GET /my-index-000001/_rank_eval
{
  "requests": [
    {
      "id": "JFK query",
      "request": { "query": { "match_all": {} } },
      "ratings": []
    } ],
  "metric": {
    "recall": {
      "k": 20,
      "relevant_rating_threshold": 1
    }
  }
}

指标 recall 接受以下可选参数

Parameter Description

k

设置每个查询检索的最大文档数。此值将代替查询中的通常size参数。默认为10。

相关评分阈值

设置评分阈值,高于该阈值的文档被认为是“相关”的。默认为1

平均倒数排名
edit

对于测试集中的每个查询,该指标计算第一个相关文档的排名的倒数。例如,在位置3找到第一个相关结果意味着倒数排名是1/3。每个查询的倒数排名在测试集中的所有查询中取平均值,以得到平均倒数排名

GET /my-index-000001/_rank_eval
{
  "requests": [
    {
      "id": "JFK query",
      "request": { "query": { "match_all": {} } },
      "ratings": []
    } ],
  "metric": {
    "mean_reciprocal_rank": {
      "k": 20,
      "relevant_rating_threshold": 1
    }
  }
}

指标 mean_reciprocal_rank 接受以下可选参数

Parameter Description

k

设置每个查询检索的最大文档数量。此值将代替查询中的通常size参数。默认为10。

相关评分阈值

设置评分阈值,高于该阈值的文档被认为是“相关的”。默认为1

折扣累积增益 (DCG)
edit

与上述两种指标不同, 折扣累计增益 同时考虑了搜索结果的排名和评分。

假设是,当高度相关的文档出现在结果列表的顶部时,对用户更有用。因此,DCG公式减少了较低搜索排名文档的高评分对整体DCG指标的贡献。

GET /my-index-000001/_rank_eval
{
  "requests": [
    {
      "id": "JFK query",
      "request": { "query": { "match_all": {} } },
      "ratings": []
    } ],
  "metric": {
    "dcg": {
      "k": 20,
      "normalize": false
    }
  }
}

指标 dcg 接受以下可选参数:

Parameter Description

k

设置每个查询检索的最大文档数。此值将代替查询中的通常size参数。默认为10。

normalize

如果设置为 true,此指标将计算 归一化折损累计增益(Normalized DCG)

期望倒数排名 (ERR)
edit

期望倒数排名(ERR)是经典倒数排名的扩展,适用于分级相关性情况(Olivier Chapelle, Donald Metzler, Ya Zhang, 和 Pierre Grinspan. 2009年1月. 分级相关性的期望倒数排名。)

它基于搜索的级联模型假设,即用户按顺序浏览排序的搜索结果,并在找到满足信息需求的第一个文档时停止。因此,它是一个很好的问答和导航查询的度量标准,但对于用户希望在顶部k个结果中找到许多相关文档的调查型信息需求来说,效果较差。

该指标模型表示用户在结果列表中停止阅读的位置的倒数的期望值。这意味着排名靠前的相关文档将对总分有较大的贡献。然而,如果同一文档出现在较低的排名位置,它对分数的贡献将大大减少;如果前面有一些相关(但可能不太相关)的文档,情况更是如此。通过这种方式,ERR指标对在非常相关的文档之后显示的文档进行折扣。这引入了相关文档排序中的一种依赖性概念,例如精确度或DCG并未考虑这一点。

GET /my-index-000001/_rank_eval
{
  "requests": [
    {
      "id": "JFK query",
      "request": { "query": { "match_all": {} } },
      "ratings": []
    } ],
  "metric": {
    "expected_reciprocal_rank": {
      "maximum_relevance": 3,
      "k": 20
    }
  }
}

指标 expected_reciprocal_rank 接受以下参数:

Parameter Description

最大相关性

必填参数。用户提供的相关性判断中使用的最高相关性等级。

k

设置每个查询检索的最大文档数。此值将代替查询中的通常size参数。默认为10。

响应格式

edit

来自 _rank_eval 端点的响应包含为定义的质量指标计算的总体结果,一个包含测试套件中每个查询结果细分的 details 部分,以及一个可选的显示单个查询潜在错误的 failures 部分。响应具有以下格式:

{
  "rank_eval": {
    "metric_score": 0.4,                          
      "details": {
      "my_query_id1": {                           
        "metric_score": 0.6,                      
        "unrated_docs": [                         
          {
            "_index": "my-index-000001",
            "_id": "1960795"
          }, ...
        ],
        "hits": [
          {
            "hit": {                              
              "_index": "my-index-000001",
              "_type": "page",
              "_id": "1528558",
              "_score": 7.0556192
            },
            "rating": 1
          }, ...
        ],
        "metric_details": {                       
          "precision": {
            "relevant_docs_retrieved": 6,
            "docs_retrieved": 10
          }
        }
      },
      "my_query_id2": { [... ] }
    },
    "failures": { [... ] }
  }
}

由定义的指标计算出的总体评估质量

the details 部分包含原始 requests 部分中每个查询的条目,按搜索请求 ID 键入

details部分中的metric_score显示了此查询对全局质量指标分数的贡献

the unrated_docs 部分包含搜索结果中每个文档的 _index_id 条目,这些文档在此查询中没有评分值。这可以用来要求用户为这些文档提供评分

the hits 部分显示了带有其提供评级的搜索结果的分组

the metric_details 提供了关于计算的质量指标的额外信息(例如,检索到的文档中有多少是相关的)。内容因每个指标而异,但有助于更好地解释结果

矢量瓦片搜索API

edit

搜索矢量瓦片中的地理空间值。返回结果为二进制 Mapbox 矢量瓦片

GET my-index/_mvt/my-geo-field/15/5271/12710

请求

edit

GET /_mvt////

POST /_mvt////

先决条件

edit

路径参数

edit
<target>

(必需,字符串) 要搜索的数据流、索引或别名的逗号分隔列表。支持通配符 (*)。要搜索所有数据流和索引,请省略此参数或使用 *_all

要搜索远程集群,请使用 : 语法。请参阅 跨集群搜索

<field>

(必需,字符串) 包含要返回的地理空间值的字段。必须是 geo_pointgeo_shape 字段。该字段必须 启用 doc values。不能是嵌套字段。

矢量瓦片本身不支持几何集合。对于geo_shape字段中的geometrycollection值,API会为集合中的每个元素返回一个hits图层特征。此行为可能会在未来的版本中发生变化。

<zoom>
(必需,整数) 要搜索的矢量瓦片的缩放级别。接受 0-29
<x>
(必需,整数) 向量图块搜索的X坐标。
<y>
(必需,整数) 要搜索的矢量瓦片的Y坐标。

描述

edit

在内部,Elasticsearch将矢量瓦片搜索API请求转换为包含以下内容的搜索

  • 一个针对geo_bounding_box查询。该查询使用//瓦片作为边界框。
  • 一个针对geotile_gridgeohex_grid聚合。grid_agg参数确定聚合类型。聚合使用//瓦片作为边界框。
  • 可选地,一个针对geo_bounds聚合。搜索仅在exact_bounds参数为true时包含此聚合。
  • 如果可选参数with_labels为true,内部搜索将包含一个动态运行时字段,该字段调用几何文档值的getLabelPosition函数。这使得能够生成包含建议几何标签的新点特征,例如,多边形将只有一个标签。

例如,Elasticsearch 可能会将一个带有 grid_agg 参数为 geotileexact_bounds 参数为 true 的矢量瓦片搜索 API 请求转换为以下搜索:

GET my-index/_search
{
  "size": 10000,
  "query": {
    "geo_bounding_box": {
      "my-geo-field": {
        "top_left": {
          "lat": -40.979898069620134,
          "lon": -45
        },
        "bottom_right": {
          "lat": -66.51326044311186,
          "lon": 0
        }
      }
    }
  },
  "aggregations": {
    "grid": {
      "geotile_grid": {
        "field": "my-geo-field",
        "precision": 11,
        "size": 65536,
        "bounds": {
          "top_left": {
            "lat": -40.979898069620134,
            "lon": -45
          },
          "bottom_right": {
            "lat": -66.51326044311186,
            "lon": 0
          }
        }
      }
    },
    "bounds": {
      "geo_bounds": {
        "field": "my-geo-field",
        "wrap_longitude": false
      }
    }
  }
}

API返回的结果为二进制 Mapbox矢量瓦片。Mapbox矢量瓦片 被编码为Google Protobufs (PBF)。默认情况下,瓦片包含三个图层:

  • 一个包含每个与geo_bounding_box查询匹配的值的hits层。
  • 一个包含每个geotile_gridgeohex_grid单元格的aggs层。该层仅包含具有匹配数据的单元格的特征。
  • 一个包含以下内容的层:

    • 一个包含边界框的特征。默认情况下,这是图块的边界框。
    • geotile_gridgeohex_grid上的任何子聚合的值范围。
    • 搜索的元数据。

API仅返回可以在其缩放级别显示的要素。例如,如果一个多边形要素在其缩放级别没有面积,API会将其省略。

API 返回的错误为 UTF-8 编码的 JSON。

查询参数

edit

您可以为此API指定多个选项,既可以作为查询参数,也可以作为请求体参数。如果同时指定这两个参数,查询参数优先。

exact_bounds

(可选,布尔值) 如果为false,则meta层的特征是图块的边界框。默认为false

如果为true,则meta层的特征是由 geo_bounds聚合生成的边界框。 该聚合在值上运行,这些值与// 瓦片相交,并将wrap_longitude设置为false。生成的边界框可能 大于矢量瓦片。

extent
(可选,整数) 图块的边长,以像素为单位。矢量图块是边长相等的正方形。默认为 4096
buffer
(可选,整数) 图块外部裁剪缓冲区的大小,以像素为单位。 这允许渲染器避免几何图形超出图块范围时产生的轮廓伪影。 默认为 5
grid_agg

(可选,字符串)用于为创建网格的聚合。

适用于 grid_agg 的有效值
geotile (默认)
geotile_grid 聚合。
geohex
geohex_grid 聚合。
grid_precision

(可选, 整数) grid_agg 中单元格的精度级别。接受 0-8。默认为 8。如果为 0,结果不包括 aggs 层。

Grid precision for geotile

对于geotilegrid_agg,您可以在aggs层中使用单元格作为较低缩放级别的图块。grid_precision表示通过这些单元格可用的额外缩放级别。最终的精度计算如下:

+ grid_precision

例如,如果 7 并且 grid_precision8,那么 geotile_grid 聚合将使用精度 15。最终的最大精度是 29

The grid_precision 也决定了网格的单元格数量,如下所示:

(2^网格精度) x (2^网格精度)

例如,值为 8 时,将瓦片划分为 256 x 256 个单元格。aggs 图层仅包含具有匹配数据的单元格的特征。

Grid precision for geohex

对于geohexgrid_agg,Elasticsearch 使用 grid_precision 来计算最终精度,如下所示:

+ grid_precision

此精度决定了由geohex聚合生成的六边形单元的H3分辨率。下表映射了每个精度的H3分辨率。

例如,如果 3 并且 grid_precision3,精度是 6。在精度为 6 时,六边形单元格的 H3 分辨率为 2。如果 3 并且 grid_precision4,精度是 7。在 精度为 7 时,六边形单元格的 H3 分辨率为 3

<td align="left" valign="
精度 唯一瓦片箱 H3 分辨率 唯一六边形箱 比率

1

4

0

122

30.5

2

16

0

122

7.625

3

64

1

842

13.15625

4

256

1

842

3.2890625

5

1024

2

5882

5.744140625

6

4096

2

5882

1.436035156

7

16384

3

41162

2.512329102

8

65536

3

41162

0.6280822754

9

262144

4

288122

1.099098206

10

1048576

4

288122

0.2747745514

11

4194304

5

2016842

0.4808526039

12

16777216

6

14117882

0.8414913416

13

67108864

6

14117882

0.2103728354

14

268435456

7

98825162

0.3681524172

15

1073741824

8

691776122

0.644266719

16

4294967296

8

691776122

0.1610666797

17

17179869184

9

4842432842

0.2818666889

18

68719476736

10

33897029882

0.4932667053

19

274877906944

11

237279209162

0.8632167343

20

1099511627776

11

237279209162

0.2158041836

21

4398046511104

12

1660954464122

0.3776573213

22

17592186044416

13

11626681248842

0.6609003122

23

70368744177664

13

11626681248842

0.165225078

24

281474976710656

grid_type

(可选,字符串) 确定 aggs 层中要素的几何类型。在 aggs 层中,每个要素代表网格中的一个单元格。

有效的 grid_type
grid (默认)
每个要素是一个 Polygon,表示单元格的几何形状。对于 grid_agggeotile 的情况,要素是单元格的边界框。对于 grid_agggeohex 的情况,要素是六边形单元格的边界。
point
每个要素是一个 Point,表示单元格的质心。
centroid
每个要素是一个 Point,表示单元格内数据的质心。对于 复杂几何形状,实际质心可能位于单元格外。在这些情况下, 要素设置为单元格内最接近质心的点。
size
(可选,整数) 在 hits 层中返回的最大特征数量。 接受 0-10000。默认为 10000。如果为 0,结果不包括 hits 层。
track_total_hits

(可选,整数或布尔值) 匹配查询的命中次数,精确计数。默认为 10000

如果true,则以牺牲一些性能为代价返回匹配查询的命中数的准确值。 如果false,则响应中不包括与查询匹配的总命中数。

with_labels

(可选, 布尔值) 如果为 true,hits 和 aggs 图层将包含额外的点特征,表示原始特征的建议标签位置。

  • PointMultiPoint 特征将选择其中一个点。
  • PolygonMultiPolygon 特征将生成一个单一点, 如果是质心,如果它在多边形内,或者从排序的三角树中选择的多边形内的另一个点。
  • LineString 特征同样会从三角树中选择一个大致中心的点。
  • 聚合结果将为每个聚合桶提供一个中心点。

原始特征的所有属性也将被复制到新的标签特征中。 此外,新的特征将使用标签 _mvt_label_position 进行区分。

请求体

edit
aggs

(可选, 聚合对象) 子聚合 用于 grid_agg。支持以下聚合类型:

exact_bounds

(可选,布尔值) 如果为false,则meta层的特征是图块的边界框。默认为false

如果为true,则meta层的特征是由 geo_bounds聚合生成的边界框。 该聚合在值上运行,这些值与// 瓦片相交,并将wrap_longitude设置为false。生成的边界框可能 大于矢量瓦片。

extent
(可选,整数) 图块的边长,以像素为单位。矢量图块是边长相等的正方形。默认为 4096
buffer
(可选,整数) 图块外部裁剪缓冲区的大小,以像素为单位。 这允许渲染器避免几何图形超出图块范围时产生的轮廓伪影。 默认为 5
fields

(可选,字符串和对象数组) 在 hits 层中返回的字段。 支持通配符 (*)。

此参数不支持包含数组值的字段。包含数组值的字段可能会返回不一致的结果。

您可以在数组中将字段指定为字符串或对象。

Properties of fields objects
field
(必需, 字符串) 要返回的字段。支持通配符 (*)。
format

(可选, 字符串) 日期和地理空间字段的格式。其他字段数据类型不支持此参数。

datedate_nanos 字段接受一个 日期格式geo_pointgeo_shape 字段接受:

geojson (默认)
GeoJSON
wkt
Well Known Text
mvt()

二进制 Mapbox 矢量瓦片。API 返回瓦片作为base64编码的字符串。 的格式为 //,带有两个可选的后缀:@ 和/或 :。例如,2/0/12/0/1@4096:5

mvt parameters
(必需, 整数) 瓦片的缩放级别。接受 0-29
(必需, 整数) 瓦片的X坐标。
(必需, 整数) 瓦片的Y坐标。
(可选, 整数) 瓦片一边的大小,以像素为单位。矢量瓦片是 正方形,边长相等。默认为 4096
(可选, 整数) 瓦片外部裁剪缓冲区的大小,以像素为单位。 这允许渲染器避免几何图形延伸到瓦片范围之外时产生的轮廓伪影。默认为 5
grid_agg

(可选,字符串)用于为创建网格的聚合。

适用于 grid_agg 的有效值
geotile (默认)
geotile_grid 聚合。
geohex
geohex_grid 聚合。
grid_precision

(可选, 整数) grid_agg 中单元格的精度级别。接受 0-8。默认为 8。如果为 0,结果不包括 aggs 层。

Grid precision for geotile

对于geotilegrid_agg,您可以在aggs层中使用单元格作为较低缩放级别的图块。grid_precision表示通过这些单元格可用的额外缩放级别。最终的精度计算如下:

+ grid_precision

例如,如果 7 并且 grid_precision8,那么 geotile_grid 聚合将使用精度 15。最终的最大精度是 29

The grid_precision 也决定了网格的单元格数量,如下所示:

(2^网格精度) x (2^网格精度)

例如,值为 8 时,将瓦片划分为 256 x 256 个单元格。aggs 图层仅包含具有匹配数据的单元格的特征。

Grid precision for geohex

对于geohexgrid_agg,Elasticsearch 使用 grid_precision 来计算最终精度,如下所示:

+ grid_precision

此精度决定了由geohex聚合生成的六边形单元的H3分辨率。下表映射了每个精度的H3分辨率。

例如,如果 3 并且 grid_precision3,精度是 6。在精度为 6 时,六边形单元格的 H3 分辨率为 2。如果 3 并且 grid_precision4,精度是 7。在 精度为 7 时,六边形单元格的 H3 分辨率为 3

<td align="left" valign="
精度 唯一瓦片箱 H3 分辨率 唯一六边形箱 比率

1

4

0

122

30.5

2

16

0

122

7.625

3

64

1

842

13.15625

4

256

1

842

3.2890625

5

1024

2

5882

5.744140625

6

4096

2

5882

1.436035156

7

16384

3

41162

2.512329102

8

65536

3

41162

0.6280822754

9

262144

4

288122

1.099098206

10

1048576

4

288122

0.2747745514

11

4194304

5

2016842

0.4808526039

12

16777216

6

14117882

0.8414913416

13

67108864

6

14117882

0.2103728354

14

268435456

7

98825162

0.3681524172

15

1073741824

8

691776122

0.644266719

16

4294967296

8

691776122

0.1610666797

17

17179869184

9

4842432842

0.2818666889

18

68719476736

10

33897029882

0.4932667053

19

274877906944

11

237279209162

0.8632167343

20

1099511627776

11

237279209162

0.2158041836

21

4398046511104

12

1660954464122

0.3776573213

22

17592186044416

13

11626681248842

0.6609003122

23

70368744177664

13

11626681248842

0.165225078

24

281474976710656

grid_type

(可选,字符串) 确定 aggs 层中要素的几何类型。在 aggs 层中,每个要素代表网格中的一个单元格。

有效的 grid_type
grid (默认)
每个要素是一个 Polygon,表示单元格的几何形状。对于 grid_agggeotile 的情况,要素是单元格的边界框。对于 grid_agggeohex 的情况,要素是六边形单元格的边界。
point
每个要素是一个 Point,表示单元格的质心。
centroid
每个要素是一个 Point,表示单元格内数据的质心。对于 复杂几何形状,实际质心可能位于单元格外。在这些情况下, 要素设置为单元格内最接近质心的点。
query
(可选, 对象) Query DSL 用于过滤搜索的文档。
runtime_mappings

(可选,对象的对象) 定义搜索请求中的一个或多个运行时字段。这些字段优先于具有相同名称的映射字段。

Properties of runtime_mappings objects

(必需,对象) 运行时字段的配置。键是字段名称。

Properties of
type

(必需的, 字符串) 字段类型, 可以是以下任意一种:

  • boolean
  • composite
  • date
  • double
  • geo_point
  • ip
  • keyword
  • long
  • lookup
script

(可选, 字符串) Painless脚本 在查询时执行。该脚本可以访问文档的整个上下文,包括原始的 _source 和任何映射字段及其值。

此脚本必须包含 emit 以返回计算值。例如:

"script": "emit(doc['@timestamp'].value.dayOfWeekEnum.toString())"
size
(可选,整数) 在 hits 层中返回的最大特征数量。 接受 0-10000。默认为 10000。如果为 0,结果不包括 hits 层。
sort

(可选,排序对象数组) 对 hits 图层中的要素进行排序。

默认情况下,API 会为每个要素计算一个边界框。它根据此框的对角线长度对要素进行排序,从最长到最短。

track_total_hits

(可选,整数或布尔值) 匹配查询的命中次数,精确计数。默认为 10000

如果true,则以牺牲一些性能为代价返回匹配查询的命中数的准确值。 如果false,则响应中不包括与查询匹配的总命中数。

with_labels

(可选, 布尔值) 如果为 true,hits 和 aggs 图层将包含额外的点特征,表示原始特征的建议标签位置。

  • PointMultiPoint 特征将选择其中一个点。
  • PolygonMultiPolygon 特征将生成一个单一点, 如果是质心,如果它在多边形内,或者从排序的三角树中选择的多边形内的另一个点。
  • LineString 特征同样会从三角树中选择一个大致中心的点。
  • 聚合结果将为每个聚合桶提供一个中心点。

原始特征的所有属性也将被复制到新的标签特征中。 此外,新的特征将使用标签 _mvt_label_position 进行区分。

响应

edit

返回的矢量瓦片包含以下数据:

hits

(对象) 包含 geo_bounding_box 查询结果的图层。

Properties of hits
extent
(整数) 瓦片一边的大小,以像素为单位。矢量瓦片是等边的方形。
version
(整数) Mapbox 矢量瓦片规范的主版本号。
features

(对象数组) 特征数组。包含每个与 geo_bounding_box 查询匹配的 值的特征。

Properties of features objects
geometry

(对象) 特征的几何形状。

Properties of geometry
type

(字符串) 特征的几何类型。有效值为:

  • UNKNOWN
  • POINT
  • LINESTRING
  • POLYGON
coordinates
(整数数组或数组的数组) 特征的瓦片坐标。
properties

(对象) 功能的属性。

Properties of properties
_id
(字符串) 特征文档的 _id
_index
(字符串) 特征文档的索引名称。
字段值。仅在 fields 参数中的字段返回。
type

(整数) 特征几何类型的标识符。值为:

  • 1 (POINT)
  • 2 (LINESTRING)
  • 3 (POLYGON)
aggs

(对象) 包含 grid_agg 聚合及其子聚合结果的图层。

Properties of aggs
extent
(整数) 瓦片一边的大小,以像素为单位。矢量瓦片是等边的方形。
version
(整数) Mapbox 矢量瓦片规范的主版本号。
features

(对象数组) 特征数组。包含网格中每个单元格的特征。

Properties of features objects
geometry

(对象) 特征的几何形状。

Properties of geometry
type

(字符串) 特征的几何类型。有效值为:

  • UNKNOWN
  • POINT
  • LINESTRING
  • POLYGON
coordinates
(整数数组或数组的数组) 特征的瓦片坐标。
properties

(对象) 功能的属性。

Properties of properties
_count
(长整型) 单元格文档的数量。
_key
(字符串) 单元格的桶键,格式为 //
.value
单元格的子聚合结果。仅在 aggs 参数中的子聚合时返回。
type

(整数) 特征几何类型的标识符。值为:

  • 1 (POINT)
  • 2 (LINESTRING)
  • 3 (POLYGON)
meta

(对象) 包含请求元数据的层。

Properties of meta
extent
(整数) 瓦片一边的大小,以像素为单位。矢量瓦片是正方形,边长相等。
version
(整数) Mapbox 矢量瓦片规范的主版本号。
features

(对象数组) 包含一个用于边界框的功能。

Properties of features objects
geometry

(对象) 特征的几何形状。

Properties of geometry
type

(字符串) 特征的几何类型。有效值为:

  • UNKNOWN
  • POINT
  • LINESTRING
  • POLYGON
coordinates
(整数数组或数组的数组) 特征的瓦片坐标。
properties

(对象) 特征的属性。

Properties of properties
_shards.failed
(整数) 执行搜索失败的碎片数量。参见搜索 API 的 shards 响应属性。
_shards.skipped
(整数) 跳过搜索的碎片数量。参见搜索 API 的 shards 响应属性。
_shards.successful
(整数) 成功执行搜索的碎片数量。参见搜索 API 的 shards 响应属性。
_shards.total
(整数) 需要查询的碎片总数,包括未分配的碎片。参见搜索 API 的 shards 响应属性。
aggregations._count.avg
(浮点数) aggs 层中特征的 _count 值的平均值。
aggregations._count.count
(整数) aggs 层中特征的唯一 _count 值的数量。
aggregations._count.max
(浮点数) aggs 层中特征的 _count 值的最大值。
aggregations._count.min
(浮点数) aggs 层中特征的 _count 值的最小值。
aggregations._count.sum
(浮点数) aggs 层中特征的 _count 值的总和。
aggregations..avg
(浮点数) 子聚合结果的平均值。
aggregations..count
(整数) 子聚合结果中的唯一值数量。
aggregations..max
(浮点数) 子聚合结果中的最大值。
aggregations..min
(浮点数) 子聚合结果中的最小值。
aggregations..sum
(浮点数) 子聚合结果的值的总和。
hits.max_score
(浮点数) 搜索命中文档的最高 _score
hits.total.relation

(字符串) 指示 hits.total.value 是准确的值还是下限。 可能的值有:

eq
准确的
gte
下限
hits.total.value
(整数) 搜索的总命中数。
timed_out
(布尔值) 如果为 true,则搜索在完成前超时。结果可能是部分的或空的。
took
(整数) Elasticsearch 运行搜索所花费的毫秒数。参见搜索 API 的 took 响应属性。
type

(整数) 特征几何类型的标识符。值为:

  • 1 (POINT)
  • 2 (LINESTRING)
  • 3 (POLYGON)

示例

edit

以下请求创建了 museum 索引并添加了几个地理空间 location 值。

PUT museums
{
  "mappings": {
    "properties": {
      "location": {
        "type": "geo_point"
      },
      "name": {
        "type": "keyword"
      },
      "price": {
        "type": "long"
      },
      "included": {
        "type": "boolean"
      }
    }
  }
}

POST museums/_bulk?refresh
{ "index": { "_id": "1" } }
{ "location": "POINT (4.912350 52.374081)", "name": "NEMO Science Museum",  "price": 1750, "included": true }
{ "index": { "_id": "2" } }
{ "location": "POINT (4.901618 52.369219)", "name": "Museum Het Rembrandthuis", "price": 1500, "included": false }
{ "index": { "_id": "3" } }
{ "location": "POINT (4.914722 52.371667)", "name": "Nederlands Scheepvaartmuseum", "price":1650, "included": true }
{ "index": { "_id": "4" } }
{ "location": "POINT (4.914722 52.371667)", "name": "Amsterdam Centre for Architecture", "price":0, "included": true }

以下请求搜索索引中与13/4207/2692矢量瓦片相交的location值。

GET museums/_mvt/location/13/4207/2692
{
  "grid_agg": "geotile",
  "grid_precision": 2,
  "fields": [
    "name",
    "price"
  ],
  "query": {
    "term": {
      "included": true
    }
  },
  "aggs": {
    "min_price": {
      "min": {
        "field": "price"
      }
    },
    "max_price": {
      "max": {
        "field": "price"
      }
    },
    "avg_price": {
      "avg": {
        "field": "price"
      }
    }
  }
}

API返回结果为一个二进制矢量瓦片。当解码为JSON时,瓦片包含以下数据:

{
  "hits": {
    "extent": 4096,
    "version": 2,
    "features": [
      {
        "geometry": {
          "type": "Point",
          "coordinates": [
            3208,
            3864
          ]
        },
        "properties": {
          "_id": "1",
          "_index": "museums",
          "name": "NEMO Science Museum",
          "price": 1750
        },
        "type": 1
      },
      {
        "geometry": {
          "type": "Point",
          "coordinates": [
            3429,
            3496
          ]
        },
        "properties": {
          "_id": "3",
          "_index": "museums",
          "name": "Nederlands Scheepvaartmuseum",
          "price": 1650
        },
        "type": 1
      },
      {
        "geometry": {
          "type": "Point",
          "coordinates": [
            3429,
            3496
          ]
        },
        "properties": {
          "_id": "4",
          "_index": "museums",
          "name": "Amsterdam Centre for Architecture",
          "price": 0
        },
        "type": 1
      }
    ]
  },
  "aggs": {
    "extent": 4096,
    "version": 2,
    "features": [
      {
        "geometry": {
          "type": "Polygon",
          "coordinates": [
            [
              [
                3072,
                3072
              ],
              [
                4096,
                3072
              ],
              [
                4096,
                4096
              ],
              [
                3072,
                4096
              ],
              [
                3072,
                3072
              ]
            ]
          ]
        },
        "properties": {
          "_count": 3,
          "max_price.value": 1750.0,
          "min_price.value": 0.0,
          "avg_price.value": 1133.3333333333333
        },
        "type": 3
      }
    ]
  },
  "meta": {
    "extent": 4096,
    "version": 2,
    "features": [
      {
        "geometry": {
          "type": "Polygon",
          "coordinates": [
            [
              [
                0,
                0
              ],
              [
                4096,
                0
              ],
              [
                4096,
                4096
              ],
              [
                0,
                4096
              ],
              [
                0,
                0
              ]
            ]
          ]
        },
        "properties": {
          "_shards.failed": 0,
          "_shards.skipped": 0,
          "_shards.successful": 1,
          "_shards.total": 1,
          "aggregations._count.avg": 3.0,
          "aggregations._count.count": 1,
          "aggregations._count.max": 3.0,
          "aggregations._count.min": 3.0,
          "aggregations._count.sum": 3.0,
          "aggregations.avg_price.avg": 1133.3333333333333,
          "aggregations.avg_price.count": 1,
          "aggregations.avg_price.max": 1133.3333333333333,
          "aggregations.avg_price.min": 1133.3333333333333,
          "aggregations.avg_price.sum": 1133.3333333333333,
          "aggregations.max_price.avg": 1750.0,
          "aggregations.max_price.count": 1,
          "aggregations.max_price.max": 1750.0,
          "aggregations.max_price.min": 1750.0,
          "aggregations.max_price.sum": 1750.0,
          "aggregations.min_price.avg": 0.0,
          "aggregations.min_price.count": 1,
          "aggregations.min_price.max": 0.0,
          "aggregations.min_price.min": 0.0,
          "aggregations.min_price.sum": 0.0,
          "hits.max_score": 0.0,
          "hits.total.relation": "eq",
          "hits.total.value": 3,
          "timed_out": false,
          "took": 2
        },
        "type": 3
      }
    ]
  }
}