Elasticsearch7.2中文教程翻译(八): API约定

@高效码农  July 28, 2019

多个索引(跨索引)

大多数索引参数的api都支持跨多个索引执行,使用简单的test1、test2、test3表示法(或_all 对于所有索引)。它还支持通配符,例如:test or test or tet or test,以及“排除”(-)的能力,例如:test,-test3。

所有多索引api都支持以下url查询字符串参数:

  • ignore_unavailable:是否忽略不可用的索引
  • allow_no_indices: 当没有可用的索引时,是否正常;例如,如果foo指定了通配符表达式并且没有可用的索引foo,那么根据此设置,请求将失败。当指定或不指定索引时_all,此设置也适用。如果别名指向封闭索引,则此设置也适用于别名。
  • expand_wildcards:统配的对象,是open的索引,还是closed的索引

索引对日期的支持

日期索引解析使您可以搜索一系列时间序列索引,而不是搜索所有时间序列索引并过滤结果或维护别名。限制搜索的索引数可减少群集上的负载并提高执行性能。例如,如果您在日常日志中搜索错误,则可以使用日期数学名称模板将搜索限制为过去两天。

几乎所有具有index参数的API都支持index参数值中的日期。

日期数学索引名称采用以下形式:

<static_name{date_math_expr{date_format|time_zone}}>
  • static_name:索引名称的静态部分
  • date_math_expr: 一个动态date math表达式,可以动态计算时间
  • date_format: 可选的日期格式化参数。默认是YYYY.MM.dd
  • time_zone: 可选的时区参数。默认是utc

注意:小写和大写字母date_format。例如: mm表示分钟,而MM表示一年中的一个月。同样hh表示该1-12范围内的小时与 组合AM/PM,而HH表示0-23 24小时范围内的小时。

日期数学表达式与区域设置无关。因此,除了公历之外,不可能使用任何其他日历。

您必须将日期数学索引名称表达式括在尖括号内,并且所有特殊字符都应进行URI编码。例如:

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

通用选项

下面这些选项可以被应用到所有的REST API。

格式良好的结果

当在任何请求后面追加?pretty=true会使得返回格式良好的JSON(只限debug!!)。当设置为?format=yaml时结果将会是更可读的yaml格式。

人类可读的输出

统计返回的结果是一种适合人类阅读的格式(例如:"exists_time": "1h" 或者 "size": "1kb"),对于计算机是"exists_time_in_millis": 3600000 or "size_in_bytes": 1024。人类可读这个选项可以在查询字符串后添加?human=false来关闭,这个适合统计结果被某种监控工具来使用。同时这也是默认选项。

日期计算

大多数参数接收一个格式化后的日期值,例如gt和lt在范围查询里,或者from和to在日起范围聚合里。

表达式开始于一个锚点日期,可以是now或者以||结尾的日期字符串。这个锚点日期可以随意的追加一个或多个数学表达式组合:

  • +1h 增加1小时
  • -1d 减少1天
  • /d 四舍五入定位到最近的天

支持的时间单位有:

时间单位描述
y
M
w星期
d
h小时(12小时制)
H小时(24小时制)
m分钟
s

一些示例:

示例描述
now+1h当前时间增加1小时,使用毫秒解析
now+1h+1m当前时间增加1小时零1分钟,使用毫秒解析
now+1h/d当前时间增加1小时,四舍五入到最近的天
2015-01-01丨丨+1M/d2015-01-01增加1个月,四舍五入到最近的天

响应过滤

所有的REST API接受一个filter_path参数,它可以用来减少响应的返回字段。参数使用逗号分割并且使用点记法表示:

GET /_search?q=elasticsearch&filter_path=took,hits.hits._id,hits.hits._score

响应值:

{
  "took" : 3,
  "hits" : {
    "hits" : [
      {
        "_id" : "0",
        "_score" : 1.6375021
      }
    ]
  }
}

它也支持*通配符来匹配任何字段或者字段名字的一部分:

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

响应值:

{
  "metadata" : {
    "indices" : {
      "twitter": {"state": "open"}
    }
  }
}

**通配符可以在不知道准确字段路径的情况下进行匹配:

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

响应值:

{
  "routing_table": {
    "indices": {
      "twitter": {
        "shards": {
          "0": [{"state": "STARTED"}, {"state": "UNASSIGNED"}]
        }
      }
    }
  }
}

还可以使用-字符来排除一个或多个字段:

GET /_count?filter_path=-_shards

响应值:

{
  "count" : 5
}

包含和排斥过滤器可以混合使用:

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

响应值:

{
  "metadata" : {
    "indices" : {
      "index-1" : {"state" : "open"},
      "index-2" : {"state" : "open"},
      "index-3" : {"state" : "open"}
    }
  }
}

注意,有时elasticsearch会直接返回未加工的值,例如_source字段。你应该考虑组合已经存在的_source参数和filter_path参数:

POST /library/book?refresh
{"title": "Book #1", "rating": 200.1}
POST /library/book?refresh
{"title": "Book #2", "rating": 1.7}
POST /library/book?refresh
{"title": "Book #3", "rating": 0.1}
GET /_search?filter_path=hits.hits._source&_source=title&sort=rating:desc
{
  "hits" : {
    "hits" : [ {
      "_source":{"title":"Book #1"}
    }, {
      "_source":{"title":"Book #2"}
    }, {
      "_source":{"title":"Book #3"}
    } ]
  }
}

Flat设置

当flat_settings的值是true时,响应将会以flat格式返回:

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"
      }
    }
  }
}

