8. ES API规约

8.1 多索引

 通常可以用test1test2test3这样的形式(或者用_all表示所有索引),当然它也支持通配符(如:test**test或者te*t),排除某些索引可以用-符号,比如test*,-test3(匹配所有的test开头的索引但不包括test3),所有的多索引API都支持下面的url查询字符串参数:

  • ignore_unavailable:如果指定索引不存在或者是封闭索引,这个参数可以控制这些索引是否可以被忽略,可以指定为truefalse
  • allow_no_indices:如果通配符索引表达式没有匹配到具体索引,这个参数可以控制是否失败,可以指定为truefalse,不如foo*,但是却没有以foo开头的索引,据此可以设置为失败,这个参数同样适用于_all*或者像test这样具体的某个索引,如果一个别名指向封闭索引,则此设置也适用于别名;
  • expand_wildcards:控制通配符索引表达式可以匹配到哪种具体索引,如果指定了open,则通配符表达式只能匹配到打开的索引,如果指定了closed,则通配符表达式仅能匹配到封闭的索引,它还能同时指定为openclosed两个值。

8.2 索引名对日期和数学的支持

 日期、数学索引名称解析可以让我们搜索一系列时间序列索引,而不是搜索所有时间序列索引并过滤结果或维护别名。限制搜索的索引数可以减少集群上的负载并提高执行性能。比如,在日志中搜索错误,就可以使用日期、数学名称模板将搜索限制为过去两天。几乎所有的API都有index参数,index参数可以支持日期和数学,大概的格式如下:

<static_name{date_math_expr{date_format|time_zone}}>

对上述的语句中的几个参数做如下说明:

  • static_name:名称的静态文本部分;
  • date_math_expr:动态日期、数学数学表达式(动态计算日期);
  • date_format:呈现计算日期的格式(可选),默认是YYYY.MM.dd格式;
  • time_zone:时区(可选),默认是UTC

下面是一个简单的例子:

# GET /<logstash-{now/d}>/_search
GET /%3Clogstash-%7Bnow%2Fd%7D%3E/_search
{
  "query" : {
    "match": {
      "test": "data"
    }
  }
}

【注意】

日期数学索引名称表达式必须包在尖括号中,并且所有特殊字符都应该是URI编码的,下面是具体的参照表:

特殊字符

URI编码

<

%3C

>

%3E

/

%2F

{

%7B

}

%7D

|

%7C

+

%2B

:

%3A

,

%2C

下面是对2024年3月22日中午(UTC)不同参数对应的解析结果:

表达式

解析结果

<logstash-{now/d}>

logstash-2024.03.22

<logstash-{now/M}>

logstash-2024.03.01

<logstash-{now/M{YYYY.MM}}>

logstash-2024.03

<logstash-{now/M-1M{YYYY.MM}}>

logstash-2024.02

<logstash-{now/d{YYYY.MM.dd|+12:00}}>

logstash-2024.03.23

【注意】如果要在索引名称模板的静态部分中使用字符{},需要用反斜杠\来转义,如:

<elastic\\{ON\\}-{now/M}>解析为elastic{ON}-2024.03.01

以下示例显示搜索请求,该搜索请求搜索过去三天的Logstash索引,假设索引使用默认的Logstash索引名称格式logstash-YYYY.MM.dd,那么如下:

# GET /<logstash-{now/d-2d}>,<logstash-{now/d-1d}>,<logstash-{now/d}>/_search
GET /%3Clogstash-%7Bnow%2Fd-2d%7D%3E%2C%3Clogstash-%7Bnow%2Fd-1d%7D%3E%2C%3Clogstash-%7Bnow%2Fd%7D%3E/_search
{
  "query" : {
    "match": {
      "test": "data"
    }
  }
}

8.3 常规选项

 下面的这些选项适用于所有的REST APIs,不局限于ES。

8.3.1 美化返回结果

 之前有提过这个参数,可以在任何请求后面追加?pretty=true,任何JSON格式的返回结果都将会被格式化(美化),一般只在调试的时候使用!另一个相类似的是?format=yaml参数可以返回更加易读的yaml格式的结果。

8.3.2 更易阅读的输出

 有些返回结果更适用于人(如"exists_time": "1h""size": "1kb"),有些返回结形式则更适合机器(如"exists_time_in_millis": 3600000"size_in_bytes": 1024),适合人的阅读方式在请求时追加?human=false将其关闭,当统计结果被监控工具(机器)消耗时,这是有意义的,而不是用于人类消费,这个选项默认是flase

8.3.3 日期数字

 大部分接受格式化日期值参数都是能解析日期数值的,比如range查询中的gtlt以及daterange聚合中的fromto。它可以是任意的固定好的日期(原文是anchor date),可以是now或者以||结尾的日期字符串,除此之外固定日期后面可以跟下面的一个或多个表达式:

  • +1h:加1小时;
  • -1d:减1小时;
  • /d:四舍五入到最近的一天;

