1. 概述逻辑视图Logical Views——将常用查询定义为命名视图一处定义处处引用。子查询Subqueries——在单个FROM中组合多个索引各自拥有独立的处理管道即使它们的 schema 互不兼容。Schema-on-Read——无需修改映射mapping或重建索引reindex即可查询那些从未被映射过的字段直接从_source中按需读取。这些特性共同构建了一种更灵活、更敏捷的数据建模与查询方式。2. 三大核心能力概览在深入每个特性之前先理解它们之间的组合关系至关重要。这三者设计为分层叠加layer together的架构逻辑视图命名查询子查询管道每个索引独立处理Schema-on-Read读取未映射字段统一结果集合并输出子查询负责为每个索引定义独立的管道WHERE、EVAL、KEEP等处理各自特有的字段和逻辑。视图将子查询打包对外暴露一个单一名称消费者仪表板、告警、临时查询只需引用视图名无需关心内部复杂性。Schema-on-Read赋予这些管道访问从未在映射中声明的字段的能力数据在写入时无需预知所有字段查询时按需从_source提取。结果一条FROM view_name查询就能融合多个服务的日志统一规范化它们的 schema并直接使用那些你当初忘记在 ingest 阶段映射的字段——所有这一切无需重新索引。3. 逻辑视图Logical ViewsTech Preview3.1 逻辑视图逻辑视图可以理解为虚拟索引virtual indices。你通过_query/viewREST API 在集群级别定义一个 ES|QL 查询并为它赋予一个名称。之后在任何FROM子句中你可以像使用真实索引一样引用这个名称。使用定义视图定义存储于集群PUT _query/view/error_triageFROM svc-gateway-*| WHERE ...| KEEP ...FROM error_triage| STATS ...| SORT ...关键特性自动更新修改视图定义后所有引用该视图的仪表板、告警和临时查询立即生效无需逐个更新。可嵌套视图可以引用其他视图支持组合复用。跨集群搜索视图可跨多个集群定义。专用 RBAC 权限可以为视图设置独立的访问控制。3.2 用法示例定义视图PUT _query/view/error_triage { query: FROM svc-gateway-* | WHERE http.response.status_code 500 | KEEP timestamp, http.response.status_code, url.path, source.ip }使用视图FROM error_triage | STATS error_count COUNT(*) BY url.path | SORT error_count DESC在 Kibana Discover 中自动完成会识别出error_triage是一个逻辑视图并提供语法提示。3.3 简析视图本质上是查询定义的存储并不实际存储任何数据。执行时Elasticsearch 会将视图内部的查询文本展开并合并外部查询生成最终的执行计划。因此视图不会带来额外的存储开销但在执行时会有微小的解析开销可忽略。4. 子查询Subqueries in FROMTech Preview4.1 为什么需要子查询在实际场景中不同服务的日志往往写入不同的索引它们的 schema 可能完全不同例如网关日志有http.response.status_code支付日志有transaction.status认证日志有event.outcome。以往要合并分析这些数据要么在 ingest 阶段统一 schema要么在查询后手动合并——前者笨重后者低效。ES|QL 的子查询提供了组合原语composition primitive你可以在单个FROM中列出多个子查询每个子查询针对一个索引或索引模式独立处理然后所有结果以UNION ALL语义合并进入后续管道。4.2 工作流程关键点独立过滤每个分支有自己的WHERE优化器会分别将过滤条件下推到各索引充分利用索引的统计信息和缓存。灵活投影EVAL可以在分支内计算新字段统一输出结构例如每个分支都产出service、error_detail等公共字段。性能各分支并行执行最终结果合并整体延迟取决于最慢的分支。4.3 完整示例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这个查询将三个不同服务的异常事件合并按时间倒序返回最新的 20 条记录每条记录都带有统一的service和error_detail字段。5. Schema-on-Read未映射字段与 JSON 提取Tech Preview5.1 传统困境在 Elasticsearch 中字段必须在映射mapping中定义才能被索引和查询。如果 ingest 时遗漏了某个字段或者 schema 后期发生变化通常需要重新索引reindex整个数据这在生产环境中代价高昂。Schema-on-Read打破了这一限制。它允许你查询从未被映射的字段直接从_source原始 JSON 文档中按需读取无需任何事前准备。5.2 两种访问方式ES|QL 提供了两个层次的支持方式适用场景使用方法SET unmapped_fieldsload统一开启未映射字段访问所有未映射字段自动从_source读取在查询开头设置一次之后即可像普通字段一样使用未映射字段JSON_EXTRACT精细化提取从原始 JSON 字符串或flattened类型字段中抽取特定值在EVAL或WHERE中使用JSON_EXTRACT(field, $.path)5.3 行为模式unmapped_fields支持三种模式unmapped_fields 模式默认: 忽略未映射字段查询中引用会报错nullify: 未映射字段显示为 null保留列值为空load: 从 _source 读取实际值查询时加载默认未设置引用未映射字段会导致错误确保 schema 严格。nullify未映射字段在结果中作为null列出现不报错但也不实际读取。load核心模式查询引擎会在需要时从_source加载这些字段的值并缓存以供后续使用。5.4 使用示例SET unmapped_fieldsload; FROM otel-logs-* | WHERE log.level IN (error, warn) | STATS errors COUNT(*), latest MAX(timestamp) BY service.name, resource.cost_center | SORT errors DESC假设service.name和resource.cost_center并未在映射中定义开启load后查询仍然成功执行ES|QL 会从每个文档的_source中提取这些字段的值。5.5 原理剖析读取时机仅在查询执行期间当管道需要访问该字段时才会从_source中解析 JSON 并提取值。这带来了灵活性但会增加查询的 CPU 和 I/O 开销因为需要读取和解析_source。缓存对于多次引用的字段ES|QL 会在内部缓存提取结果避免重复解析。性能考量适用于探索性分析或低基数查询对于高频、高性能要求的场景仍建议将常用字段映射为常规字段并重新索引。注JSON_EXTRACT是更底层的工具适合从嵌套 JSON 或flattened字段中提取特定路径。未来原生flattened字段支持将进一步优化这一流程。6. 时区支持Timezone SupportGA在时序数据分析中时区处理一直是个痛点。以前你需要在每个日期函数中单独指定时区或者在后处理中转换。现在SET time_zone成为全局配置一次设置整个查询中的所有日期时间操作自动转换。6.1 使用方法SET time_zoneAmerica/Los_Angeles; FROM error_triage | EVAL hour DATE_TRUNC(1 hour, timestamp) | STATS errors COUNT(*) BY hour, service | SORT hour DESC效果DATE_TRUNC按洛杉矶时区截断时间。聚合结果中的timestamp输出会带上时区偏移量例如2026-04-09T11:00:00.000-07:00而非原始的...T18:00:00.000Z。所有日期比较、聚合、排序都基于同一时区。6.2 原理解释ES|QL 在内部将timestamp这样的日期时间字段视为 UTC 时间戳。设置time_zone后所有日期操作在内部先进行时区转换然后再处理。这避免了每个函数单独传递时区参数的繁琐也保证了结果的一致性。7. LIMIT BY原生分组 Top‑NTech Preview7.1 痛点传统SORT ... LIMIT N只能返回全局前 N 条记录。如果要“按服务分组分别返回每个服务中错误数最多的 3 种错误类型”你必须用复杂的子查询或后处理脚本。LIMIT BY解决了这个原生需求。7.2 语法与示例FROM error_triage | STATS cnt COUNT(*) BY service, error_detail | SORT cnt DESC | LIMIT 3 BY service语义按service字段分组对每组内按cnt降序排序取每组前 3 行。数字3在BY之前。7.3 内部机制输入行分组操作BY service每组内部排序SORT cnt DESC每组保留前 N 条合并输出LIMIT BY是在聚合后、最终输出前的一个管道操作它利用了分组后的局部排序能力每个组独立维护一个小根堆只需扫描一次数据即可完成。8. 其他重要更新8.1 FIRST / LAST / EARLIEST / LATESTGA这些聚合函数返回某个分组中按指定排序字段的最早或最晚记录所对应的值。函数参数说明FIRST(value, sort_field)值字段排序字段返回排序后第一条记录的valueLAST(value, sort_field)值字段排序字段返回排序后最后一条记录的valueEARLIEST(value)值字段隐式按timestamp排序等价于FIRST(value, timestamp)LATEST(value)值字段隐式按timestamp排序等价于LAST(value, timestamp)示例按source.ip分组统计每个 IP 的首次和末次失败时间以及首次失败时的用户名。FROM svc-auth-* | WHERE event.outcome failure | STATS first_seen FIRST(timestamp, timestamp), last_seen LAST(timestamp, timestamp), first_user EARLIEST(user.name), attempts COUNT(*) BY source.ip | SORT attempts DESC8.2 URI_PARTS / USER_AGENT / REGISTERED_DOMAIN新管道命令这三个命令将单个字段展开为多个结构化输出列极大地简化了解析工作。命令输入字段输出列示例URI_PARTS target source_fieldURL 字符串target.domain,target.path,target.scheme,target.port,target.query等USER_AGENT target source_fieldUser-Agent 字符串target.name,target.version,target.os.name,target.device等REGISTERED_DOMAIN target source_field域名字符串target.registered_domain,target.top_level_domain,target.subdomain用法示例FROM svc-gateway-* | WHERE http.response.status_code 400 | URI_PARTS parts url.full | STATS errors COUNT(*) BY parts.domain, parts.path | SORT errors DESC这些命令在内部使用 Lucene 或 Elasticsearch 内置的解析器效率远高于自定义脚本。9. Lookup Join 优化性能增强Lookup Join在 9.1 版本引入用于将主查询的每一行与一个较小的“查找索引”进行关联常用于数据丰富enrichment。本次发布带来了两项重要优化9.1 Lucene 结构复用问题每次执行 lookup join都需要打开查找索引的 doc values 和 TermsEnum 结构涉及磁盘 I/O。优化现在对于相同查找索引的重复查询这些底层结构会被缓存并跨查询复用避免重复读取。适用场景典型的丰富模式——主查询有大量行查找索引相对较小且被频繁使用。例如将 IP 地址映射到地理位置信息。9.2 单关键字连接加速对于连接键为单个 keyword 字段的最常见情况ES|QL 使用了一条更快的执行路径减少了每行连接的开销例如减少了类型转换和字典查找的代价。这两项优化使得 lookup join 在生产环境中更具实用性尤其适合高吞吐量的数据丰富需求。总结功能状态核心价值逻辑视图Tech Preview查询复用一处定义全局生效子查询FROM 中Tech Preview合并不同 schema 的索引各分支独立处理Schema-on-Read未映射字段Tech Preview无需 reindex查询时按需读取_source时区支持GA全局时区设置简化日期时间处理LIMIT BYTech Preview原生分组 Top‑N无需后处理FIRST / LAST / EARLIEST / LATESTGA分组内极值关联取值URI_PARTS / USER_AGENT / REGISTERED_DOMAIN新命令解析结构化字段为多列Lookup Join 优化性能提升缓存复用 单键加速更适合丰富场景VALUES / MV_EXPAND / FORKGA多值字段操作与并行执行分支SPARKLINE / MV_UNION / MV_DIFFERENCE / MV_INTERSECTSTech Preview内置迷你图与集合运算如何用所有 Tech Preview 功能已包含在 Elasticsearch 的最新版本中Serverless 中视图暂不可用。可以在 Kibana 的 Dev Tools 或 Discover 中直接尝试。重要提示Tech Preview 功能可能在未来版本中变更且不享受 GA 功能的 SLA 支持。功能的上线时间由 Elastic 自行决定。通过上述能力ES|QL 正在从一个单纯的查询语言演变为一个完整的数据访问与组合层。逻辑视图、子查询和 Schema-on-Read 三驾马车让数据建模变得更加动态、灵活也大大降低了运维成本。