Elasticsearch:ES|QL 查询语言简介

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

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

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

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

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

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

运行 ES|QL 查询

ES|QL API

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

python 复制代码
1.  POST /_query
2.  {
3.    "query": """
4.      FROM library
5.      | EVAL year = DATE_TRUNC(1 YEARS, release_date)
6.      | STATS MAX(page_count) BY year
7.      | SORT year
8.      | LIMIT 5
9.    """
10.  }

结果按行返回:

less 复制代码
1.  {
2.    "columns": [3.      { "name": "MAX(page_count)", "type": "integer"},4.      { "name": "year"           , "type": "date"}5.    ],
6.    "values": [7.      [268, "1932-01-01T00:00:00.000Z"],
8.      [224, "1951-01-01T00:00:00.000Z"],
9.      [227, "1953-01-01T00:00:00.000Z"],
10.      [335, "1959-01-01T00:00:00.000Z"],
11.      [604, "1965-01-01T00:00:00.000Z"]
12.    ]
13.  }

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

python 复制代码
1.  POST /_query?format=txt
2.  {
3.    "query": """
4.      FROM library
5.      | EVAL year = DATE_TRUNC(1 YEARS, release_date)
6.      | STATS MAX(page_count) BY year
7.      | SORT year
8.      | LIMIT 5
9.    """
10.  }

上述查询的 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 查询由一个源命令组成,后跟一系列可选的处理命令,并用竖线字符分隔:|。 例如:

markdown 复制代码
1.  source-command
2.  | processing-command1
3.  | processing-command2

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

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

source-command | processing-command1 | processing-command2

注释

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

  • 双斜杠 // 用于单行注释
  • /* 和 */ 用于块注释
arduino 复制代码
1.  // Query the employees index
2.  FROM employees
3.  | WHERE height > 2
css 复制代码
1.  FROM /* Query the employees index */ employees
2.  | WHERE height > 2
markdown 复制代码
1.  FROM employees
2.  /* Query the
3.   * employees
4.   * index */
5.  | WHERE height > 2

运算符

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

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

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

css 复制代码
1.  ROW a = 1, b = 4, c = 3
2.  | WHERE c-a IN (3, b / 2, a)

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

  • 使用 LIKE 来匹配使用通配符的字符串。 支持以下通配符:
    *
    • 匹配零个或多个字符。
    • ? 匹配一个字符。
sql 复制代码
1.  FROM employees
2.  | WHERE first_name LIKE "?b*"
3.  | KEEP first_name, last_name
  • 使用 RLIKE 使用正则表达式来匹配字符串:
sql 复制代码
1.  FROM employees
2.  | WHERE first_name RLIKE ".leja.*"
3.  | KEEP first_name, last_name

支持以下布尔运算符:

  • AND
  • OR
  • NOT

Predicates - 谓词

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

markdown 复制代码
1.  FROM employees
2.  | WHERE birth_date IS NULL
3.  | KEEP first_name, last_name
4.  | SORT first_name
5.  | LIMIT 3
first_name:keyword last_name:keyword
Basil Tramer
Florian Syrotiuk
Lucien Rosenbaum
sql 复制代码
1.  FROM employees
2.  | WHERE is_rehired IS NOT NULL
3.  | 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

FROM

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

css 复制代码
FROM employees

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

bash 复制代码
FROM <logs-{now/d}>

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

css 复制代码
FROM employees-00001,other-employees-*

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

css 复制代码
FROM employees [METADATA _id]

ROW

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

ini 复制代码
ROW a = 1, b = "two", c = null 
a:integer b:keyword c:null
1 "two" null

使用方括号创建多值列:

css 复制代码
ROW a = [2, 1]

ROW 支持使用函数

ini 复制代码
ROW a = ROUND(1.23, 0)

SHOW

SHOW 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 文档

perl 复制代码
1.  ROW a = "1953-01-23T12:15:00Z - some text - 127.0.0.1;"
2.  | DISSECT a "%{Y}-%{M}-%{D}T%{h}:%{m}:%{s}Z - %{msg} - %{ip};"
3.  | 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 删除列:

css 复制代码
1.  FROM employees
2.  | DROP height

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

css 复制代码
1.  FROM employees
2.  | DROP height*

ENRICH

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

ini 复制代码
1.  ROW language_code = "1"
2.  | ENRICH languages_policy
language_code:keyword language_name:keyword
1 English

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

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

ini 复制代码
1.  ROW a = "1"
2.  | ENRICH languages_policy ON a
a:keyword language_name:keyword
1 English

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

ini 复制代码
1.  ROW a = "1"
2.  | ENRICH languages_policy ON a WITH language_name
a:keyword language_name:keyword
1 English

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

ini 复制代码
1.  ROW a = "1"
2.  | ENRICH languages_policy ON a WITH name = language_name
a:keyword name:keyword
1 English

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

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

EVAL