ES支持的时间单位也和持续时间的单位也有点不太一样,ES只支持年(y)月(M)日(d)周(w)时(H)分(m)秒(s),下面有2个案例(假设当前时间为2001-01-01 12:00:00):

  • now-1h/d解析结果为2001-01-01 00:00:00
  • 2001.02.01\|\|+1M/d解析结果为2001-03-01 00:00:00
8.3.4 过滤返回结果

 所有的REST APIS都可以接受一个减少ES返回值的过滤参数filter_path,这个参数接受一系列使用.表示的过滤器(多个过滤器之间使用,分隔),比如:

GET /_search?q=elasticsearch&filter_path=took,_shards.total,hits

看结果:

{
  "took": 3,
  "_shards": {
    "total": 15
  },
  "hits": {
    "total": 0,
    "max_score": null,
    "hits": []
  }
}

直接将took_shards.totalhits这三块过滤出来然后将过滤的东西返回给我们,注意这里不是将指定的filter_path过滤掉,而是将它显示出来(总感觉这里“过滤”这个词用的怪怪的,对吧),filter_path也是可以使用通配符*匹配任何字段或者字段名的一部分,比如下面的:

GET /_cluster/state?filter_path=metadata.indices.*.stat*

返回的结果如下:

{
  "metadata": {
    "indices": {
      ".kibana": {
        "state": "open"
      },
      ".monitoring-kibana-6-2018.09.06": {
        "state": "open"
      },
      ".monitoring-kibana-6-2018.09.05": {
        "state": "open"
      },
      ".monitoring-es-6-2018.09.05": {
        "state": "open"
      },
      "bank": {
        "state": "open"
      },
      "customer": {
        "state": "open"
      },
      ".monitoring-es-6-2018.09.06": {
        "state": "open"
      }
    }
  }
}

另外**通配符可用于包括字段而不知道字段的确切路径的匹配,比如使用请求返回每个片段的Lucene版本:

GET /_cluster/state?filter_path=routing_table.indices.**.state

在过滤的时候也可以使用-符号来排除一些东西,如排除掉命中结果:

GET /_search?q=elasticsearch&filter_path=-hits

为了过滤复杂条件,包含和排他过滤器可以组合在同一表达式中。在这种情况下,将首先应用排他过滤器,并使用包含过滤器再次过滤结果:

GET /_cluster/state?filter_path=metadata.indices.*.state,-metadata.indices.logstash-*

8.3.5 标识设置

 这个参数(默认为false)主要用于获取设置参数的返回形式,当flat_settings=true时,设置将以平面格式(flat format)的返回,比如下面的:

GET twitter/_settings?flat_settings=true

// 结果如下
{
  "twitter" : {
    "settings": {
      "index.number_of_replicas": "1",
      "index.number_of_shards": "1",
      "index.creation_date": "1474389951325",
      "index.uuid": "n6gzFZTgS664GUfx0Xrpjw",
      "index.version.created": ...,
      "index.provided_name" : "twitter"
    }
  }
}

flat_settings=false时,设置将会以更加人类可读的形式返回:

GET twitter/_settings?flat_settings=false

// 结果如下
{
  "twitter" : {
    "settings" : {
      "index" : {
        "number_of_replicas": "1",
        "number_of_shards": "1",
        "creation_date": "1474389951325",
        "uuid": "n6gzFZTgS664GUfx0Xrpjw",
        "version": {
          "created": ...
        },
        "provided_name" : "twitter"
      }
    }
  }
}
8.3.6 关于一些单位

时间单位:

对于持续性时间(比如超时时间timeout参数)必须指定单位,ES支持的时间单位如下:

d

h

小时

m

分钟

s

ms

毫秒

micros

微秒

nanos

纳秒

数据字节单位:

对于数据字节大小必须要指定,比如在设置缓冲区大小。注意,这些单位都是使用1024的幂,即1kb=1024b(复杂化了……),主要就单位有:

b

字节

kb

千字节

mb

兆字节

gb

千兆字节

tb

T

pb

P

无单位数的单位:

即没有像“字节”或“赫兹”或“米”或“长吨”这样的“单位”,如果这些数很大,打印的时候就用10m代替10,000、用7k代替7,000,而87仍会打印87,主要支持的单位有:

``

Single

k

Kilo

m

Mega

g

Giga

t

Tera

p

Peta

距离单位:

即距离单位,比如使用distance参数时,支持的单位有:

英里

mi or miles

yd or yards

英尺

ft or feet

英寸

in or inch

公里

km or kilometers

m or meters

厘米

cm or centimeters

毫米

mm or millimeters

海里

NM, nmi or nauticalmiles

8.3.7 基于一个URL的访问控制

 许多用户使用代理和基于url的访问控制安全访问Elasticsearch索引,多搜索、多获取和批处理请求,用户可以在URL请求体中指定索引的选择和每个请求,使得基于URL的访问控制面对挑战,为了避免用户在URL已经指定的索引,需要在elasticsearch.yml文件中添加如下配置:rest.action.multi.allow_explicit_index: false,这个配置的默认值是true,但是设置为false,ES将不会接受请求体中带指定索引的请求。