news 2026/5/8 17:44:04

三个索引走进一个 FROM 子句:Elasticsearch 中的 ES|QL 子查询

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
三个索引走进一个 FROM 子句:Elasticsearch 中的 ES|QL 子查询

作者:来自 Elastic Tyler Perkins

ES|QL 子查询让每个数据源都拥有各自独立的 pipeline 和过滤条件,从而消除了 CASE 链、恢复了谓词下推(predicate pushdown),并使多索引查询在设计上具备可扩展性。

亲自体验 Elasticsearch:查看 Elasticsearch Labs 仓库中的示例 notebooks、开始免费的云试用,或立即在本地机器上试用 Elastic。


Elasticsearch Query Language(ES|QL)现在支持在 FROM 中使用子查询。三个索引、不同 schema、一条查询;每个数据源都拥有自己的 pipeline、过滤条件和转换逻辑。不再需要 CASE 链,也不再需要客户端拼接数据。想增加第四个数据源?只需增加第四个分支,对原有三个分支无需任何修改。

问题:异构数据,一个查询

考虑一个生产事故调查场景。错误日志分散在三个微服务中:API gateway、payments service 和 auth service,并且每个服务都有不同的字段名和不同的约定。在子查询出现之前,要在一条 ES|QL 查询中组合它们,通常意味着把所有内容塞进一个 FROM,并配合大量 CASE 链:

FROM svc-gateway-*, svc-payments-*, svc-auth-* METADATA _index | WHERE http.response.status_code >= 500 OR transaction.status IN ("failed", "timeout") OR (event.action == "login" AND event.outcome == "failure") | EVAL service = CASE( _index LIKE "svc-gateway*", "gateway", ... /* one branch per source */), error_detail = CASE( _index LIKE "svc-gateway*", CONCAT("HTTP ", http.response.status_code::string), ... /* one branch per source */) | KEEP @timestamp, service, error_detail, source.ip | SORT @timestamp DESC

这种方式既脆弱又缓慢。带有 OR 的析取条件会阻止谓词下推(predicate pushdown);每个索引都必须扫描所有条件。每增加一个数据源,CASE 链就会继续增长。如果再把这段查询复制到五个仪表板和三个告警规则中,那么任何变更都会产生八处需要同步更新的地方。

解决方案:独立 pipeline

子查询取代了单体式的 FROM + CASE 模式。每个数据源都拥有自己完整的 pipeline:

FROM (FROM svc-gateway-* | WHERE http.response.status_code >= 500 | EVAL service = "gateway", error_detail = CONCAT("HTTP ", http.response.status_code::string) | KEEP @timestamp, service, error_detail, source.ip), (FROM svc-payments-* | WHERE transaction.status IN ("failed", "timeout") | EVAL service = "payments", error_detail = transaction.status | KEEP @timestamp, service, error_detail, source.ip), (FROM svc-auth-* | WHERE event.action == "login" AND event.outcome == "failure" | EVAL service = "auth", error_detail = CONCAT(event.action, " ", event.outcome) | KEEP @timestamp, service, error_detail, source.ip) | SORT @timestamp DESC | LIMIT 20

gateway 分支只扫描 HTTP 500 错误。payments 分支只检查交易状态。auth 分支只检查登录失败。由于每个分支都有自己的 WHERE 条件,优化器能够将过滤条件独立下推到各自索引中,从而恢复单一 FROM 配合 OR 条件时无法实现的谓词下推(predicate pushdown)。某个分支中存在而其他分支不存在的字段,则会自动填充为 null。

如果要新增第四个服务,只需要增加第四个分支即可,现有分支完全不需要修改。

保存为视图(View)

这正是子查询与逻辑视图(logical views)结合发挥作用的地方。只需一次 API 调用,就可以把上面的子查询封装为一个命名视图:

