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.
Either query or retrievers must be specified.
Combining query and retrievers is not supported.
queryStack-
(Optional, String)
The query to use when using the multi-field query format.
fieldsStack-
(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_fieldindex 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
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_nwhere
rrf_score_iis the RRF score for document from retrieveri, andweight_iis 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 to60. 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_sizemust be greater than or equal tosizeand greater than or equal to1. 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
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 :
{
"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.). weightStack-
(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
}
}
}
- Defines a retriever tree with an RRF retriever.
- The sub-retriever array.
- The first sub-retriever is a
standardretriever. - The second sub-retriever is a
knnretriever. - The rank constant for the RRF retriever.
- The rank window size for the RRF retriever.
Stack
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
}
}
}
- The first retriever in weighted format.
- This retriever has a weight of 2.0, giving it twice the influence of the kNN retriever.
- The second retriever in weighted format.
- This retriever has a weight of 1.0 (default weight).
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
}
}
]
}
}
}