---
title: ES|QL FUSE command
description: 
url: https://www.elastic.co/docs/reference/query-languages/esql/commands/fuse
products:
  - Elasticsearch
---

# ES|QL FUSE command
<applies-to>
  - Elastic Cloud Serverless: Preview
  - Elastic Stack: Preview since 9.2
</applies-to>

The `FUSE` [processing command](https://www.elastic.co/docs/reference/query-languages/esql/commands/processing-commands) merges rows from multiple result sets and assigns
new relevance scores.
`FUSE` enables [hybrid search](/docs/reference/query-languages/esql/esql-search-tutorial#perform-hybrid-search) to combine and score results from multiple queries, together with the [`FORK`](https://www.elastic.co/docs/reference/query-languages/esql/commands/fork) command.
`FUSE` works by:
1. Merging rows with matching `<key_columns>` values
2. Assigning new relevance scores using the specified `<fuse_method>` algorithm
   and the values from the `<group_column>` and `<score_column>`

<tip>
  `FUSE` is for search use cases: it merges ranked result sets and computes relevance.
  Learn more about [how search works in ES|QL](https://www.elastic.co/docs/solutions/search/esql-for-search#how-search-works-in-esql).
</tip>

A `LIMIT` is required before `FUSE`, because `FUSE` can only work with a finite set of rows.
<applies-switch>
  <applies-item title="{ serverless: ga , stack: ga 9.4+ }" applies-to="Elastic Cloud Serverless: Generally available, Elastic Stack: Generally available since 9.4">
    `FORK` branches do not have an implicit `LIMIT 1000`.
    When using `FUSE` after `FORK`, a `LIMIT` must be added to each `FORK` branch.
  </applies-item>

  <applies-item title="stack: preview 9.1-9.3" applies-to="Elastic Stack: Preview from 9.1 to 9.3">
    An implicit `LIMIT 1000` is added to each `FORK` branch.
    When using `FUSE` after `FORK`, `FUSE` does not require an explicit `LIMIT` in each `FORK` branch.
    However, as a best practice and to avoid issues when upgrading to newer versions, it is advised to still add an explicit `LIMIT` before `FUSE`.
  </applies-item>
</applies-switch>


## Syntax

Use default parameters:
```esql
FUSE
```

Specify custom parameters:
```esql
FUSE <fuse_method> SCORE BY <score_column> GROUP BY <group_column> KEY BY <key_columns> WITH <options>
```


## Parameters

<definitions>
  <definition term="fuse_method">
    Defaults to `RRF`. Can be one of `RRF` (for [Reciprocal Rank Fusion](https://cormack.uwaterloo.ca/cormacksigir09-rrf.pdf)) or `LINEAR` (for linear combination of scores).
    Designates which method to use to assign new relevance scores.
  </definition>
  <definition term="options">
    Options for the `fuse_method`.
  </definition>
</definitions>

<tab-set>
  <tab-item title="RRF">
    When `fuse_method` is `RRF`, `options` supports the following parameters:
    <definitions>
      <definition term="rank_constant">
        Defaults to `60`. Represents the `rank_constant` used in the RRF formula.
      </definition>
      <definition term="weights">
        Defaults to `{}`. Allows you to set different weights for RRF scores based on `group_column` values. Refer to the [Set custom weights](#set-custom-weights) example.
      </definition>
    </definitions>
  </tab-item>

  <tab-item title="LINEAR">
    When `fuse_method` is `LINEAR`, `options` supports the following parameters:
    <definitions>
      <definition term="normalizer">
        Defaults to `none`. Can be one of `none` or `minmax`. Specifies which score normalization method to apply.
      </definition>
      <definition term="weights">
        Defaults to `{}`. Allows you to different weights for scores based on `group_column` values. Refer to the [Set custom weights](#set-custom-weights) example.
      </definition>
    </definitions>
  </tab-item>
</tab-set>

<definitions>
  <definition term="score_column">
    Defaults to `_score`. Designates which column to use to retrieve the relevance scores of the input row
    and where to output the new relevance scores of the merged rows.
  </definition>
  <definition term="group_column">
    Defaults to `_fork`. Designates which column represents the result set.
  </definition>
  <definition term="key_columns">
    Defaults to `_id, _index`. Rows with matching `key_columns` values are merged.
  </definition>
</definitions>


## Examples

The following examples use `FORK` to run parallel queries and `FUSE` to merge the results.

### Use RRF

Run a lexical and a semantic query in parallel with `FORK`, then merge with `FUSE` (applies `RRF` by default):
```esql
FROM books METADATA _id, _index, _score 
| FORK (WHERE title:"Shakespeare" | SORT _score DESC | LIMIT 100) 
       (WHERE semantic_title:"Shakespeare" | SORT _score DESC | LIMIT 100) 
| FUSE 
| SORT _score DESC
```


### Use linear combination

`FUSE` can also use linear score combination:
```esql
FROM books METADATA _id, _index, _score
| FORK (WHERE title:"Shakespeare" | SORT _score DESC | LIMIT 100) 
       (WHERE semantic_title:"Shakespeare" | SORT _score DESC | LIMIT 100) 
| FUSE LINEAR 
| SORT _score DESC
```


### Normalize scores

When combining results from semantic and lexical queries through linear combination, we recommend first normalizing the scores from each result set.
The following example uses `minmax` score normalization.
This means the scores normalize and assign values between 0 and 1, before combining the rows:
```esql
FROM books METADATA _id, _index, _score
| FORK (WHERE title:"Shakespeare" | SORT _score DESC | LIMIT 100) 
       (WHERE semantic_title:"Shakespeare" | SORT _score DESC | LIMIT 100) 
| FUSE LINEAR WITH { "normalizer": "minmax" } 
| SORT _score DESC
```


### Set custom weights

`FUSE` allows you to specify different weights to scores, based on the `_fork` column values, enabling you to control the relative importance of each query branch in the final results.
```esql
FROM books METADATA _id, _index, _score
| FORK (WHERE title:"Shakespeare" | SORT _score DESC | LIMIT 100) 
       (WHERE semantic_title:"Shakespeare" | SORT _score DESC | LIMIT 100) 
| FUSE LINEAR WITH { "weights": { "fork1": 0.7, "fork2": 0.3 }, "normalizer": "minmax" } 
| SORT _score DESC
```


## Limitations

These limitations can be present either when:
- `FUSE` is not combined with [`FORK`](https://www.elastic.co/docs/reference/query-languages/esql/commands/fork)
- `FUSE` doesn't use the default  [metadata](https://www.elastic.co/docs/reference/query-languages/esql/esql-metadata-fields) columns `_id`, `_index`, `_score` and `_fork`
  1. `FUSE` assumes that `key_columns` are single valued. When `key_columns` are multivalued, `FUSE` can produce unreliable relevance scores.
2. `FUSE` automatically assigns a score value of `NULL` if the `<score_column>` or `<group_column>` are multivalued.
3. `FUSE` assumes that the combination of `key_columns` and `group_column` is unique. If not, `FUSE` can produce unreliable relevance scores.