﻿---
title: Define reusable queries with ES|QL views
description: A view is a virtual index defined by an ES|QL query. You reference a view by name in the FROM command, just like an ordinary index. The query runs each...
url: https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/esql-views
products:
  - Elasticsearch
applies_to:
  - Elastic Cloud Serverless: Generally available
  - Elastic Stack: Preview from 9.4 to 9.5
---

# Define reusable queries with ES|QL views
A view is a virtual index defined by an ES|QL query. You reference a view by name in the [`FROM`](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/commands/from) command, just like an ordinary index. The query runs each time the view is referenced, so results always reflect the current state of the data.
A view has two components:
- **Name**: unique within the index namespace, used anywhere an index name is accepted in `FROM`.
- **Definition**: a complete ES|QL query that runs each time the view is referenced.


## Basic example

Here's how a view works in practice:
<stepper>
  <step title="Start with a query">
    ```esql
    FROM addresses
    | RENAME city.country.name AS country
    | EVAL country = CASE(country == "United States of America", "United States", country)
    | STATS count=COUNT() BY country
    ```


    | count:long | country:keyword |
    |------------|-----------------|
    | 1          | Japan           |
    | 1          | Netherlands     |
    | 1          | United States   |
  </step>

  <step title="Save it as a view">
    ```json

    {
        "query": """
            FROM addresses
            | RENAME city.country.name AS country
            | EVAL country = CASE(country == "United States of America", "United States", country)
            | STATS count=COUNT() BY country
            """
    }
    ```
  </step>

  <step title="Reference it by name, just like an index">
    ```esql
    FROM country_addresses
    ```


    | count:long | country:keyword |
    |------------|-----------------|
    | 1          | Japan           |
    | 1          | Netherlands     |
    | 1          | United States   |
  </step>
</stepper>


## When to use views

Views are a good fit when you want to:
- **Reuse a named query.** Wrap a frequently used ES|QL pipeline as a view and reference it by name, instead of repeating the same query in every request.
- **Abstract common transformations.** Centralize renames, type conversions, or derived fields so consumers see a consistent set of columns without needing to know the underlying source structure.
- **Combine pre-processed data sources.** Define one view per source, each with its own filters or aggregations, and query them together in a single `FROM` clause.
- **Simplify queries for downstream tools.** Dashboards, alerts, or ad-hoc analysts can query `FROM my_view` without needing to know the indices or processing commands behind it.


## Create and manage views

Use the REST API to create, update, delete, and list views:
- [Create or update a view](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-esql-put-view)
- [Delete a view](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-esql-delete-view)
- [Get or list views](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-esql-get-view)


### Query validation

`PUT /_query/view/<name>` rejects a query that cannot be parsed.
<applies-to>Elastic Stack: Planned</applies-to> To check the query without running it, set the `validate` query parameter to `true`. Validation is off by default.
With `validate=true`:
- If the query uses an index or column that does not exist, the response carries a `Warning` header.
- A warning does not stop Elasticsearch from saving the view. The view is saved whether or not validation reports a problem, so you can create a view before the index it reads from.
- The analysis uses your privileges. An index you cannot read is reported as unknown.
- Failures unrelated to the query, such as an overloaded cluster, produce no warning.


### Reserved views

Some views are reserved. Elasticsearch or its components create them, not users. A reserved view is marked with `"reserved": true` in the [get view](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-esql-get-view) response.
You cannot modify or delete a reserved view through the REST API:
- `PUT /_query/view/<name>` fails if a reserved view with that name exists. You also cannot set `reserved` in a request.
- `DELETE /_query/view/<name>` fails with `cannot delete reserved view [<name>]`.

