Elasticsearch:ES|QL 查询语言简介

警告:此功能处于技术预览阶段,可能会在未来版本中更改或删除。 Elastic 将尽最大努力解决任何问题,但技术预览版中的功能不受官方 GA 功能的支持 SLA 的约束。在目前的 Elastic Stack 8.10 中此功能还没有提供。

Elasticsearch 查询语言 (ES|QL) 是一种支持迭代探索数据的查询语言。

ES|QL 查询由一系列由管道分隔的命令组成。 每个查询都以源命令(FROM, ROW, SHOW <item>)开始。 源命令会生成一个表,通常包含来自 Elasticsearch 的数据。

源命令后面可以跟一个或多个处理命令。 处理命令通过添加、删除或更改行和列来更改输入表。

你可以链接处理命令,并用竖线字符分隔:|。 每个处理命令都作用于前一个命令的输出表。

查询的结果是最终处理命令生成的表。

运行 ES|QL 查询

ES|QL API

使用 _query 端点运行 ES|QL 查询:

POST /_query
{
  "query": """
    FROM library
    | EVAL year = DATE_TRUNC(1 YEARS, release_date)
    | STATS MAX(page_count) BY year
    | SORT year
    | LIMIT 5
  """
}

结果按行返回:

{
  "columns": [
    { "name": "MAX(page_count)", "type": "integer"},
    { "name": "year"           , "type": "date"}
  ],
  "values": [
    [268, "1932-01-01T00:00:00.000Z"],
    [224, "1951-01-01T00:00:00.000Z"],
    [227, "1953-01-01T00:00:00.000Z"],
    [335, "1959-01-01T00:00:00.000Z"],
    [604, "1965-01-01T00:00:00.000Z"]
  ]
}

默认情况下,结果以 JSON 形式返回。 要返回文本、CSV 或 TSV 格式的结果,请使用 format 参数:

POST /_query?format=txt
{
  "query": """
    FROM library
    | EVAL year = DATE_TRUNC(1 YEARS, release_date)
    | STATS MAX(page_count) BY year
    | SORT year
    | LIMIT 5
  """
}

上述查询的 LIMIT 命令将结果限制为 5 行。

如果未指定,LIMIT 默认为 500。无论 LIMIT 值如何,单个查询都不会返回超过 10,000 行。

Kibana

在 Discover 中使用 ES|QL 探索数据集。 从数据视图下拉列表中,选择 Try ES|QL 开始。

注意:Discover 和 Lens 中的 ES|QL 查询受时间过滤器选择的时间范围的限制。

限制

  • ES|QL 目前支持以下字段类型:
    • alias
    • boolean
    • data
    • double(float、half_float、scaled_float 表示为 double)
    • ip
    • keyword 系列,包括 keyword、constant_keyword 和 wildcard
    • int(short 和 byte 均表示为 int)
    • long
    • null
    • text
    • unsigned_long
    • version
  • 无论 LIMIT 命令的值如何,单个查询都不会返回超过 10,000 行。

ES|QL 语法参考

基本语法

ES|QL 查询由一个源命令组成,后跟一系列可选的处理命令,并用竖线字符分隔:|。 例如:

source-command
| processing-command1
| processing-command2

查询的结果是最终处理命令生成的表。

为了便于阅读,本文档将每个处理命令放在一个新行中。 但是,你可以将 ES|QL 查询编写为一行。 以下查询与前一个查询相同:

source-command | processing-command1 | processing-command2

注释

ES|QL 使用 C++ 风格的注释:

  • 双斜杠 // 用于单行注释

  • /* 和 */ 用于块注释

    // Query the employees index
    FROM employees
    | WHERE height > 2

    FROM /* Query the employees index */ employees
    | WHERE height > 2

    FROM employees
    /* Query the

    • employees
    • index */
      | WHERE height > 2

运算符

支持以下二进制比较运算符:

  • 平等:==
  • 不等式:!=
  • 小于:<
  • 小于或等于:<=
  • 大于:>
  • 大于或等于:>=