PUT _query/view/error_triage { "query": "FROM (FROM svc-gateway-* | WHERE ...) , (FROM svc-payments-* | WHERE ...) , (FROM svc-auth-* | WHERE ...)" }

现在,使用者只需要编写:

FROM error_triage | STATS error_count = COUNT(*) BY service

三个索引、三个 pipeline、一个名称。如果你当前有 10 个仪表板和 5 个告警规则在复用这套逻辑,那么实际上就有 15 份重复逻辑;而使用 view 后,只保留一个定义,当新增第四个服务时,所有消费者侧都无需修改。有关 views 的完整深入介绍,请参阅《Elasticsearch ES|QL Views》。

在分支内部可以做什么

每个分支都支持完整的 ES|QL pipeline,包括 WHERE、EVAL、STATS、LOOKUP JOIN、ENRICH 等等。完整列表请参阅 subquery 文档。

聚合不同指标后再组合

每个分支都可以在结果合并前先计算自己的汇总信息。这在不同索引使用不同字段名来表示同一个概念时尤其有用:

FROM (FROM svc-gateway-* | STATS avg_latency = AVG(http.response.time_ms) BY hour = BUCKET(@timestamp, 1 hour) | EVAL service = "gateway"), (FROM svc-payments-* | STATS avg_latency = AVG(transaction.duration_ms) BY hour = BUCKET(@timestamp, 1 hour) | EVAL service = "payments") | SORT hour DESC, service

两个分支都会生成 avg_latency 和 hour,但它们分别基于不同的源字段进行计算。最终合并后的结果是一张统一的表,可以直接用于绘图或告警,而无需在数据摄取阶段统一字段名。这个模式在单一 FROM 中是无法实现的;没有子查询,你无法针对不同索引执行不同的聚合逻辑。

Subqueries 与 FORK 的区别

ES|QL 还提供了 FORK(现已正式发布),它用于从同一输入创建并行执行分支。两者的区别在于:

  • 不同索引 → 使用 subqueries。
  • 相同数据、不同分析 → 使用 FORK。

如何对比其他方案

如果你来自其他查询语言生态,以下是截至目前 ES|QL subqueries 的对比方式:

Splunk SPL / SPL2
经典 SPL 中提供 append 和 multisearch,而 SPL2 增加了 union 命令,用于合并来自多个数据集的事件(这是与 ES|QL subqueries 最接近的对应能力)。Federated Search 则将这种能力扩展到远程 Splunk 部署(类似于 CCS)。

差异主要在于引擎如何处理每个分支:ES|QL subqueries 为每个分支提供独立的谓词下推(predicate pushdown),也就是说,过滤条件会分别下推到各自索引的 shard 级结构中。而 SPL2 union 虽然可以合并数据集,但跨分支优化能力主要受限于 search scheduler 能实现的并行化程度。

另外,将 ES|QL subqueries 封装为 view 后,可以获得引擎级封装与基于角色的访问控制(RBAC);而 Splunk 的对应机制是 saved searches 与 macros,本质上是解析阶段的文本替换。

SQL 数据库
SQL 中最接近的能力是 UNION ALL。区别在于,SQL UNION ALL 通常要求在解析阶段就保证列数量与类型一致。

ES|QL subqueries 更灵活:某个分支存在而其他分支不存在的列,会自动以 null 补齐。这对于 schema 不一致(也是 observability 数据的常态)的场景非常重要。

SQL views 也能解决复用问题,但 ES|QL views 是 cluster 级对象,而不是 database scope;它们还支持跨集群搜索(CCS)。

Grafana / Datadog / 其他仪表板工具
这些工具通常在可视化层处理多数据源组合:分别执行查询,然后在 panel 中合并。

这种方式对于展示是可行的,但对于告警、下游查询或任何需要统一结果集的程序化场景来说会出现问题。

ES|QL subqueries 则把组合逻辑下沉到引擎层,因此 alerts、views 与 API consumer 都能获得同一份统一结果集。