You can query and read a reserved view like any other view, subject to the same [privileges](#esql-views-privileges).

## Query a view

Use views as if they were ordinary indices:
```esql
FROM index_pattern
```

Where `index_pattern` is a comma-separated list of index or view names. Index
expressions can include wildcards and date math. Whether a wildcard also matches
views depends on the version and deployment type.

### Wildcard patterns and views

<applies-switch>
  <applies-item title="{ "stack": "ga 9.6+", "serverless": "ga" }" applies-to="Elastic Cloud Serverless: Generally available, Elastic Stack: Planned">
    By default, a wildcard pattern in `FROM` does not match views. `FROM my-view-1`
    reads the view by exact name, while `FROM my-view-*` resolves to indices, data
    streams, and aliases only. Registered views are excluded.To include views in wildcard resolution, enable the `wildcards_match_views` setting:
    ```esql
    SET wildcards_match_views = true;
    FROM my-view-*
    ```
    You can also send it in the `_query` request body as `"settings": {"wildcards_match_views": true}`. A value set in the query overrides the request body, but neither value enters a referenced view. Refer to [Settings across view boundaries](#settings-across-view-boundaries) for the limits and warnings.<applies-to>Elastic Stack: Planned</applies-to> As an alternative, set the cluster-wide default
    with `esql.query.settings.wildcards_match_views` in `elasticsearch.yml` or
    through the cluster settings API. The cluster default applies both outside and
    inside views.
  </applies-item>

  <applies-item title="stack: preview 9.4-9.5" applies-to="Elastic Stack: Preview from 9.4 to 9.5">
    Wildcard patterns in `FROM` match registered views automatically.
  </applies-item>
</applies-switch>


## Privileges

View operations use the standard Elasticsearch [index privileges](/elastic/docs-builder/docs/4572/reference/elasticsearch/security-privileges#privileges-list-indices), applied to the view name.

| Operation                                    | Privilege (on the view name)                         |
|----------------------------------------------|------------------------------------------------------|
| Query (`FROM my_view`)                       | `read`, `all`                                        |
| Create or update (`PUT /_query/view/<name>`) | `create_view`, `manage_view`, `manage`, `all`        |
| Read definition (`GET /_query/view/<name>`)  | `read_view_metadata`, `manage_view`, `manage`, `all` |
| Delete (`DELETE /_query/view/<name>`)        | `delete_view`, `manage_view`, `manage`, `all`        |


### Views are not a security boundary

`read` on a view name permits querying the view but does **not** grant access to the data behind it. The caller must also have `read` on every index or alias the view definition resolves to, including through nested views.
Access is enforced at query time. Creating a view requires no privilege over the indices it references.
If some underlying indices are unauthorized, the query fails with a `403`. If none are accessible, it fails with a `400 Unknown index`. Wildcard patterns (`FROM view-*`) silently exclude unauthorized views.
Nested views are resolved under the calling user's credentials. Access to an outer view does not grant access to any inner view it references.

### Document- and field-level security

`read` on a view name must not carry DLS or FLS. If it does, the query fails with a `403` and the `views_with_dls_or_fls` error field lists the affected names. This applies at every nesting level.
DLS or FLS on the **underlying indices** is applied normally.

### Example role

```json
{
  "indices": [
    {
      "names": ["country_addresses"],
      "privileges": ["read", "create_view", "read_view_metadata", "delete_view"]
    },
    {
      "names": ["addresses"],
      "privileges": ["read"]
    }
  ]
}
```


## Examples

The following examples show how to use views within the `FROM` command.

### Combine data from multiple indices

Assume we've defined three views in a similar way to the example above, each counting the number of documents that reference a particular country, but from three different source indices:
- `country_airports` - reports counts of documents per country from our `airports` index
- `country_addresses` - reports counts of documents per country from our `addresses` index
- `country_languages` - reports counts of documents per country from our `languages` index

Now we can query these together with a query like:
```esql
FROM country_addresses, country_airports, country_languages
| WHERE country LIKE "United*"
| SORT country ASC, count DESC
```


| count:long | country:keyword |
|------------|-----------------|
| 17         | United Kingdom  |
| 1          | United Kingdom  |
| 129        | United States   |
| 1          | United States   |
| 1          | United States   |

The same country might appear in multiple views, producing multiple rows.
We could combine these with a `STATS` command, using `SUM(count) BY country`.

### Use wildcards

<applies-to>
  - Elastic Cloud Serverless: Generally available
  - Elastic Stack: Preview from 9.4 to 9.5
</applies-to>

<note applies-to="Elastic Cloud Serverless: Generally available, Elastic Stack: Planned">
  This example requires `wildcards_match_views = true`. By default, wildcards do
  not match views. Refer to [wildcard patterns and views](#esql-views-wildcards)
  and review the [ES|QL view limitations](#esql-views-limitations).
</note>

```esql
FROM country_*
| STATS count=SUM(count) BY country
| WHERE count > 11
| SORT count DESC, country ASC
```


| count:long | country:keyword |
|------------|-----------------|
| 131        | United States   |
| 50         | India           |
| 45         | Mexico          |
| 41         | China           |
| 38         | Canada          |
| 31         | Brazil          |
| 26         | Russia          |
| 18         | United Kingdom  |
| 17         | Australia       |
| 13         | Argentina       |
| 13         | Germany         |
| 12         | France          |
| 12         | Indonesia       |

Note how we used `SUM` to combine the counts of the three previously aggregated `count` columns.

### Use LOOKUP JOIN inside a view

We can define views with complex queries, including commands like `LOOKUP JOIN`:
```json

{
    "query": """
        FROM airports
        | RENAME abbrev AS code
        | LOOKUP JOIN airports_mp ON abbrev == code
        | WHERE abbrev IS NOT NULL
        | DROP code
       """
}
```

This creates a view called `airports_mp_filtered` that contains all rows from the `airports` index that also have a matching `abbrev` inside the `airports_mp` index.
This is effectively a subset of the `airports` index.
We could, for example, see how many airports are defined only in `airports` versus how many are defined in the view, by combining both a view and an index in the same `FROM` command:
```esql
FROM airports_mp_filtered, airports
| STATS duplications=COUNT() BY abbrev
| STATS count=COUNT() BY duplications
| SORT count DESC
```


| count:long | duplications:long |
|------------|-------------------|
| 880        | 1                 |
| 7          | 2                 |
| 1          | 3                 |


### Views with METADATA

The [`METADATA` directive](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/esql-metadata-fields) is supported both inside and outside a view.
Views follow the same rules as [subqueries](/elastic/docs-builder/docs/4572/reference/query-languages/esql/esql-from-subquery#subqueries-with-metadata).
Inside the view, the directive generates columns just like other fields. You can use them for filtering and as output columns.
Except for `_class` and `_name`, an outer `METADATA` request returns `null` when the source output does not contain the requested field.
When the source retains a metadata field in its output, the outer query receives its values even if it does not request that field with `METADATA`.
<warning applies-to="Elastic Stack: Preview in 9.4">
  `METADATA` on the outer `FROM` is not handled consistently.If the `FROM` names only a view, the directive is ignored. For example, `FROM my_view METADATA _index` returns the view contents without an `_index` column.
  If the `FROM` combines that source with other sources, the requested metadata columns might appear with `null` values for rows from that source, but this behavior is not consistent.
  To retrieve metadata values reliably, request the fields inside the source and retain them in its output.
</warning>

<applies-to>Elastic Stack: Planned</applies-to> `_class` and `_name` are the only metadata fields that work on a view without the view body declaring them. The outer query answers them for each view. `_class` is `view`. `_name` is the view name. You do not need the directive inside the view. If the view body also declares `_class` or `_name`, the outer values replace them.
```esql
FROM airports_mp_filtered, airports METADATA _class, _name
| WHERE abbrev == "LUH"
| KEEP abbrev, _class, _name
| SORT _name
```


| abbrev:keyword | _class:keyword | _name:keyword        |
|----------------|----------------|----------------------|
| LUH            | index          | airports             |
| LUH            | view           | airports_mp_filtered |


## How views execute

Views behave like inline subqueries at execution time and when you start combining multiple views, it helps to know how nesting works and where the limits are.

### Execution model

When a query references one or more views, each view's definition query executes independently at query time, in parallel where possible. This is the same execution model used by [`FROM` subqueries](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/esql-from-subquery) and [`FORK`](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/commands/fork).
Results from all sources (indices, views, subqueries) are unioned into a single result set. Duplicate rows are preserved. Columns that exist in one source but not another are filled with `null`.

### Nesting and branching

A view definition can reference another view. This is called a nested view. ES|QL allows nesting to a depth of 10.
When multiple views are referenced within the same index pattern, each view executes independently (in parallel if possible), similar to subqueries and [`FORK`](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/commands/fork).
<applies-switch>
  <applies-item title="{ "stack": "ga 9.6+", "serverless": "ga" }" applies-to="Elastic Cloud Serverless: Generally available, Elastic Stack: Planned">
    [Query compaction](#query-compaction) flattens nested view branches into one merge only when the result has at most 20 branches by default (`esql.query.max_branch_count`). If flattening would exceed that cap, ES|QL keeps the nested plan instead of failing the query. The same setting also caps the total number of leaf branches in the query.A query and the views and subqueries it references are limited to 500 commands in total (`esql.query.max_command_count`). The limit applies both to the query as written and to the expanded plan after every view and subquery body is inlined, so deeply nested or heavily repeated view references fail instead of consuming unbounded memory.
  </applies-item>

  <applies-item title="stack: preview 9.4-9.5" applies-to="Elastic Stack: Preview from 9.4 to 9.5">
    Views, subqueries, and `FORK` share a maximum branch count of 8. For example, a single index pattern could reference four views and four subqueries, but adding one more would exceed the limit and the query will fail.
  </applies-item>
</applies-switch>


### Combining branching and nesting

<applies-switch>
  <applies-item title="{ "stack": "ga 9.6+", "serverless": "ga" }" applies-to="Elastic Cloud Serverless: Generally available, Elastic Stack: Planned">
    Nested branching is supported. A view definition can contain `FROM` subqueries,
    nested views, and `FORK`, and a query can combine that view with other
    branched sources. The complete expanded query remains subject to the branch and
    command limits described above. The restriction on two user-written `FORK`
    commands along the same uninterrupted pipeline still applies.
  </applies-item>

  <applies-item title="stack: preview 9.4-9.5" applies-to="Elastic Stack: Preview from 9.4 to 9.5">
    Branching and nesting are allowed in combination only when there is no more than
    one branch point:
    - A view can contain subqueries, but that view cannot be used together with other
      views, and the subqueries can reference only nested views that contain no
      further branching.
    - A subquery can contain views, but those views must not introduce any additional
      branch points through subqueries or `FORK`.
  </applies-item>
</applies-switch>


### Query compaction

When a view definition contains branches, such as subqueries or references to
other views, query compaction tries to flatten the inner branches into the outer
branch set.
<applies-switch>
  <applies-item title="{ "stack": "ga 9.6+", "serverless": "ga" }" applies-to="Elastic Cloud Serverless: Generally available, Elastic Stack: Planned">
    Compaction produces a single-level plan when the flattened width is within
    `esql.query.max_branch_count` (20 by default). If flattening would exceed the
    limit, ES|QL keeps the nested plan.
  </applies-item>

  <applies-item title="stack: preview 9.4-9.5" applies-to="Elastic Stack: Preview from 9.4 to 9.5">
    Compaction produces the single branch point these versions require when the
    flattened plan has at most 8 branches. Otherwise, the query fails.
  </applies-item>
</applies-switch>

The following example shows how compaction works. Two views are each defined as a pair of subqueries:
```json

{
    "query": """
        FROM (
            FROM app-events-* | KEEP msg, level
        ), (
            FROM auth-events-* | KEEP msg, level
        )
       """
}
```

```json

{
    "query": """
        FROM (
            FROM nginx-events-* | KEEP msg, level
        ), (
            FROM apache-events-* | KEEP msg, level
        )
       """
}
```

A query references both views alongside a regular index:
```esql
FROM other-events, view_x, view_y
| STATS count(msg) BY level
```

Without compaction, this would create two levels of branching. Three outer branches exist, and two of them branch again inside their view definitions:
```mermaid
flowchart TD
    S["STATS count(msg) BY level"]
    S --> O["other-events"]
    S --> VX["view_x"]
    S --> VY["view_y"]
    VX --> AX["app-events-*"]
    VX --> AU["auth-events-*"]
    VY --> NG["nginx-events-*"]
    VY --> AP["apache-events-*"]
```

Compaction flattens the inner view branches into the outer branch set, producing a single-level plan with five branches:
```mermaid
flowchart TD
    S["STATS count(msg) BY level"]
    S --> O["other-events"]
    S --> AX["app-events-*"]
    S --> AU["auth-events-*"]
    S --> NG["nginx-events-*"]
    S --> AP["apache-events-*"]
```

Compaction doesn't apply if the view definition contains processing commands
after its subqueries. Those commands must run on the combined branch output, so
the branch level can't be collapsed.
<applies-switch>
  <applies-item title="{ "stack": "ga 9.6+", "serverless": "ga" }" applies-to="Elastic Cloud Serverless: Generally available, Elastic Stack: Planned">
    If compaction isn't possible, or flattening would exceed the branch cap, ES|QL
    keeps the nested plan and executes it subject to the overall branch and command
    limits.
  </applies-item>

  <applies-item title="stack: preview 9.4-9.5" applies-to="Elastic Stack: Preview from 9.4 to 9.5">
    If compaction isn't possible, the query fails because these versions allow only
    one branch point in the plan.
  </applies-item>
</applies-switch>


## Limitations

ES|QL views have the following limitations:

#### Document- and field-level security

A role entry that grants `read` on a view name must not carry DLS or FLS restrictions. If it does, the query fails with a `403`. DLS/FLS on the underlying indices is applied normally. Refer to [view privileges](#esql-views-privileges).

#### Branching inside views

Views may be nested up to depth 10.
<applies-switch>
  <applies-item title="{ "stack": "ga 9.6+", "serverless": "ga" }" applies-to="Elastic Cloud Serverless: Generally available, Elastic Stack: Planned">
    View definitions can contain branched query plans created by `FROM` subqueries,
    nested views, and [`FORK`](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/commands/fork).
    These branches can be nested, subject to the branch and command limits described
    in [How views execute](#how-views-execute).
  </applies-item>

  <applies-item title="stack: preview 9.4-9.5" applies-to="Elastic Stack: Preview from 9.4 to 9.5">
    Branching and nesting are allowed in combination only when there is no more than
    one branch point. A view can contain subqueries only when the resulting plan can
    be flattened through
    [query compaction](#query-compaction).
  </applies-item>
</applies-switch>


#### Cross-cluster and serverless

Views can reference remote indices in [cross-cluster search](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/esql-cross-clusters), but you can't query a view that is defined on a remote cluster.
<applies-switch>
  <applies-item title="stack: ga 9.6+" applies-to="Elastic Stack: Planned">
    Remote views are invisible to source resolution. An exact reference such as `FROM cluster:view` returns an `Unknown index` error.
  </applies-item>

  <applies-item title="stack: preview 9.4-9.5" applies-to="Elastic Stack: Preview from 9.4 to 9.5">
    A query fails if its source expression matches a remote view.
  </applies-item>
</applies-switch>

Views are available in serverless and [cross-project search](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/esql-cross-serverless-projects), but with some limitations:
- You can define views in both origin and linked projects.
- CPS resolves index expressions against indices in every project that the
  expression targets, but it resolves views only in the origin project. Views
  in linked projects are invisible to the query, including through qualified
  expressions such as `FROM linked-project:view`.
- CPS uses the same resolution process for index expressions in the top-level
  query and inside view definitions.
- An unqualified index expression can match a view in the origin project and
  indices in linked projects. CPS returns results from both.


#### Query DSL filters

<applies-switch>
  <applies-item title="{ "stack": "ga 9.6+", "serverless": "ga" }" applies-to="Elastic Cloud Serverless: Generally available, Elastic Stack: Planned">
    A Query DSL filter on the request applies to the output of a view, after the commands in the view definition. If Elasticsearch can't translate a filter clause to ES|QL, it omits that clause for the view and returns a warning. Check the response warnings because omitting a clause can produce more results than the complete filter would.For example, create a view that counts sales by region:
    ```json

    {
      "query": "FROM sales | STATS total = COUNT(*) BY region"
    }
    ```
    The following request requires both `should` clauses to match:
    ```json

    {
      "query": "FROM sales_by_region | KEEP region, total | LIMIT 1000",
      "filter": {
        "bool": {
          "should": [
            { "term": { "region": "eu" } },
            { "term": { "total": 3 } }
          ],
          "minimum_should_match": 2
        }
      }
    }
    ```
    ES|QL can't translate a `minimum_should_match` value greater than `1`. It skips
    the `should` group for the view, which can return more rows than the complete
    filter would, and returns this warning:
    ```text
    The request filter could not be fully applied to view(s); the following Query DSL constructs are not supported and were skipped: [bool[minimum_should_match=2]] on view [sales_by_region]. Use a WHERE clause to filter rows from views instead
    ```
  </applies-item>

  <applies-item title="stack: preview 9.4-9.5" applies-to="Elastic Stack: Preview from 9.4 to 9.5">
    A Query DSL filter on the request applies to the source indices in the view definition, not to the view output.
  </applies-item>
</applies-switch>


#### Aliases, data streams, and transform results

A view definition can read from index aliases and data streams. An alias cannot
point to a view.
An [Elasticsearch transform](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/4572/explore-analyze/transforms) is not an
ES|QL source. To query transform results from a view, use the transform's
destination index as the source in the view definition.

#### Data Federation datasets

<applies-to>
  - Elastic Cloud Serverless: Unavailable
  - Elastic Stack: Experimental in 9.5
</applies-to>

A view definition can read from a [dataset](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/esql-data-federation-datasets), which [ES|QL Data Federation](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/esql-data-federation) uses to query external data.
<applies-to>Elastic Stack: Planned</applies-to> A wildcard in the view definition
matches datasets only when the view definition sets `wildcards_match_datasets`
to `true`.

#### Query settings

<applies-switch>
  <applies-item title="{ "stack": "ga 9.6+", "serverless": "ga" }" applies-to="Elastic Cloud Serverless: Generally available, Elastic Stack: Planned">
    Only the following settings are supported in a view definition:

    | Setting                                                                                                                                                                                   | Supported values                 |
    |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------|
    | [`unmapped_fields`](/elastic/docs-builder/docs/4572/reference/query-languages/esql/directives/set#esql-unmapped_fields)                                                                   | `DEFAULT`, `NULLIFY`, and `LOAD` |
    | [`wildcards_match_views`](/elastic/docs-builder/docs/4572/reference/query-languages/esql/directives/set#esql-wildcards_match_views)                                                       | `true` and `false`               |
    | [`wildcards_match_datasets`](/elastic/docs-builder/docs/4572/reference/query-languages/esql/directives/set#esql-wildcards_match_datasets) <applies-to>Elastic Stack: Planned</applies-to> | `true` and `false`               |
    <applies-to>Elastic Cloud Serverless: Preview, Elastic Stack: Planned</applies-to> `LOAD_ALL`
    is not supported in a view definition.All other settings, including `time_zone`, are rejected in a view definition.
  </applies-item>

  <applies-item title="stack: preview 9.4-9.5" applies-to="Elastic Stack: Preview from 9.4 to 9.5">
    A view definition can't contain a `SET` directive.
  </applies-item>
</applies-switch>


##### Settings across view boundaries

<applies-switch>
  <applies-item title="{ "stack": "ga 9.6+", "serverless": "ga" }" applies-to="Elastic Cloud Serverless: Generally available, Elastic Stack: Planned">
    The three settings supported in view definitions are scoped at every view
    boundary. Values from the calling query, request body, or an enclosing view
    don't enter the view. The cluster setting is used to set the default throughout
    the query, both inside and outside views. A value in a view definition overrides
    that default for its body, but doesn't enter a nested view. If neither is
    configured, the built-in default applies.Other query settings are rejected in a view definition, but aren't scoped to
    individual views. Their effective value for the calling query can apply while
    evaluating a view. For example, `time_zone` can apply inside a view.At a view boundary:
    - `unmapped_fields`: Fields loaded by an outer query are `null` for rows from a
      view unless the view produces those fields itself. If an outer setting would
      have loaded fields that the view doesn't produce, the response warning
      identifies the view and the fields that are `null`.
    - For each supported wildcard setting, exact names work regardless of the
      setting. A wildcard matches the corresponding target type only when the view
      definition sets the setting to `true`. If a `true` value from outside the view
      stops at the boundary and the wildcard would otherwise have matched targets,
      the response returns a warning that identifies the view and the missed
      matches.
  </applies-item>

  <applies-item title="stack: preview 9.4-9.5" applies-to="Elastic Stack: Preview from 9.4 to 9.5">
    The effective query settings apply throughout the query, including inside view
    bodies.
  </applies-item>
</applies-switch>


#### Query parameters

Query parameters are not allowed in a stored view definition. A calling query
can still use parameters in commands after `FROM view_name`, but those parameters
are not substituted into the view body.

#### Time series data in views

<applies-to>
  - Elastic Cloud Serverless: Generally available
  - Elastic Stack: Planned
</applies-to>

A view that starts with [`TS`](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/commands/ts)
must also contain a `STATS` command after it. A view without `STATS` is
rejected when you create or update it. This ensures the view returns plain
tabular results. A `PROMQL` view must also use an aggregation function.
Query a time series view with `FROM view_name`. A view name cannot be used as a
source in `TS` or `PROMQL`. An exact view name in one of those source commands is
rejected, and a wildcard source expression skips matching views.

#### Validation and dependencies

When you create or update a view, Elasticsearch validates its name, size, query
syntax, and the settings that are allowed in a view definition.
<applies-to>Elastic Cloud Serverless: Generally available, Elastic Stack: Planned</applies-to> For a time series
view, Elasticsearch also validates that `TS` is followed by `STATS`.
Elasticsearch doesn't resolve or execute the query, and it doesn't check
whether referenced indices, fields, datasets, or views exist, or whether nested
views form a cycle. Creation doesn't return warnings for those problems.
Elasticsearch reports them when you query the view.
Deleting a resource doesn't check whether a view depends on it. Deleting an index, data stream, alias, dataset, or nested view can therefore cause existing views to fail when queried.

## Compare views, subqueries, and FORK

For a detailed comparison of views, subqueries, and `FORK`, refer to [Combine and reuse ES|QL queries](/elastic/docs-builder/docs/4572/reference/query-languages/esql/esql-combine-reuse-queries#comparing-views-subqueries-and-fork).

## Related pages

- [ES|QL subqueries](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/esql-subquery): nest queries inside other queries, in `FROM` or with `IN` / `NOT IN`.
- [`FROM` command](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/commands/from): full reference for index expressions, where view names are used.
- [Query multiple indices](https://www.elastic.co/elastic/docs-builder/docs/4572/reference/query-languages/esql/esql-multi-index): how index patterns, wildcards, and date math combine sources in a single `FROM`.