IN 运算符允许测试字段或表达式是否等于文字 (literals)、字段 (fields) 或表达式 (expressions) 列表中的元素:

ROW a = 1, b = 4, c = 3
| WHERE c-a IN (3, b / 2, a)

对于使用通配符或正则表达式的字符串比较,请使用 LIKE 或 RLIKE:

  • 使用 LIKE 来匹配使用通配符的字符串。 支持以下通配符:

    • * 匹配零个或多个字符。

    • ? 匹配一个字符。

      FROM employees
      | WHERE first_name LIKE "?b*"
      | KEEP first_name, last_name

  • 使用 RLIKE 使用正则表达式来匹配字符串:

    FROM employees
    | WHERE first_name RLIKE ".leja.*"
    | KEEP first_name, last_name

支持以下布尔运算符:

  • AND
  • OR
  • NOT

Predicates - 谓词

对于 NULL 比较,请使用 IS NULL 和 IS NOT NULL 谓词:

FROM employees
| WHERE birth_date IS NULL
| KEEP first_name, last_name
| SORT first_name
| LIMIT 3
first_name:keyword last_name:keyword
Basil Tramer
Florian Syrotiuk
Lucien Rosenbaum
FROM employees
| WHERE is_rehired IS NOT NULL
| STATS count(emp_no)
count(emp_no):long
84

Timespan literals

日期时间间隔和时间跨度可以使用时间跨度文字来表示。 时间跨度文字是数字和限定符的组合。 支持这些限定符:

  • millisecond/milliseconds
  • second/seconds
  • minute/minutes
  • hour/hours
  • day/days
  • week/weeks
  • month/months
  • year/years

时间跨度文字对空格不敏感。 这些表达式都是有效的:

  • 1day
  • 1 day
  • 1 day

ES|QL 源命令

ES|QL 源命令会生成一个表,通常包含来自 Elasticsearch 的数据。

ES|QL 支持以下源命令:

  • FROM
  • ROW
  • SHOW <item>

FROM

FROM source 命令返回一个表,其中包含来自数据流、索引或别名的最多 10,000 个文档。 结果表中的每一行代表一个文档。 每列对应一个字段,并且可以通过该字段的名称进行访问。

FROM employees

你可以使用 date math 来引用索引、别名和数据流。 这对于时间序列数据很有用,例如访问今天的索引:

FROM <logs-{now/d}>

使用逗号分隔的列表或通配符查询多个数据流、索引或别名:

FROM employees-00001,other-employees-*

使用 METADATA 指令启用元数据字段:

FROM employees [METADATA _id]

ROW

ROW source 命令生成一行,其中包含一个或多个列,这些列具有你指定的值。 这对于测试很有用。

ROW a = 1, b = "two", c = null
a:integer b:keyword c:null
1 "two" null

使用方括号创建多值列:

ROW a = [2, 1]

ROW 支持使用函数

ROW a = ROUND(1.23, 0)

SHOW <item>

SHOW <item> source 命令返回有关部署及其功能的信息:

  • 使用 SHOW INFO 返回部署的版本、构建日期和哈希值。
  • 使用 SHOW FUNCTIONS 返回所有支持的函数的列表以及每个函数的概要。

ES|QL 处理命令

ES|QL 处理命令通过添加、删除或更改行和列来更改输入表。

ES|QL 支持这些处理命令:

  • DISSECT
  • DROP
  • ENRICH
  • EVAL
  • GROK
  • KEEP
  • LIMIT
  • MV_EXPAND
  • RENAME
  • SORT
  • STATS ... BY
  • WHERE

DISSECT

DISSECT 使你能够从字符串中提取结构化数据。 DISSECT 将字符串与基于分隔符的模式进行匹配,并将指定的键提取为列。

有关 dissect 模式的语法,请参阅 dissect processor 文档

ROW a = "1953-01-23T12:15:00Z - some text - 127.0.0.1;"
| DISSECT a "%{Y}-%{M}-%{D}T%{h}:%{m}:%{s}Z - %{msg} - %{ip};"
| KEEP Y, M, D, h, m, s, msg, ip
Y:keyword M:keyword D:keyword h:keyword m:keyword s:keyword msg:keyword ip:keyword
1953 01 23 12 15 00