能力Splunk SPL/SPL2SQL UNION ALL仪表板层合并ES|QL 子查询
独立按源过滤SPL2union合并数据集;优化在调度器层面|N/A(独立查询)是;并行且支持下推
模式不匹配处理
模式不匹配处理手动字段标准化严格列匹配面板配置中手动处理自动空值填充
引擎级复用文本宏(解析时展开)数据库范围视图仪表板变量集群级视图 + RBAC
支持告警 + API有限(摘要索引)否;仅用于展示
添加数据源修改每个宏/保存搜索添加 UNION 分支添加面板查询添加分支;现有分支不变

当前限制

在技术预览版本中,子查询是非相关的;各分支独立运行,不能引用外层查询。它们仅支持在 FROM 中使用(不支持 TS),并且 FORK 不能在子查询内部或之后使用。详情请参见子查询文档。

子查询的未来方向

WHERE 子查询 —— 例如 WHERE field IN (FROM other_index | ...) 以及其他相关形式 —— 将把组合模型从 FROM 扩展到过滤层。这将把类似 SQL 的嵌套过滤模式引入 ES|QL。

尝试使用

FROM 中的子查询已作为技术预览开放。你可以在 Kibana Dev Tools 或 Discover 中尝试使用它们。欢迎反馈;请在 GitHub 提交带有 ES|QL 标签的问题。

FROM 中的 ES|QL 子查询属于技术预览功能。技术预览功能可能会发生变化,并不包含在 GA 功能的支持 SLA 中。本文所述任何功能或能力的发布与发布时间均由 Elastic 全权决定,部分功能可能无法按时交付或最终不予提供。

原文:https://www.elastic.co/search-labs/blog/esql-subquery-from

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/8 17:43:58

OMS、WMS、TMS、ERP:一张图看懂物流四大系统的分工与协作

OMS、WMS、TMS、ERP:一张图看懂物流四大系统的分工与协作 摘要:OMS管“单”,WMS管“货”,TMS管“车”,ERP管“账”——这四大系统构成了现代供应链的数字化骨架。但它们分别做什么?彼此之间如何传递信息&am…

作者头像 李华
网站建设 2026/5/8 17:43:49

简单说明Linux系统中input作用

在 Linux 系统中,input 通常指与输入设备相关的子系统和设备文件,主要用于管理各类输入设备(如键盘、鼠标、触摸屏、游戏手柄、传感器等)的输入事件。核心概念:input 子系统Linux 的 input 子系统是内核的一部分&#…

作者头像 李华
网站建设 2026/5/8 17:42:53

手机隐藏实用功能,很多人都不知道,一键开启超方便

大家好,我是熊大科技君,专注分享手机、电脑、数码产品实用技巧,致力于用通俗易懂的语言,讲解各类科技操作,让每个人都能轻松玩转数码产品。 现在手机已经成为我们生活中不可或缺的工具,但大部分人只用到了手…

作者头像 李华
网站建设 2026/5/8 17:42:50

基于 Flutter × Harmony6.0 的校园问卷模块页面开发实践

基于 Flutter Harmony6.0 的校园问卷模块页面开发实践 前言 随着 HarmonyOS 生态逐渐成熟,越来越多开发者开始关注 Flutter 在 Harmony6.0 环境下的跨端适配能力。相比传统单平台开发,Flutter 能够以统一的 UI 渲染体系快速覆盖 Android、HarmonyOS 等多…

作者头像 李华
网站建设 2026/5/8 17:41:57

AMBA TLM 2.0库:SystemC总线建模与SoC验证指南

1. AMBA TLM 2.0库概述AMBA TLM 2.0库是Arm公司提供的一套基于SystemC和TLM 2.0标准的C建模库,专门用于对AMBA总线协议(包括AXI、ACE和CHI)进行事务级建模和仿真。这个库为SoC设计工程师提供了从行为级到周期精确级的建模能力,是硬…

作者头像 李华