ELK-Elasticsearch(Search API)-未完
大多数搜索API都是多索引、多类型的,除了解释API端点之外。
Routing
在执行搜索时,将对所有索引/索引碎片(副本之间的轮询)进行广播。通过提供routing参数,可以对哪些碎片进行搜索。例如,当索引tweets时,routing的值可以是用户名:
POST /twitter/tweet?routing=kimchy
{
"user" : "kimchy",
"postDate" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}
在这种情况下,如果我们只想搜索特定用户的tweet,我们可以指定它为routing,从而导致搜索只触及相关的碎片:
POST /twitter/tweet/_search?routing=kimchy
{
"query": {
"bool" : {
"must" : {
"query_string" : {
"query" : "some query string here"
}
},
"filter" : {
"term" : { "user" : "kimchy" }
}
}
}
}
可以将routing参数以逗号分隔的字符串表示。这将导致与routing值匹配的相关碎片被查出。
Stats Group
搜索可以与统计组相关联,统计组维护每个组的统计聚合。它稍后可以使用索引统计API进行检索。例如,这里是一个搜索体请求,将请求与两个不同的组关联:
POST /_search
{
"query" : {
"match_all" : {}
},
"stats" : ["group1", "group2"]
}
全局搜索超时
单个搜索作为请求体搜索的一部分可以有一个超时。由于搜索请求可以来自许多源,Elasticsearch有一个动态的集群级别设置,用于全局搜索超时,适用于所有没有设置请求超时的搜索请求。默认值无全局超时。设置 key是search.default_search_timeout,可以使用Cluster Update Setting端点设置。将这个值设置为- 1,重置全局搜索超时设置为n无超时。
取消搜索
可以使用标准的任务取消机制来取消搜索。默认情况下,正在运行的搜索只检查是否取消了区段边界,因此取消可以被大段延迟。通过设置动态集群级别设置search.low_level_cancellation为true,可以改进搜索的取消响应。但是,它带来了更多的额外开销,更多频繁的取消检查在大型快速运行的搜索查询中带来的影响是显著的。更改此设置只会影响更改后开始的搜索。
搜索
搜索API允许你执行一个搜索查询并返回查询命中结果来匹配查询。查询可以使用一个简单的query string as a parameter或request body。
多索引,多类型
所有的搜索API都可以在一个索引中跨多个类型,并且可以跨多个索引来支持多索引语法。例如,我们可以在twitter索引中搜索所有类型的文档:
GET /twitter/_search?q=user:kimchy
我们也可以在特定类型中进行搜索:
GET /twitter/tweet,user/_search?q=user:kimchy
我们还可以在多个索引中搜索所有带有特定标记的tweet(例如,当每个用户都有自己的索引):
GET /kimchy,elasticsearch/tweet/_search?q=tag:wow
或者我们可以使用_all占位符搜索所有可用的索引:
GET /_all/tweet/_search?q=tag:wow
甚至搜索所有的索引和类型:
GET /_search?q=tag:wow
默认情况下,Elasticsearch不会因为请求命中碎片数量问题拒的搜索请求。尽管Elasticsearch将优化协调节点上的搜索执行,但是大量的碎片还是会对CPU和内存有很大的影响。通常,更好的方法是组织数据以减少较大的碎片。如果您想配置一个软限制,您可以更新action.search.shard_count。限制集群设置,以拒绝命中过多碎片的搜索请求。
URI请求
可以通过提供请求参数来完全使用URI执行搜索请求。在使用这种模式执行搜索时,并不是所有的搜索选项都是公开的,但是对于快速的“curl测试”来说,这是很方便的。这是一个例子:
GET twitter/tweet/_search?q=user:kimchy
这里是一个响应的例子:
{
"timed_out": false,
"took": 62,
"_shards":{
"total" : 1,
"successful" : 1,
"failed" : 0
},
"hits":{
"total" : 1,
"max_score": 1.3862944,
"hits" : [
{
"_index" : "twitter",
"_type" : "tweet",
"_id" : "0",
"_score": 1.3862944,
"_source" : {
"user" : "kimchy",
"date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch",
"likes": 0
}
}
]
}
}
参数
在URI中可以使用的参数如下:
名称 | 描述 |
---|---|
q | 查询字符串(映射到query_string 查询,更多细节参考Query String Query ) |
df | 在查询中没有定义字段前缀时使用的默认字段。 |
analyzer | 在分析查询字符串时,将使用analyzer名称。 |
analyze_wildcard | 对通配符和前缀查询进行分析。默认值为false。 |
batched_reduce_size | 在协调节点上应立即减少的碎片的数量。如果请求中的碎片数量可能很大,则应该将此值用作一种保护机制,以减少每个搜索请求的内存开销。 |
default_operator | 默认使用的运算符,可以是 AND或OR。 |
lenient | 如果设置为true,将导致基于格式的失败(例如向数字字段提供文本)被忽略。默认值为false。 |
explain | 对于每一个命中,都包含一个如何计算命中的解释。 |
_source | 设置为false,以禁用_source字段的检索。您还可以通过使用_source_include &_source_exclude 来检索文档的一部分(参见请求正文文档了解更多细节) |
stored_fields | 文档的选择性存储字段用于返回每个hit,逗号分隔。没有指定任何值将导致没有字段返回。 |
sort | 执行排序。形式可以是字fieldName 或fieldName:asc /fieldName:desc。fieldName可以是文档中的一个实际字段,也可以是特殊的_score名称来表示基于分数的排序。可以有多个排序参数(顺序很重要)。 |
track_scores | 当排序时,设置为true,以继续跟踪分数并作为每个命中的一部分返回。 |
timeout | 搜索超时,将搜索请求的边界限制为在指定的时间值内执行,并在到期时累积到该点的点击量。默认为没有超时。 |
terminate_after | 为每个shard收集的文档的最大数量,在到达时查询执行将提前终止。如果设置,响应将会有一个布尔字段 terminated_early,以指示查询执行是否实际终止。默认为没有terminate_after。 |
from | 从命中的索引开始返回。默认值为0。 |
size | 返回命中的数量,默认值为10. |
search_type | 搜索操作的类型。可以是dfs_query_then_fetch或query_then_fetch。默认为query_then_fetch。查看搜索类型,了解可以执行的不同类型搜索的更多细节。 |
请求体搜索
请求会以搜索DSL执行,其中包括Query DSL,下面是第一个例子:
GET /twitter/tweet/_search
{
"query" : {
"term" : { "user" : "kimchy" }
}
}
这是响应的例子:
{
"took": 1,
"timed_out": false,
"_shards":{
"total" : 1,
"successful" : 1,
"failed" : 0
},
"hits":{
"total" : 1,
"max_score": 1.3862944,
"hits" : [
{
"_index" : "twitter",
"_type" : "tweet",
"_id" : "0",
"_score": 1.3862944,
"_source" : {
"user" : "kimchy",
"message": "trying out Elasticsearch",
"date" : "2009-11-15T14:12:12",
"likes" : 0
}
}
]
}
}
参数
名称 | 描述 |
---|---|
q | 查询字符串(映射到 query_string,更多详细介绍参见 Query String Query) |
df | 在查询中定义没有字段前缀时使用的默认字段 |
analyzer | 在分析查询字符串时,将使用analyzer名称。 |
analyze_wildcard | 对通配符和前缀查询进行分析。默认值为false。 |
batched_reduce_size | 在协调节点上应立即减少的碎片的数量。如果请求中的碎片数量可能很大,则应该将此值用作一种保护机制,以减少每个搜索请求的内存开销。 |
default_operator | 默认使用的运算符,可以是 AND 或 OR。默认是 OR |
lenient | 如果设置为true,因为格式导致的失败(例如向数字字段提供文本)被忽略。默认值为false。 |
explain | 对于每一个命中,都包含一个如何计算命中的解释。 |
_source | 设置为false,以禁用_source字段的检索。您还可以通过使用_source_include & _source_exclude来检索文档的一部分(参见请求正文文档了解更多细节) |
stored_fields | 文档的选择性存储字段用于返回每个hit,逗号分隔。没有指定任何值将导致没有字段返回。 |
sort | 执行排序。形式可以是fieldName、或fieldName:asc /fieldName:desc。字段名可以是文档中的一个实际字段,也可以是特殊的_score名称来表示基于分数的排序。可以有多个排序参数(顺序很重要)。 |
track_scores | 当排序时,设置true,以继续跟踪分数并作为每个命中的一部分返回。 |
timeout | 搜索超时,将搜索请求的边界限制为在指定的时间值内执行,并在到期时累积到该点的点击量。默认为没有超时。 |
terminate_after | 为每个shard收集的文档的最大数量,在到达时查询执行将提前终止。如果设置,响应将会有一个布尔字段终止,以指示查询执行是否实际终止。默认为没有terminate_after。 |
from | 从索引返回命中的开始位置。默认值为0。 |
size | 返回命中的数量,默认为10。 |
search_type | 搜索操作的类型。可以是dfs_query_then_fetch或query_then_fetch。默认为query_then_fetch。查看搜索类型,了解可以执行的不同类型搜索的更多细节。 |
请求体搜索
搜索请求可以以一个搜索DSL执行,其中包含 Query DSL。下面是具体的例子:
GET /twitter/tweet/_search
{
"query" : {
"term" : { "user" : "kimchy" }
}
}
这是响应结果:
{
"took": 1,
"timed_out": false,
"_shards":{
"total" : 1,
"successful" : 1,
"failed" : 0
},
"hits":{
"total" : 1,
"max_score": 1.3862944,
"hits" : [
{
"_index" : "twitter",
"_type" : "tweet",
"_id" : "0",
"_score": 1.3862944,
"_source" : {
"user" : "kimchy",
"message": "trying out Elasticsearch",
"date" : "2009-11-15T14:12:12",
"likes" : 0
}
}
]
}
}
参数
名称 | 描述 |
---|---|
timeout | 搜索超时,将搜索请求的边界限制为在指定的时间值内执行,并在到期时累积到该点的点击量。默认为没有超时。参见“Time unit”一节。 |
from | 从某个偏移量中检索命中。默认值为0。 |
size | 返回命中数量。默认为10。如果您不关心是否得到一些回火,但是只关心匹配和/或聚合的数量,将值设置为0将有助于性能。 |
search_type | 搜索操作的类型。可以是dfs_query_then_fetch或query_then_fetch。默认为query_then_fetch。请参阅搜索类型以获得更多信息。 |
request_cache | 设置为true或false,以启用或禁用搜索结果的缓存,其中的大小为0,即聚合和建议(不返回顶级点击)。看到碎片请求缓存。 |
terminate_after | 为每个shard收集的文档的最大数量,在到达时查询执行将提前终止。如果设置,响应将会有一个布尔字段终止,以指示查询执行是否实际终止。默认为没有terminate_after。 |
batched_reduce_size | 在协调节点上应立即减少的碎片的数量。如果请求中的碎片数量可能很大,则应该将此值用作一种保护机制,以减少每个搜索请求的内存开销。 |
在上面,search_type和request_cache必须作为查询字符串参数传递。搜索请求的其余部分应该在主体内部传递。主体内容也可以作为REST参数传递给源。 HTTP GET和HTTP POST都可以用于执行搜索。由于不是所有的客户都支持和body打交道,POST也是被允许的。
匹配文档快速检查
如果我们只想知道是否有匹配特定查询的任何文档,那么我们可以将大小设置为0,表明我们对搜索结果不感兴趣。此外,我们还可以将“终止”设置为1,以指示在找到第一个匹配文档时,可以终止查询执行。
GET /_search?q=message:elasticsearch&size=0&terminate_after=1
当大小设置为0时,响应将不包含任何命中。hits.total将等于0,表示没有匹配的文档,或者大于0意味着至少有许多匹配查询的文档,匹配将提前终止。另外,如果查询提前终止,则在响应中设置terminated_early标志为true。
Query
查询元素在搜索请求体中允许使用Query DSL定义一个查询。
GET /_search
{
"query" : {
"term" : { "user" : "kimchy" }
}
}
From/Size
结果分页可以使用from 和 size 参数。from参数定义了您想要获取的第一个结果的偏移量。size参数允许你配置一个最大返回命中数量。 尽管 from 和 size 可以设置为请求参数,他们也可以设置在请求体中。from默认为0,size默认为10。
GET /_search
{
"from" : 0, "size" : 10,
"query" : {
"term" : { "user" : "kimchy" }
}
}
注意,from+szie不能超过index.max_result_window 索引设置,默认为10,000。查看Scroll 或 Search 后的API,以获得更有效的方法来进行深度滚动。
排序
允许对一到多个指定字段进行排序。每个排序也可以颠倒。这个排序是在一个字段级别上定义的,以一个特殊字段名_score来按分数排序,然后按索引顺序_doc排序。 假设以下索引映射:
PUT /my_index
{
"mappings": {
"my_type": {
"properties": {
"post_date": { "type": "date" },
"user": {
"type": "keyword"
},
"name": {
"type": "keyword"
},
"age": { "type": "integer" }
}
}
}
}
GET /my_index/my_type/_search
{
"sort" : [
{ "post_date" : {"order" : "asc"}},
"user",
{ "name" : "desc" },
{ "age" : "desc" },
"_score"
],
"query" : {
"term" : { "user" : "kimchy" }
}
}
除了作为最有效的排序顺序外,_doc没有实际的用例。因此,如果您不关心返回文档的顺序,那么您应该按照_doc排序。这在滚动时特别有用。
排序值
每个文档返回的排序值也作为响应的一部分返回。
排序方式
order 选项可以有以下值:
asc 升序排序
desc 降序排序
当基于_score排序顺序默认为desc,当按其他的排序时顺序默认为asc。
排序模式选项
Elasticsearch排序支持按数组或多字段。mode选项控制为排序其所属的文档选择的数组值。mode选项可以是一下值:
min 选择最小值
max 选择最大值
sum 将所有值的和作为排序值。只适用于基于数字的数组字段。
avg 将所有值的平均值作为排序值。只适用于基于数字的数组字段。
median 使用所有值的中值作为排序值。只适用于基于数字的数组字段。
排序模式使用样例
在下面的例子中,每个文档有多个价格。在这种情况下,结果将按每个文档的平均价格进行排序。
PUT /my_index/my_type/1?refresh
{
"product": "chocolate",
"price": [20, 4]
}
POST /_search
{
"query" : {
"term" : { "product" : "chocolate" }
},
"sort" : [
{"price" : {"order" : "asc", "mode" : "avg"}}
]
}
嵌套对象排序
Elasticsearch也支持多字段排序,其中存在一个或多个嵌套对象。嵌套字段排序的支持在已经存在的排序选项之上有以下参数:
nested_path 定义要排序的嵌套对象。实际的排序字段必须是这个嵌套对象内的一个直接字段。在嵌套字段排序时,该字段是强制性的。
nested_filter 一个过滤器,在嵌套路径内的内部对象应该匹配,以使其字段值被排序。常见的情况是在嵌套过滤器或查询中重复查询/过滤。默认情况下,没有任何nested_filter是活动的。
嵌套排序例子
在下面的示例中,offer是nested类型的一个字段。需要指定nested_path;否则,Elasticsearch不知道需要捕获嵌套级别排序值。
POST /_search
{
"query" : {
"term" : { "product" : "chocolate" }
},
"sort" : [
{
"offer.price" : {
"mode" : "avg",
"order" : "asc",
"nested_path" : "offer",
"nested_filter" : {
"term" : { "offer.color" : "blue" }
}
}
}
]
}
在按脚本排序并按geo距离排序时也支持嵌套排序。
缺失值
missing参数指定如何处理缺少字段的文档:missing值可以设置为_last、_first或自定义值(将用于丢失的文档作为排序值)。缺省值是_last。 实例:
GET /_search
{
"sort" : [
{ "price" : {"missing" : "_last"} }
],
"query" : {
"term" : { "product" : "chocolate" }
}
}
请注意 如果嵌套的内部对象与nested_filter不匹配,则使用缺失值。
忽略无映射字段
默认情况下,如果没有与字段关联的映射,搜索请求将会失败。unmapped_type选项允许忽略没有映射的字段并且不以这些字段排序。该参数的值用于确定要发出的排序值。下面是一个如何使用的例子:
GET /_search
{
"sort" : [
{ "price" : {"unmapped_type" : "long"} }
],
"query" : {
"term" : { "product" : "chocolate" }
}
}
如果查询的任何一个索引没有对应价格的映射,那么Elasticsearch将处理它为一个long类型的映射,这个索引中的所有文档都没有这个字段的值。
Geo 距离排序
允许通过_geo_distance排序。这是一个例子,假设 pin.location 是一个geo_point类型的字段。
GET /_search
{
"sort" : [
{
"_geo_distance" : {
"pin.location" : [-70, 40],
"order" : "asc",
"unit" : "km",
"mode" : "min",
"distance_type" : "arc"
}
}
],
"query" : {
"term" : { "user" : "kimchy" }
}
}
distance_type 如何计算距离。可以是arc(默认),或plane(速度快,但在长距离和接近两极的情况下是不准确的)。
mode 如果一个字段有几个geo点,该怎么办。默认情况下,当按升序排序和按降序排序的最长距离时,要考虑到最短的距离。支持值为min、max、中值和avg。
unit 用于计算排序值时使用的单位。默认是m(米)。
geo距离排序不支持可配置的缺失值:当文档没有用于远程计算的字段的值时,距离总是被认为等于Infinity 。