DROP

使用 DROP 删除列:

FROM employees
| DROP height

你可以使用通配符删除名称与模式匹配的所有列,而不是按名称指定每个列:

FROM employees
| DROP height*

ENRICH

你可以使用 ENRICH 将现有索引中的数据添加到传入记录中。 它与 ingest enrich 类似,但它在查询时工作。

ROW language_code = "1"
| ENRICH languages_policy
language_code:keyword language_name:keyword
1 English

ENRICH 需要执行 enrich policy。 丰富策略定义了一个匹配字段(关键字段)和一组丰富字段。

ENRICH 将根据匹配字段值在 enrich index 中查找记录。 输入数据集中的匹配键可以使用 ON <field-name> 定义; 如果未指定,则将在与 enrich policy 中定义的匹配字段同名的字段上执行匹配。

ROW a = "1"
| ENRICH languages_policy ON a
a:keyword language_name:keyword
1 English

你可以使用 WITH <field1>, <field2>... 语法指定必须将哪些属性(在策略中定义为丰富字段的属性之间)添加到结果中。

ROW a = "1"
| ENRICH languages_policy ON a WITH language_name
a:keyword language_name:keyword
1 English

还可以使用 WITH new_name=<field1> 重命名属性

ROW a = "1"
| ENRICH languages_policy ON a WITH name = language_name
a:keyword name:keyword
1 English

默认情况下(如果未定义 WITH),ENRICH 会将 enrich policy 中定义的所有丰富字段添加到结果中。

如果发生名称冲突,新创建的字段将覆盖现有字段。

EVAL

EVAL 使你能够附加新列:

FROM employees
| SORT emp_no
| KEEP first_name, last_name, height
| EVAL height_feet = height * 3.281, height_cm = height * 100
first_name:keyword last_name:keyword height:double height_feet:double height_cm:double
Georgi Facello 2.03 6.66043 202.99999999999997

如果指定的列已存在,则现有列将被删除,新列将追加到表中:

FROM employees
| SORT emp_no
| KEEP first_name, last_name, height
| EVAL height = height * 3.281
first_name:keyword last_name:keyword height:double
Georgi Facello 6.66043

Functions

EVAL 支持各种计算值的函数。 请参阅函数了解更多信息。

GROK

GROK 使你能够从字符串中提取结构化数据。 GROK 基于正则表达式将字符串与模式进行匹配,并将指定的模式提取为列。

有关 grok 模式的语法,请参阅 grok 处理器文档

例如:

ROW a = "1953-01-23T12:15:00Z 127.0.0.1 some.email@foo.com 42"
| GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}"
| KEEP date, ip, email, num
date:keyword ip:keyword email:keyword num:integer
1953-01-23T12:15:00Z 127.0.0.1 some.email@foo.com 42

KEEP

KEEP 命令使你能够指定返回哪些列以及返回它们的顺序。

要限制返回的列,请使用以逗号分隔的列名称列表。 列按指定顺序返回:

FROM employees
| KEEP emp_no, first_name, last_name, height
emp_no:integer first_name:keyword last_name:keyword height:double
10001 Georgi Facello 2.03
10002 Bezalel Simmel 2.08
10003 Parto Bamford 1.83
10004 Chirstian Koblick 1.78
10005 Kyoichi Maliniak 2.05

你可以使用通配符返回名称与模式匹配的所有列,而不是按名称指定每个列:

FROM employees
| KEEP h*

星号通配符 (*) 本身会转换为与其他参数不匹配的所有列。 此查询将首先返回名称以 h 开头的所有列,然后是所有其他列:

FROM employees
| KEEP h*, *

LIMIT

LIMIT 处理命令使你能够限制行数:

FROM employees
| SORT emp_no ASC
| LIMIT 5

如果未指定,LIMIT 默认为 500。无论 LIMIT 值如何,单个查询都不会返回超过 10,000 行。

MV_EXPAND

MV_EXPAND 处理命令将多值(multivalued)字段扩展为每个值一行,并复制其他字段:

