Loading

RRF retriever

Serverless Stack

An RRF retriever returns top documents based on the RRF formula, combining two or more child retrievers. Reciprocal rank fusion (RRF) is a method for combining multiple result sets with different relevance indicators into a single result set.

Note

Either query or retrievers must be specified. Combining query and retrievers is not supported.

query Stack 9.1.0

(Optional, String)

The query to use when using the multi-field query format.

fields Stack 9.1.0

(Optional, array of strings)

The fields to query when using the multi-field query format. If not specified, uses the index's default fields from the index.query.default_field index setting, which is * by default.

retrievers

(Optional, array of retriever objects)

A list of child retrievers to specify which sets of returned top documents will have the RRF formula applied to them. Each retriever can optionally include a weight to adjust its influence on the final ranking. Stack 9.2.0

When weights are specified, the final RRF score is calculated as:

rrf_score = weight_1 × rrf_score_1 + weight_2 × rrf_score_2 + ... + weight_n × rrf_score_n
		

where rrf_score_i is the RRF score for document from retriever i, and weight_i is the weight for that retriever.

rank_constant

(Optional, integer)

This value determines how much influence documents in individual result sets per query have over the final ranked result set. A higher value indicates that lower ranked documents have more influence. This value must be greater than or equal to 1. Defaults to 60.

rank_window_size

(Optional, integer)

This value determines the size of the individual result sets per query. A higher value will improve result relevance at the cost of performance. The final ranked result set is pruned down to the search request’s size. rank_window_size must be greater than or equal to size and greater than or equal to 1. Defaults to 10.

filter

(Optional, query object or list of query objects)

Applies the specified boolean query filter to all of the specified sub-retrievers, according to each retriever’s specifications.

Each entry in the retrievers array can be specified using the direct format or the wrapped format. Stack 9.2.0

Direct format (default weight of 1.0):

{
  "rrf": {
    "retrievers": [
      {
        "standard": {
          "query": {
            "multi_match": {
              "query": "search text",
              "fields": ["field1", "field2"]
            }
          }
        }
      },
      {
        "knn": {
          "field": "vector",
          "query_vector": [1, 2, 3],
          "k": 10,
          "num_candidates": 50
        }
      }
    ]
  }
}
		

Wrapped format with custom weights Stack 9.2.0 :

{
  "rrf": {
    "retrievers": [
      {
        "retriever": {
          "standard": {
            "query": {
              "multi_match": {
                "query": "search text",
                "fields": ["field1", "field2"]
              }
            }
          }
        },
        "weight": 2.0
      },
      {
        "retriever": {
          "knn": {
            "field": "vector",
            "query_vector": [1, 2, 3],
            "k": 10,
            "num_candidates": 50
          }
        },
        "weight": 1.0
      }
    ]
  }
}
		

In the wrapped format:

retriever

(Required, a retriever object)

Specifies a child retriever. Any valid retriever type can be used (e.g., standard, knn, text_similarity_reranker, etc.).

weight Stack 9.2.0

(Optional, float)

The weight that each score of this retriever's top docs will be multiplied in the RRF formula. Higher values increase this retriever's influence on the final ranking. Must be non-negative. Defaults to 1.0.

A simple hybrid search example (lexical search + dense vector search) combining a standard retriever with a knn retriever using RRF:

				GET /restaurants/_search
					{
  "retriever": {
    "rrf": {
      "retrievers": [
        {
          "standard": {
            "query": {
              "multi_match": {
                "query": "Austria",
                "fields": [
                  "city",
                  "region"
                ]
              }
            }
          }
        },
        {
          "knn": {
            "field": "vector",
            "query_vector": [10, 22, 77],
            "k": 10,
            "num_candidates": 10
          }
        }
      ],
      "rank_constant": 1,
      "rank_window_size": 50
    }
  }
}
		
  1. Defines a retriever tree with an RRF retriever.
  2. The sub-retriever array.
  3. The first sub-retriever is a standard retriever.
  4. The second sub-retriever is a knn retriever.
  5. The rank constant for the RRF retriever.
  6. The rank window size for the RRF retriever.

Stack 9.2.0

This example demonstrates how to use weights to adjust the influence of different retrievers in the RRF ranking. In this case, we're giving the standard retriever more importance (weight 2.0) compared to the knn retriever (weight 1.0):

				GET /restaurants/_search
					{
  "retriever": {
    "rrf": {
      "retrievers": [
        {
          "retriever": {
            "standard": {
              "query": {
                "multi_match": {
                  "query": "Austria",
                  "fields": ["city", "region"]
                }
              }
            }
          },
          "weight": 2.0
        },
        {
          "retriever": {
            "knn": {
              "field": "vector",
              "query_vector": [10, 22, 77],
              "k": 10,
              "num_candidates": 10
            }
          },
          "weight": 1.0
        }
      ],
      "rank_constant": 60,
      "rank_window_size": 50
    }
  }
}
		
  1. The first retriever in weighted format.
  2. This retriever has a weight of 2.0, giving it twice the influence of the kNN retriever.
  3. The second retriever in weighted format.
  4. This retriever has a weight of 1.0 (default weight).
Note

You can mix weighted and non-weighted formats in the same query. The direct format (without explicit retriever wrapper) uses the default weight of 1.0:

{
  "rrf": {
    "retrievers": [
      { "standard": { "query": {...} } },
      { "retriever": { "knn": {...} }, "weight": 2.0 }
    ]
  }
}
		

In this example, the standard retriever uses weight 1.0 (default), while the knn retriever uses weight 2.0.

A more complex hybrid search example (lexical search + ELSER sparse vector search + dense vector search) using RRF:

				GET movies/_search
					{
  "retriever": {
    "rrf": {
      "retrievers": [
        {
          "standard": {
            "query": {
              "sparse_vector": {
                "field": "plot_embedding",
                "inference_id": "my-elser-model",
                "query": "films that explore psychological depths"
              }
            }
          }
        },
        {
          "standard": {
            "query": {
              "multi_match": {
                "query": "crime",
                "fields": [
                  "plot",
                  "title"
                ]
              }
            }
          }
        },
        {
          "knn": {
            "field": "vector",
            "query_vector": [10, 22, 77],
            "k": 10,
            "num_candidates": 10
          }
        }
      ]
    }
  }
}