﻿---
title: ES|QL HIGHLIGHT command
description: 
url: https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/commands/highlight
products:
  - Elasticsearch
---

# ES|QL HIGHLIGHT command
<applies-to>
  - Elastic Cloud Serverless: Generally available
  - Elastic Stack: Planned
</applies-to>

The `HIGHLIGHT` [processing command](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/commands/processing-commands)
extracts and highlights matching text snippets from one or more fields based on a
full-text query. Matching terms are wrapped in highlight tags, bringing the
highlighting features of the Elasticsearch
[`_search` API](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/elasticsearch/rest-apis/highlighting) to ES|QL.

## Syntax

```esql
HIGHLIGHT [prefix = "<prefix>"] [query] [ON field [, field, ...] | ON *] [WITH { "option": value [, ...] }]
```


## Parameters

<definitions>
  <definition term="prefix">
    (Optional) A quoted string literal used to name the output columns. Each
    highlighted field is written to `<prefix><field>`. Defaults to `highlight_` (for
    example, `HIGHLIGHT "fox" ON content` produces `highlight_content`). If a generated
    column name matches an existing column, the existing column is replaced. To
    overwrite the source column in place, specify an empty prefix (`prefix = ""`).
    Unlike the query and the `WITH` option values, `prefix` cannot be a query parameter.
  </definition>
  <definition term="query">
    (Optional) The query used to find matching terms to highlight. This can be a
    string literal (which uses
    [`query_string`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/query-dsl/query-dsl-query-string-query)
    syntax) or a full-text search function such as
    [`MATCH`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/functions-operators/search-functions/match),
    [`MATCH_PHRASE`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/functions-operators/search-functions/match_phrase),
    [`QSTR`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/functions-operators/search-functions/qstr),
    [`KQL`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/functions-operators/search-functions/kql),
    or the [match operator `:`](/elastic/docs-builder/docs/4371/reference/query-languages/esql/functions-operators/operators#esql-match-operator).
    You can combine full-text functions using `AND`, `OR`, and `NOT`.
    If you don't specify a query, `HIGHLIGHT` automatically reuses full-text
    search conditions from earlier [`WHERE`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/commands/where)
    commands in the query. Refer to [Reuse a query from WHERE](#esql-highlight-implicit-query).
    When you provide both a query and an `ON` clause, any field named in your
    query must also be listed in `ON`. For example,
    `HIGHLIGHT MATCH(title, "fox") ON body` is rejected because `title` is not in
    `ON`. When you let ES|QL determine the query or fields automatically, it
    handles this check for you.
    Unqualified string literals and `QSTR` expressions are evaluated against
    whichever fields are being highlighted. Queries without positive search
    conditions (such as `NOT MATCH(...)`) have no terms to highlight and return
    `null`, unless you configure `no_match_size`.
  </definition>
  <definition term="field">
    (Optional) One or more comma-separated columns to highlight, or `*` to
    highlight every `text` and `keyword` column in the table. Fields must be `text`
    or `keyword` types (`semantic_text` fields are supported and treated as `text`).
    You can only use `*` by itself; wildcard patterns like `title*` and combining
    `*` with specific field names (such as `ON *, title`) are not supported.
    If you omit `ON`, `HIGHLIGHT` determines which columns to highlight based on
    your query:
    - For queries targeting a specific column (such as `MATCH` or `MATCH_PHRASE`),
      only that column is highlighted.
    - For queries that don't target a single column (such as string literals,
      `QSTR`, or `KQL`), `HIGHLIGHT` checks all `text` and `keyword` columns in
      the table.
    Refer to [Choose fields with ON](#esql-highlight-on-fields). If a field has no
    matching terms, its output is `null` unless you set `no_match_size`.
  </definition>
</definitions>


## WITH options

All option values passed in the `WITH` clause must be constants. Both literals and
[query parameters](/elastic/docs-builder/docs/4371/reference/query-languages/esql/esql-rest#esql-rest-params) that
resolve to a literal are accepted; column references are not.
<definitions>
  <definition term="pre_tags">
    (Optional) Opening tag inserted before each highlighted term. Accepts a string
    or a single-element array of strings. Defaults to `<em>`. Multiple rotating
    tags are not supported. At most 256 characters.
  </definition>
  <definition term="post_tags">
    (Optional) Closing tag inserted after each highlighted term. Accepts a string
    or a single-element array of strings. Defaults to `</em>`. At most 256
    characters.
  </definition>
  <definition term="encoder">
    (Optional) Text encoding applied before adding highlight tags. Accepts
    `default` (no encoding) or `html` (HTML-escapes snippet text). Defaults to
    `default`. As in the `_search` API, this value is case-sensitive, so `html` is valid
    but `HTML` is rejected. `boundary_scanner` and `order` are case-insensitive.
  </definition>
  <definition term="analyzer">
    (Optional) Analyzer to use across all highlighted fields, overriding each
    field's own analyzer. Also analyzes query terms, unless a full-text search
    function specifies its own `analyzer`. When omitted, `HIGHLIGHT` uses each
    field's analyzer (see [Choose an analyzer](#esql-highlight-analyzer)).
    Only built-in and node-level plugin analyzers are supported.
  </definition>
  <definition term="number_of_fragments">
    (Optional) Maximum number of snippets (fragments) to return per field. Set to `0` to return the entire
    field value with matching terms highlighted without fragmenting. Must be `>= 0`.
    Defaults to `5`.
  </definition>
  <definition term="fragment_size">
    (Optional) Approximate character length of each snippet. Must be `>= 0`.
    Defaults to `100`.
  </definition>
  <definition term="no_match_size">
    (Optional) Approximate number of leading characters to return from the field
    when there are no matching terms. This is a minimum, not an exact limit: the
    returned text extends to the next boundary set by `boundary_scanner`, so the
    result can be longer than the requested size. Must be `>= 0`. Defaults to `0`
    (returns `null`).
  </definition>
  <definition term="boundary_scanner">
    (Optional) Boundary scanner used to split text into fragments. Accepts
    `sentence` or `word`, case-insensitively. Defaults to `sentence`.
  </definition>
  <definition term="boundary_scanner_locale">
    (Optional) Locale used by the boundary scanner, given as an
    [IETF BCP 47](https://www.rfc-editor.org/info/bcp47) language tag such as `en-US` or
    `ja-JP`. Use hyphens as separators. Defaults to the root locale. This is the same
    format accepted by the `_search` API's
    [`boundary_scanner_locale`](/elastic/docs-builder/docs/4371/reference/elasticsearch/rest-apis/highlighting-settings#boundary_scanner_locale).
  </definition>
  <definition term="order">
    (Optional) Sort order of returned fragments. Accepts `none` (preserves document
    order) or `score` (orders fragments by descending relevance score),
    case-insensitively. Defaults to `none`.
  </definition>
  <definition term="max_analyzed_offset">
    (Optional) Maximum number of characters to analyze per field value. Accepts a
    positive integer, or `-1` to leave the limit unset. Defaults to `-1`.
    `HIGHLIGHT` analyzes at most 1 million characters per field value regardless of
    this setting, and the index's `index.highlight.max_analyzed_offset` setting does
    not apply. Text beyond the effective offset is not highlighted.
  </definition>
</definitions>


## Description

Use `HIGHLIGHT` to find and display matching snippets in text fields, typically
after filtering rows with a full-text search condition in `WHERE`.
`HIGHLIGHT` processes each row, analyzes the specified text fields against the
query, and generates new keyword columns containing matching terms wrapped in
highlight tags. By default, output columns are named `highlight_<field>`. If a
field contains no matching terms, the result is `null` unless you specify
`no_match_size`.
Because `HIGHLIGHT` re-analyzes text values at query time, you can highlight
source fields from an index as well as computed columns created by earlier
commands like `EVAL`, `DISSECT`, `GROK`, `STATS`, `ENRICH`, or `LOOKUP JOIN`.
Index `text` fields use their mapped analyzer, while computed and other columns
default to `standard` unless overridden. Refer to
[Choose an analyzer](#esql-highlight-analyzer).
For multivalued fields, each value is highlighted independently:
- Phrase queries and fragment boundaries do not cross values.
- When a field produces multiple fragments, the output column contains a multivalued list of snippets.
- Multivalued `keyword` fields loaded from doc values are sorted and deduplicated before highlighting, which can result in a different snippet order compared to the `_search` API.


### Reuse a query from WHERE

Most search queries filter rows with a full-text condition in `WHERE`, then
highlight matching terms in those same fields. To avoid repeating your search
query, you can omit the query from `HIGHLIGHT`. When you do, `HIGHLIGHT`
automatically finds and reuses full-text search conditions from earlier
[`WHERE`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/commands/where) commands.
This works with any positive full-text search function, including
[`MATCH`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/functions-operators/search-functions/match),
[`MATCH_PHRASE`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/functions-operators/search-functions/match_phrase),
[`QSTR`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/functions-operators/search-functions/qstr),
[`KQL`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/functions-operators/search-functions/kql),
and the match operator `:`.
You can include intermediate commands between `WHERE` and `HIGHLIGHT` as long as
each row still represents an individual document. For example, commands like
`KEEP`, `DROP`, `RENAME`, `EVAL`, `GROK`, `DISSECT`, `LIMIT`, `SORT`,
`MV_EXPAND`, and `INLINE STATS` pass through without issue.
However, commands that summarize, aggregate, or join rows—such as `STATS`,
`LOOKUP JOIN`, or `FORK`—change the document context. If you use any of these
commands between `WHERE` and `HIGHLIGHT`, you must provide the query explicitly
in `HIGHLIGHT`.
If your query contains multiple `WHERE` clauses, `HIGHLIGHT` combines all of
their full-text search conditions so that every searched field can produce
snippets, even though the `WHERE` clauses filter your rows together using `AND`.
The following search conditions cannot be automatically reused:
- Negated conditions, such as `NOT MATCH(...)` (there are no positive matches to highlight)
- Conditions combined with non-text filters using `OR`, such as `MATCH(title, "fox") OR year > 2020`

If your query relies solely on conditions that cannot be reused, specify the
query explicitly in `HIGHLIGHT`.
If you provide an explicit query in `HIGHLIGHT`, it takes precedence, and any
conditions from earlier `WHERE` commands are ignored for highlighting.

### Choose fields with ON

The `ON` clause specifies which columns to highlight. You can choose specific
columns, highlight all available text columns, or let ES|QL determine the
columns automatically:
- **Highlight specific fields**: Use `ON field1, field2` to highlight only the
  specified columns.
- **Highlight all text and keyword fields**: Use `ON *` to highlight every
  `text` and `keyword` column in the current table, including multi-fields
  (such as `author.keyword`) and `semantic_text` fields (highlighted lexically).
  Metadata columns such as `_id` and `_index` are not included.
- **Let ES|QL determine fields**: If you omit `ON`, `HIGHLIGHT` chooses the
  columns based on your query:
  - If the query targets a specific field (such as `MATCH(title, "fox")`),
  only that field is highlighted.
- If the query does not name a specific field (such as a string literal,
  `QSTR`, or `KQL`), `HIGHLIGHT` checks all `text` and `keyword` columns in
  the table.

If a highlighted field does not match any query terms, its output is `null`
(or the leading text specified by `no_match_size`). If ES|QL cannot find any
eligible `text` or `keyword` columns to highlight, you must provide an explicit
`ON` clause.

### Choose an analyzer

`HIGHLIGHT` analyzes each field with its own analyzer, using the first rule that
applies:
- The `analyzer` option in the `WITH` clause (overrides all `ON` fields).
- For an index `text` field, its mapped
  [`analyzer`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/elasticsearch/mapping-reference/analyzer) or the
  index default analyzer.
- For a column created with
  [`TO_TEXT`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/functions-operators/type-conversion-functions/to_text),
  the analyzer set in its `analyzer` option.
- The `standard` analyzer for all other columns, including `keyword` fields.

An index `text` field keeps its mapped analyzer when you rename it with
`RENAME`, copy it with `EVAL` (such as `EVAL t = title`), group by it with
`STATS` or `INLINE STATS` (such as `BY t = title`), or pass it unchanged
through [`FORK`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/commands/fork),
[`FUSE`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/commands/fuse), or
[subqueries in `FROM`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/esql-from-subquery).
Columns computed from expressions do not inherit a mapped analyzer. They use
the analyzer declared with `TO_TEXT`, or default to `standard`. To analyze a
computed column like the original field, set the `analyzer` option in `WITH`.
If the queried indices map a field with different analyzers, each row uses the
analyzer of the index it comes from.
`HIGHLIGHT` returns an error when:
- Queried indices map the field with different analyzers and `HIGHLIGHT` cannot
  determine which index supplied the value (for example, after `STATS`, `DEDUP`,
  or a `FUSE` whose `KEY BY` includes neither `_index` nor a copy of it, or
  across a `LOOKUP JOIN`).
- Branches of `FORK`, or subqueries in `FROM`, define conflicting analyzers for
  the same column (for example, when one branch reads the field from an index and
  another computes the column with a different analyzer).

To resolve this, set the `analyzer` option in the `WITH` clause. For a computed
column, you can instead set the `analyzer` option of `TO_TEXT` to match the
analyzer of the index field.
Analyzers defined in index settings, and analyzers that are not reported, fall
back to `standard` with a warning, as described later in this section. If
another queried index uses an analyzer that does not fall back, the field still
counts as having different analyzers.
Query terms use the target field's analyzer. An `analyzer` specified on a
full-text search function, such as
`MATCH(title, "rings", {"analyzer": "whitespace"})`, applies only to the query
text. If the query and field analyzers produce different tokens, some matches
might not be highlighted.
`HIGHLIGHT` falls back to `standard` and returns a warning when:
- The analyzer is defined in index settings (such as a custom analyzer or
  index-level default) rather than globally on the node.
- The analyzer is not registered on the coordinating node (for example, because
  a required plugin is missing).
- The field type does not report an analyzer, such as `semantic_text` or
  `pattern_text`.

When falling back to `standard`, highlights might not match the terms that
matched your search. To avoid the warning, set the `analyzer` option in the
`WITH` clause.
<tip>
  Learn more about using [ES|QL for search use cases](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/4371/solutions/search/esql-for-search).
</tip>


## Limitations

- `HIGHLIGHT` supports only built-in and node-level plugin analyzers. Specifying an analyzer defined in index settings in `WITH` or in a full-text search function returns an error. If an implicitly reused `WHERE` query references an unsupported analyzer, write the query explicitly in `HIGHLIGHT` without that `analyzer` option.
- `HIGHLIGHT` ignores [`search_analyzer`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/elasticsearch/mapping-reference/search-analyzer) and [`search_quote_analyzer`](/elastic/docs-builder/docs/4371/reference/elasticsearch/mapping-reference/analyzer#search-quote-analyzer) settings. Because query terms are analyzed with the field's index analyzer, fields configured with separate search analyzers might produce unexpected highlights. To analyze query terms with a different analyzer, specify the `analyzer` option on the full-text search function.
- On `keyword` fields, `HIGHLIGHT` tokenizes text using the `standard` analyzer and breaks it into snippets like a `text` field, rather than treating the value as a single atomic term.
- On `semantic_text` fields, `HIGHLIGHT` only performs lexical matching against the underlying text. Pure semantic vector matches that lack literal term overlap are not highlighted.
- Fields are analyzed up to a maximum of 1 million characters. Text beyond this limit is not analyzed or highlighted.
- `HIGHLIGHT` cannot automatically reuse a `WHERE` query across commands that aggregate, summarize, or join rows, such as `STATS`, `LOOKUP JOIN`, or `FORK`. In those queries, specify the query directly on `HIGHLIGHT`.
- If you drop a field targeted by the reused `WHERE` query before `HIGHLIGHT`, the implicit query can no longer highlight that field. If no other reusable fields remain, provide an explicit query and `ON` clause using columns that are still in scope.


## Examples

The following examples show common ways to highlight search terms and customize snippet output.

### Highlight matches in a field

Wrap matching terms in the default `<em>` tags:
```esql
ROW content = "The quick brown fox jumps over the lazy dog."
| HIGHLIGHT "fox" ON content
| KEEP highlight_content
```


| highlight_content:keyword                             |
|-------------------------------------------------------|
| The quick brown <em>fox</em> jumps over the lazy dog. |


### Highlight search results

Filter rows with a `WHERE` clause, then highlight matching terms in the output.
You can specify the search condition again in `HIGHLIGHT`:
```esql
FROM books
| WHERE MATCH(title, "Return")
| HIGHLIGHT "return" ON title
| KEEP book_no, highlight_title
| SORT book_no
```


| book_no:keyword | highlight_title:keyword                                                   |
|-----------------|---------------------------------------------------------------------------|
| 2714            | <em>Return</em> of the King Being the Third Part of The Lord of the Rings |
| 7350            | <em>Return</em> of the Shadow                                             |


### Automatically reuse a WHERE condition

To avoid repeating your search query, omit the query from `HIGHLIGHT`. When you
also omit `ON`, `HIGHLIGHT` automatically highlights matches in the field
searched by `WHERE` (in this case, creating `highlight_title`):
```esql
FROM books
| WHERE MATCH(title, "Return")
| HIGHLIGHT
| KEEP title, highlight_title
| SORT title
```


| title:text                                                       | highlight_title:keyword                                                   |
|------------------------------------------------------------------|---------------------------------------------------------------------------|
| Return of the King Being the Third Part of The Lord of the Rings | <em>Return</em> of the King Being the Third Part of The Lord of the Rings |
| Return of the Shadow                                             | <em>Return</em> of the Shadow                                             |

To reuse the `WHERE` condition but choose which columns to highlight, provide
an explicit `ON` clause:
```esql
FROM books
| WHERE MATCH(title, "Return")
| HIGHLIGHT ON title
| KEEP book_no, highlight_title
| SORT book_no
```


| book_no:keyword | highlight_title:keyword                                                   |
|-----------------|---------------------------------------------------------------------------|
| 2714            | <em>Return</em> of the King Being the Third Part of The Lord of the Rings |
| 7350            | <em>Return</em> of the Shadow                                             |


### Highlight without an ON clause

When your query targets a specific field (such as `MATCH`), you can omit `ON`.
Only that field is highlighted, leaving other columns untouched:
```esql
ROW title = "Return of the King", body = "An ordinary description."
| HIGHLIGHT MATCH(title, "king")
```


| title:keyword      | body:keyword             | highlight_title:keyword     |
|--------------------|--------------------------|-----------------------------|
| Return of the King | An ordinary description. | Return of the <em>King</em> |

When you use a query that doesn't target a specific field, such as a string
literal or `QSTR`, omitting `ON` highlights all `text` and `keyword` columns:
```esql
ROW title = "Return of the King", body = "Tolkien wrote the epic saga."
| HIGHLIGHT "tolkien"
| KEEP highlight_title, highlight_body
```


| highlight_title:keyword | highlight_body:keyword                |
|-------------------------|---------------------------------------|
| null                    | <em>Tolkien</em> wrote the epic saga. |


### Highlight all text and keyword fields with ON *

Use `ON *` to highlight every `text` and `keyword` column in the table at once.
Columns that do not match the query evaluate to `null`:
```esql
ROW title = "Return of the King", body = "An ordinary description."
| HIGHLIGHT MATCH(title, "king") ON *
| KEEP highlight_title, highlight_body
```


| highlight_title:keyword     | highlight_body:keyword |
|-----------------------------|------------------------|
| Return of the <em>King</em> | null                   |


### Highlight phrases with MATCH_PHRASE

Use a full-text function like `MATCH_PHRASE` to highlight an exact phrase in a single tag pair:
```esql
FROM books
| WHERE MATCH(title, "Return")
| HIGHLIGHT MATCH_PHRASE(title, "Return of the") ON title
| KEEP book_no, highlight_title
| SORT book_no
```


| book_no:keyword | highlight_title:keyword                                                   |
|-----------------|---------------------------------------------------------------------------|
| 2714            | <em>Return of the</em> King Being the Third Part of The Lord of the Rings |
| 7350            | <em>Return of the</em> Shadow                                             |


### Highlight with query string syntax (QSTR)

Use [`QSTR`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/functions-operators/search-functions/qstr) to highlight terms using Lucene query syntax with boolean operators and field qualifiers:
```esql
ROW title = "The quick fox", body = "A loyal dog"
| HIGHLIGHT QSTR("title:fox OR body:dog") ON title, body
| KEEP highlight_title, highlight_body
```


| highlight_title:keyword | highlight_body:keyword |
|-------------------------|------------------------|
| The quick <em>fox</em>  | A loyal <em>dog</em>   |


### Highlight with Kibana Query Language (KQL)

Use [`KQL`](https://www.elastic.co/elastic/docs-builder/docs/4371/reference/query-languages/esql/functions-operators/search-functions/kql) to highlight terms using Kibana Query Language syntax, optionally combined with other full-text functions:
```esql
FROM books
| WHERE MATCH(title, "Return")
| HIGHLIGHT KQL("title: shad*") OR (MATCH(title, "return") AND MATCH(title, "king")) ON title
| KEEP book_no, highlight_title
| SORT book_no
```


| book_no:keyword | highlight_title:keyword                                                            |
|-----------------|------------------------------------------------------------------------------------|
| 2714            | <em>Return</em> of the <em>King</em> Being the Third Part of The Lord of the Rings |
| 7350            | Return of the <em>Shadow</em>                                                      |


### Highlight with a field's mapped analyzer

`HIGHLIGHT` automatically uses each field's mapped analyzer. In this example, the `title` field in the `books_english` index uses the `english` analyzer, which stems `Rings` to `ring`. Even without extra options, `HIGHLIGHT` highlights `Rings` for the query term `ring`:
```esql
FROM books_english
| WHERE MATCH(title, "ring") AND book_no == "2714"
| HIGHLIGHT
| KEEP title, highlight_title
| SORT title
```


| title:text                                                       | highlight_title:keyword                                                   |
|------------------------------------------------------------------|---------------------------------------------------------------------------|
| Return of the King Being the Third Part of The Lord of the Rings | Return of the King Being the Third Part of The Lord of the <em>Rings</em> |


### Highlight with a language analyzer

Use the `analyzer` option to override the analyzer across all `ON` fields. This is especially useful for computed columns, which default to the `standard` analyzer. In this example, specifying the `english` analyzer stems `Rings` to match the query term `ring`:
```esql
ROW title = "The Lord of the Rings"
| HIGHLIGHT "ring" ON title WITH { "analyzer": "english" }
| KEEP highlight_title
```


| highlight_title:keyword        |
|--------------------------------|
| The Lord of the <em>Rings</em> |


### Highlight multiple fields

Highlight multiple columns at once by listing them in `ON`:
```esql
ROW title = "Return of the King", body = "Tolkien wrote the epic saga."
| HIGHLIGHT "king tolkien" ON title, body
| KEEP highlight_title, highlight_body
```


| highlight_title:keyword     | highlight_body:keyword                |
|-----------------------------|---------------------------------------|
| Return of the <em>King</em> | <em>Tolkien</em> wrote the epic saga. |


### Highlight an extracted or computed field

`HIGHLIGHT` re-analyzes field values at query time, so it works on columns created earlier in the pipeline:
```esql
ROW raw = "2024 Sauron Mordor"
| DISSECT raw "%{yr} %{name} %{place}"
| HIGHLIGHT "sauron" ON name
| KEEP name, highlight_name
```


| name:keyword | highlight_name:keyword |
|--------------|------------------------|
| Sauron       | <em>Sauron</em>        |


### HTML-encode text for safe display

Use `"encoder": "html"` to escape HTML tags and special characters in the text while keeping the highlight tags intact:
```esql
ROW content = "Use <b>bold</b> tags & special chars with the Ring."
| HIGHLIGHT "ring" ON content WITH { "encoder": "html" }
| KEEP highlight_content
```


| highlight_content:keyword                              |
|--------------------------------------------------------|
| Use bboldb tags  special chars with the <em>Ring</em>. |


### Return the full text without fragmenting

Set `"number_of_fragments": 0` to return the complete text value with matches highlighted rather than returning individual snippets:
```esql
ROW content = "Elasticsearch is fast. Elasticsearch is scalable. Elasticsearch is open."
| HIGHLIGHT "elasticsearch" ON content WITH { "number_of_fragments": 0 }
| KEEP highlight_content
```


| highlight_content:keyword                                                                           |
|-----------------------------------------------------------------------------------------------------|
| <em>Elasticsearch</em> is fast. <em>Elasticsearch</em> is scalable. <em>Elasticsearch</em> is open. |


### Customize highlight tags

Use `pre_tags` and `post_tags` to specify custom wrapping tags:
```esql
ROW content = "The quick brown fox jumps over the lazy dog."
| HIGHLIGHT "fox" ON content WITH { "pre_tags": ["<b>"], "post_tags": ["</b>"] }
| KEEP highlight_content
```


| highlight_content:keyword                           |
|-----------------------------------------------------|
| The quick brown <b>fox</b> jumps over the lazy dog. |


### Customize output column names

Use `prefix` to change the column name prefix:
```esql
ROW content = "The One Ring was forged by Sauron."
| HIGHLIGHT prefix = "hl_" "ring" ON content
| KEEP content, hl_content
```


| content:keyword                    | hl_content:keyword                          |
|------------------------------------|---------------------------------------------|
| The One Ring was forged by Sauron. | The One <em>Ring</em> was forged by Sauron. |


### Overwrite the original column

Set an empty prefix (`prefix = ""`) to replace the source column with the highlighted output:
```esql
ROW content = "The quick brown fox jumps over the lazy dog."
| HIGHLIGHT prefix = "" "fox" ON content
| KEEP content
```


| content:keyword                                       |
|-------------------------------------------------------|
| The quick brown <em>fox</em> jumps over the lazy dog. |


### Return leading text when nothing matches

By default, non-matching fields evaluate to `null`. Set `no_match_size` to return text from the start of the field instead:
```esql
ROW content = "Gardens and flowers bloom in spring."
| HIGHLIGHT "elasticsearch" ON content WITH { "no_match_size": 200 }
| KEEP highlight_content
```


| highlight_content:keyword            |
|--------------------------------------|
| Gardens and flowers bloom in spring. |


### Order snippets by relevance score

Use `"order": "score"` to sort snippets by relevance score rather than document order:
```esql
ROW content = ["fast search", "fast and fast results"]
| HIGHLIGHT "fast" ON content WITH { "order": "score" }
| KEEP highlight_content
```


| highlight_content:keyword                                       |
|-----------------------------------------------------------------|
| [<em>fast</em> and <em>fast</em> results, <em>fast</em> search] |