默认flat_settings的值是false。

参数

Rest参数(当使用HTTP时,对应HTTP URL参数)按照约定使用下划线包装。

时间单位

当一个时间段需要被指定时,那么它的单位也必须被指定,比如2d代表2天。支持的单位有:

时间单位描述
d
h小时
m分钟
s
ms毫秒
micros微秒
anos纳秒

字节尺寸单位

有些参数是需要指定字节尺寸的。Elasticsearch支持的单位有:b、kb、mb、gb、tb、pb。

尺寸单位描述
b字节
kb千字节
mb兆字节
gb千兆字节
tb万亿字节
pb兆亿字节

简写单位数量

例如我们不需要写7000,而可以写7k,支持的乘数有:

乘数描述
k
m百万
g十亿
t
p千兆

距离单位
无论何处需要指定距离,例如地理距离中的distance参数,如果没有指定,则默认单位为米。距离可以用其他单位指定,例如或 (2英里)。"1km""2mi"

完整的单位清单如下:

单位简写
MileMilemi or miles
Yardyd or yards
Feetft or feet
Inchin or inch
Kilometerkm or kilometers
Meterm or meters
Centimetercm or centimeters
Millimetermm or millimeters
Nautical mileNM, nmi, or nauticalmilesmi or miles

模糊匹配
模糊匹配 对待 “模糊” 相似的两个词似乎是同一个词。首先,我们需要对我们所说的 模糊性 进行定义。

在1965年,Vladimir Levenshtein 开发出了 Levenshtein distance, 用来度量从一个单词转换到另一个单词需要多少次单字符编辑。他提出了三种类型的单字符编辑:

  • 一个字符 替换 另一个字符: _f_ox -> _b_ox
  • 插入 一个新的字符:sic -> sic_k_
  • 删除 一个字符:b_l_ack -> back

Frederick Damerau 后来在这些操作基础上做了一个扩展:

  • 相邻两个字符的 换位 : _st_ar -> _ts_ar

举个例子,将单词 bieber 转换成 beaver 需要下面几个步骤:

1、把 b 替换成 v :bie_b_er → bie_v_er

2、把 i 替换成 a :b_i_ever → b_a_ ever

3、把 e 和 a 进行换位:b_ae_ver → b_ea_ver

这三个步骤表示 Damerau-Levenshtein edit distance 编辑距离为 3 。

显然,从 beaver 转换成 bieber 是一个很长的过程—他们相距甚远而不能视为一个简单的拼写错误。 Damerau 发现 80% 的拼写错误编辑距离为 1 。换句话说, 80% 的拼写错误可以对原始字符串用 单次编辑 进行修正。

Elasticsearch 指定了 fuzziness 参数支持对最大编辑距离的配置,默认为 2 。

当然,单次编辑对字符串的影响取决于字符串的长度。对单词 hat 两次编辑能够产生 mad , 所以对一个只有 3 个字符长度的字符串允许两次编辑显然太多了。 fuzziness 参数可以被设置为 AUTO ,这将导致以下的最大编辑距离:

  • 字符串只有 1 到 2 个字符时是 0
  • 字符串有 3 、 4 或者 5 个字符时是 1
  • 字符串大于 5 个字符时是 2

当然,你可能会发现编辑距离 2 仍然是太多了,返回的结果似乎并不相关。 把最大 fuzziness 设置为 1 ,你可以得到更好的结果和更好的性能。

启用堆栈跟踪

默认的当一个请求返回一个错误时Elasticsearch不会输出错误的堆栈跟踪信息。你可以通过追加error_trace=true来启用堆栈跟踪。例如:

POST /twitter/_search?size=surprise_me&error_trace=true

返回结果会像这样

{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "Failed to parse int parameter [size] with value [surprise_me]",
        "stack_trace": "Failed to parse int parameter [size] with value [surprise_me]]; nested: IllegalArgumentException..."
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "Failed to parse int parameter [size] with value [surprise_me]",
    "stack_trace": "java.lang.IllegalArgumentException: Failed to parse int parameter [size] with value [surprise_me]\n    at org.elasticsearch.rest.RestRequest.paramAsInt(RestRequest.java:175)...",
    "caused_by": {
      "type": "number_format_exception",
      "reason": "For input string: \"surprise_me\"",
      "stack_trace": "java.lang.NumberFormatException: For input string: \"surprise_me\"\n    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)..."
    }
  },
  "status": 400
}

查询字符串中的请求主体
对于不接受非post请求的请求体的库,可以将请求体作为源查询字符串参数传递。当使用此方法时,source_content_type参数还应该与指示源格式的媒体类型值一起传递,例如application/json。

内容类型的需求
在请求体中发送的内容的类型必须使用content - type头指定。此头的值必须映射到API支持的受支持格式之一。大多数api支持JSON、YAML、CBOR和SMILE。批量和多搜索api支持NDJSON、JSON和SMILE;其他类型将导致错误响应。

此外,在使用源查询字符串参数时,必须使用source_content_type查询字符串参数指定内容类型。

基于URL的访问控制

许多用户使用一个代理进行基于URL的访问控制,来保护对Elasticsearch的索引访问。对于multi-search, multi-get 和 bulk请求,用户可以选择在URL里指定一个索引或者每个单独的请求体里。这使得基于URL的访问控制非常有挑战性。

为了防止用户重新URL里指定的索引,添加下面的设置到config.yml文件:

rest.action.multi.allow_explicit_index: false

默认值是true,当设置为false时,Elasticsearch将会拒绝一个在请求体中指定索引的请求。



添加新评论