EVAL 使你能够附加新列:

css 复制代码
1.  FROM employees
2.  | SORT emp_no
3.  | KEEP first_name, last_name, height
4.  | 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

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

css 复制代码
1.  FROM employees
2.  | SORT emp_no
3.  | KEEP first_name, last_name, height
4.  | EVAL height = height * 3.281
first_name:keyword last_name:keyword height:double
Georgi Facello 6.66043

Functions

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

GROK

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

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

例如:

css 复制代码
1.  ROW a = "1953-01-23T12:15:00Z 127.0.0.1 some.email@foo.com 42"
2.  | GROK a "%{TIMESTAMP_ISO8601:date} %{IP:ip} %{EMAILADDRESS:email} %{NUMBER:num:int}"
3.  | 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 命令使你能够指定返回哪些列以及返回它们的顺序。

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

css 复制代码
1.  FROM employees
2.  | 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

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

markdown 复制代码
1.  FROM employees
2.  | KEEP h*

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

markdown 复制代码
1.  FROM employees
2.  | KEEP h*, *

LIMIT

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

markdown 复制代码
1.  FROM employees
2.  | SORT emp_no ASC
3.  | LIMIT 5

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

MV_EXPAND

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

css 复制代码
1.  ROW a=[1,2,3], b="b", j=["a","b"]
2.  | MV_EXPAND a
a:integer b:keyword j:keyword
1 b ["a", "b"]
2 b ["a", "b"]
3 b ["a", "b"]

RENAME

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

sql 复制代码
RENAME <old-name> AS <new-name>

例如:

markdown 复制代码
1.  FROM employees
2.  | KEEP first_name, last_name, still_hired
3.  | RENAME  still_hired AS employed

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

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

markdown 复制代码
1.  FROM employees
2.  | KEEP first_name, last_name
3.  | RENAME first_name AS fn, last_name AS ln

SORT

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

css 复制代码
1.  FROM employees
2.  | KEEP first_name, last_name, height
3.  | SORT height

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

css 复制代码
1.  FROM employees
2.  | KEEP first_name, last_name, height
3.  | SORT height DESC

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

css 复制代码
1.  FROM employees
2.  | KEEP first_name, last_name, height
3.  | SORT height DESC, first_name ASC

null values

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

markdown 复制代码
1.  FROM employees
2.  | KEEP first_name, last_name, height
3.  | SORT first_name ASC NULLS FIRST

STATS ... BY

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

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

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

ini 复制代码
1.  FROM employees
2.  | STATS avg_lang = AVG(languages)
avg_lang:double
3.1222222222222222

可以计算多个值:

scss 复制代码
1.  FROM employees
2.  | STATS avg_lang = AVG(languages), max_lang = MAX(languages)

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

ini 复制代码
1.  FROM employees
2.  | EVAL hired = DATE_FORMAT("YYYY", hire_date)
3.  | STATS avg_salary = AVG(salary) BY hired, languages.long
4.  | EVAL avg_salary = ROUND(avg_salary)
5.  | SORT hired, languages.long

支持以下聚合函数:

WHERE

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

ini 复制代码
1.  FROM employees
2.  | KEEP first_name, last_name, still_hired
3.  | WHERE still_hired == true

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

markdown 复制代码
1.  FROM employees
2.  | KEEP first_name, last_name, still_hired
3.  | WHERE still_hired

运算符

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

函数

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

markdown 复制代码
1.  FROM employees
2.  | KEEP first_name, last_name, height
3.  | WHERE length(first_name) < 4
相关推荐
Elastic 中国社区官方博客9 小时前
释放专利力量:Patently 如何利用向量搜索和 NLP 简化协作
大数据·数据库·人工智能·elasticsearch·搜索引擎·自然语言处理
Shenqi Lotus16 小时前
ELK-ELK基本概念_ElasticSearch的配置
elk·elasticsearch
yeye1989122417 小时前
10-Query & Filtering 与多字符串多字段查询
elasticsearch
Narutolxy20 小时前
精准优化Elasticsearch:磁盘空间管理与性能提升技巧20241106
大数据·elasticsearch·jenkins
谢小涛2 天前
ES管理工具Cerebro 0.8.5 Windows版本安装及启动
elasticsearch·es·cerebro
LKID体2 天前
Elasticsearch核心概念
大数据·elasticsearch·搜索引擎
晨欣2 天前
Elasticsearch里的索引index是什么概念?(ChatGPT回答)
大数据·elasticsearch·jenkins
许苑向上2 天前
最详细【Elasticsearch】Elasticsearch Java API + Spring Boot集成 实战入门(基础篇)
java·数据库·spring boot·elasticsearch
笔墨登场说说2 天前
git sonar maven 配置
大数据·elasticsearch·搜索引擎
Pioneer000012 天前
Elasticsearch实战应用:构建高效的全文搜索引擎
大数据·elasticsearch