多个索引(跨索引)

大多数索引参数的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/d 2015-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”

完整的单位清单如下:

单位 简写
MileMile mi or miles
Yard yd or yards
Feet ft or feet
Inch in or inch
Kilometer km or kilometers
Meter m or meters
Centimeter cm or centimeters
Millimeter mm or millimeters
Nautical mile NM, 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将会拒绝一个在请求体中指定索引的请求。