Loading

Combine and reuse ES|QL queries

ES|QL provides several ways to combine, filter, and reuse query results beyond querying a single index. Choose the mechanism that best fits your goal.

Mechanism What it does When to use
Subquery Nests a query inside another query, either to combine result sets or to filter rows You need to use the results of one query inside another
View Saves a named query as a virtual index that any FROM can reference You want to define a query once and reuse it across multiple requests
FORK Sends the same incoming rows through multiple independent branches You want to run different processing on the same data in one query

Views, FROM subqueries, IN subqueries, and FORK share several traits but differ in important ways.

IN subqueries operate differently from the other three. They filter rows rather than producing branches, so the similarities and differences below apply to FROM subqueries, views, and FORK only.

  • Dynamic execution. All three run at query time, so results reflect the current state of the data.
  • Union of columns. Columns from multiple branches are merged into a single table. Missing columns are filled with null values.
  • Supported commands. Complex processing commands can be used inside both views and FROM subqueries, as detailed in the description of FROM subqueries.
  • No nested branching. Nested branching is generally not supported, but views can work around this through query compaction.
  • Maximum branch count. All three share the same maximum branch count of 8.
  • FORK does not include a source command. Every branch receives the same incoming rows and columns.
  • FROM subqueries and views each have their own source command (FROM, TS, or ROW), so branches can read from different sources with different columns.
  • Only one FORK command is allowed per query, so nested branches are not possible. FROM subqueries and views have similar restrictions, but views can partially work around them through query compaction.
  • Views must be defined using the REST API before they can be used in queries. Subqueries are written inline and require no setup.
  • Views have names that are unique within the index namespace. A view cannot share a name with an index.
  • Views can be nested (up to a depth of 10), with two restrictions:
    • Cyclic references are not allowed. For example, if viewA references viewB and viewB references viewC, then viewC cannot reference viewA. Cycles are detected at query time.
    • No more than one branching point can exist across the nesting chain.
  • FROM subqueries do not support further FROM subqueries or FORK inside them, but can contain IN subqueries. Views allow nested branching under limited conditions.

Depending on your goal, one of these alternatives may be a better fit:

  • LOOKUP JOIN: enrich rows by joining against a lookup index on a key field.
  • ENRICH: augment rows with data from an enrich policy.
  • Query multiple indices: use comma-separated index patterns or wildcards in a single FROM to query across indices without subqueries.