ROW a=[1,2,3], b="b", j=["a","b"]
| MV_EXPAND a
a:integer b:keyword j:keyword
1 b ["a", "b"]
2 b ["a", "b"]
3 b ["a", "b"]

RENAME

使用 RENAME 使用以下语法重命名列:

RENAME <old-name> AS <new-name>

例如:

FROM employees
| KEEP first_name, last_name, still_hired
| RENAME  still_hired AS employed

如果具有新名称的列已存在,它将被新列替换。

可以使用单个 RENAME 命令重命名多个列:

FROM employees
| KEEP first_name, last_name
| RENAME first_name AS fn, last_name AS ln

SORT

使用 SORT 命令对一个或多个字段上的行进行排序:

FROM employees
| KEEP first_name, last_name, height
| SORT height

默认排序顺序为升序。 使用 ASC 或 DESC 设置显式排序顺序:

FROM employees
| KEEP first_name, last_name, height
| SORT height DESC

具有相同排序键的两行被视为相等。 你可以提供额外的排序表达式来分裁定:

FROM employees
| KEEP first_name, last_name, height
| SORT height DESC, first_name ASC

null values

默认情况下,null 值被视为大于任何其他值。 对于升序排序,空值排在最后,而对于降序排序,空值排在最前面。 你可以通过提供 NULLS FIRST 或 NULLS LAST 来更改它:

FROM employees
| KEEP first_name, last_name, height
| SORT first_name ASC NULLS FIRST

STATS ... BY

使用 STATS ... BY 根据公共值对行进行分组,并计算分组行上的一个或多个聚合值。

FROM employees
| STATS count = COUNT(emp_no) BY languages
| SORT languages
count:long languages:integer
15 1
19 2
17 3
18 4
21 5
10 null

如果省略 BY,则输出表仅包含一行,并且聚合应用于整个数据集:

FROM employees
| STATS avg_lang = AVG(languages)
avg_lang:double
3.1222222222222222

可以计算多个值:

FROM employees
| STATS avg_lang = AVG(languages), max_lang = MAX(languages)

还可以按多个值进行分组(仅支持 long 字段和 keyword 族字段):

FROM employees
| EVAL hired = DATE_FORMAT("YYYY", hire_date)
| STATS avg_salary = AVG(salary) BY hired, languages.long
| EVAL avg_salary = ROUND(avg_salary)
| SORT hired, languages.long

支持以下聚合函数:

WHERE

使用 WHERE 生成一个表,其中包含输入表中所提供的条件评估为 true 的所有行:

FROM employees
| KEEP first_name, last_name, still_hired
| WHERE still_hired == true

如果 still_hired 是布尔字段,则可以简化为:

FROM employees
| KEEP first_name, last_name, still_hired
| WHERE still_hired

运算符

有关支持的运算符的概述,请参阅上面的运算符部分。

函数

WHERE 支持各种计算值的函数。 请参阅函数了解更多信息。

FROM employees
| KEEP first_name, last_name, height
| WHERE length(first_name) < 4
相关推荐
打鱼又晒网30 分钟前
【MySQL】数据库精细化讲解:内置函数知识穿透与深度学习解析
数据库·mysql
大白要努力!35 分钟前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
在下不上天1 小时前
Flume日志采集系统的部署,实现flume负载均衡,flume故障恢复
大数据·开发语言·python
tatasix1 小时前
MySQL UPDATE语句执行链路解析
数据库·mysql
南城花随雪。2 小时前
硬盘(HDD)与固态硬盘(SSD)详细解读
数据库
儿时可乖了2 小时前
使用 Java 操作 SQLite 数据库
java·数据库·sqlite
懒是一种态度2 小时前
Golang 调用 mongodb 的函数
数据库·mongodb·golang
天海华兮2 小时前
mysql 去重 补全 取出重复 变量 函数 和存储过程
数据库·mysql
智慧化智能化数字化方案2 小时前
华为IPD流程管理体系L1至L5最佳实践-解读
大数据·华为
gma9993 小时前
Etcd 框架
数据库·etcd