Hybrid Search: Combining BM25 and Vector Search With Reciprocal Rank Fusion
AI generated
_doc
_index
Elasticsearch · Hybrid Search · RRF
Hybrid Search: Combining BM25 and Vector Search
how Reciprocal Rank Fusion merges both rankings fairly

Pure vector search finds topically relevant results even when not a single word of the query appears in the document, but it occasionally loses exact term matches, such as a specific article number or brand name, that BM25 finds reliably. Pure text search, in turn, completely misses formulations that are semantically relevant but phrased differently. Hybrid search tries to combine the best of both worlds by merging two different rankings, one from BM25 and one from vector search, into a single result list. The technical challenge is that BM25 scores and vector distance values sit on completely different, incomparable scales. Reciprocal Rank Fusion solves this elegantly by combining not the scores themselves, but the relative rank positions. This article explains how RRF works, when hybrid search actually beats pure vector search, and how to configure the whole thing concretely in a single Elasticsearch query.

10 min read Reciprocal Rank Fusion Hybrid Search · BM25 + kNN

1. The core problem: incomparable score scales

BM25 computes a relevance score based on term frequency, inverse document frequency, and document length, and the resulting number is theoretically unbounded and depends heavily on the specific index and the specific query. A kNN score from a vector search, on the other hand, is based on a distance or similarity metric such as cosine similarity, which typically falls between zero and one. Adding or comparing these two numbers directly produces no meaningful value.

A naive approach would be to normalize both scores onto a shared scale, for example via min max normalization, before summing them with weights. That approach, however, is sensitive to outliers and unstable from query to query, because the minimum and maximum score values keep shifting depending on hit count and query content. Reciprocal Rank Fusion sidesteps this problem entirely by never trying to compare scores in the first place.

2. How Reciprocal Rank Fusion actually works

RRF completely ignores the absolute score values and instead only looks at the rank position where a document appears in each of the participating rankings. For every document, a fusion score is computed per ranking using the formula one divided by the sum of the rank position and a constant, and the fusion score contributions across all rankings are then summed up for each document.

A document that appears near the top of both rankings collects two high fusion score contributions and lands near the top of the combined result list as a result. A document that ranks very highly in only one of the two rankings, but does not appear in the other at all, still receives a solid combined score, because a single very good rank is enough to look relevant. This principle makes RRF robust against the differing score distributions of the two source rankings.


// RRF formula per document and ranking:
// score = 1 / (rank_constant + rank_in_this_ranking)
// total score = sum of the score values across all rankings

// Example with rank_constant = 60:
// Document A: rank 1 in BM25, rank 5 in kNN
// score_A = 1/(60+1) + 1/(60+5) = 0.01639 + 0.01538 = 0.03177

// Document B: rank 3 in BM25, rank 1 in kNN
// score_B = 1/(60+3) + 1/(60+1) = 0.01587 + 0.01639 = 0.03226

3. The role of rank_constant in weighting

The constant in the RRF formula, configurable in Elasticsearch as rank_constant and set to 60 by default, controls how strongly high rank positions are favored over lower ones. A smaller constant strongly amplifies the influence of the top ranks, because the formula's denominator is comparatively small for rank one, while a larger constant flattens the score differences between the first and the following ranks.

In practice, the default value of 60 delivers solid results for most use cases, and tuning is worthwhile mainly when it becomes apparent that a single ranking is systematically pulling too much or too little weight in the combined result list. Any adjustment should always be validated against concrete, documented test queries, not gut feeling.

4. Practical configuration: the retriever block with rrf

In modern Elasticsearch versions, RRF can be configured directly in the search request via the retriever mechanism, without having to implement your own fusion logic in the application. An rrf retriever accepts a list of sub retrievers, typically a standard retriever for the classic BM25 query and a knn retriever for the vector search, and automatically merges their results using the RRF formula.

This built-in mechanism significantly simplifies implementation compared to earlier Elasticsearch versions, where teams had to rebuild fusion themselves in the application layer, including their own logic for rank computation and score aggregation across two separate search requests.


GET products/_search
{
  "retriever": {
    "rrf": {
      "retrievers": [
        {
          "standard": {
            "query": {
              "match": { "description": "quiet stand mixer" }
            }
          }
        },
        {
          "knn": {
            "field": "description_embedding",
            "query_vector": [0.021, -0.153, 0.402, "..."],
            "k": 20,
            "num_candidates": 100
          }
        }
      ],
      "rank_constant": 60,
      "rank_window_size": 50
    }
  }
}

5. When hybrid search actually beats pure vector search

Pure vector search has a systematic weakness with exact, rare terms, such as specific article numbers, model names, or brand names, because an embedding model often does not distinguish such rare tokens precisely enough in vector space. BM25, by contrast, is optimized for exactly this case, since rare terms automatically receive a high weight. Hybrid search combines both strengths, keeping exact term matches reliably near the top while additionally pulling in semantically relevant but differently phrased results.

The advantage shows especially clearly with mixed queries that contain both a concrete term and a vague paraphrase, for example a search for Nike running shoe light and breathable. Pure vector search might underweight the brand name Nike here, while pure text search can barely make sense of the paraphrase light and breathable. Hybrid search typically delivers the overall most relevant result list in such cases.

6. rank_window_size and its influence on result quality

The rank_window_size parameter determines how many results from each individual sub retriever are considered for the fusion before the final, combined result list is returned. A value that is too small risks excluding relevant documents that rank not quite at the top in one of the two rankings but very high in the other, simply because they fall outside the considered window.

A value that is too large, on the other hand, unnecessarily increases compute cost without noticeably improving result quality in practice. A good starting point is a multiple of the number of results actually displayed, for example five to ten times, which is then fine tuned based on real search queries and observed result quality.

7. More than two rankings: RRF with three or more retrievers

The rrf retriever is not limited to exactly two sub retrievers, it accepts an arbitrary list, which makes it possible to combine, for example, a standard retriever for BM25, a knn retriever for dense vector search, and an additional retriever for ELSER based sparse vector search in a single request. Every additional ranking brings its own perspective on relevance without requiring a manual weight to be set between the individual rankings.

In practice, combining three rankings pays off especially when BM25 and dense vector search show systematically different weaknesses that a third, independently functioning ranking can partially offset. As the number of rankings grows, however, so does the compute cost per query, which is why every additional ranking should deliver a demonstrable, measured benefit rather than being added out of pure caution.


GET products/_search
{
  "retriever": {
    "rrf": {
      "retrievers": [
        { "standard": { "query": { "match": { "description": "quiet stand mixer" } } } },
        { "knn": { "field": "description_embedding", "query_vector": ["..."], "k": 20, "num_candidates": 100 } },
        { "standard": { "query": { "sparse_vector": { "field": "description_sparse", "inference_id": ".elser_model_2", "query": "quiet stand mixer" } } } }
      ],
      "rank_constant": 60,
      "rank_window_size": 50
    }
  }
}

8. Alternative: weighted linear combination instead of RRF

Besides RRF, Elasticsearch also supports a weighted linear combination of the normalized scores from both rankings, where each ranking is explicitly assigned a weight. This approach allows a finer, more explicitly controllable balance between the BM25 and vector share, but requires a deliberate decision about the normalization strategy and is more sensitive to outlier values than RRF.

In practice, RRF is usually the more pragmatic starting point, since it does not require a normalization decision and is robust against differing score distributions. A weighted linear combination is worthwhile once, after initial experience with RRF, there is a very specific, documented need to weight one of the two ranking shares more or less strongly than rank fusion alone allows.

9. Testing and monitoring: evaluating hybrid search measurably

The effect of hybrid search cannot be reliably judged through spot checks alone, it requires a systematic comparison based on a set of real search queries with known, relevance labeled results. Metrics such as Normalized Discounted Cumulative Gain or Mean Reciprocal Rank allow pure BM25 search, pure vector search, and hybrid search with different rank_constant values to be compared objectively against each other, instead of relying on subjective case by case judgment.

After going to production, it is worth continuously monitoring actual click behavior and conversion rates for search queries served through hybrid search, compared against a control group using pure BM25 search, to concretely demonstrate the actual business benefit of the added complexity rather than justifying it purely on technical grounds.

Criterion Pure BM25 search Pure vector search Hybrid search (RRF)
Exact term matches (SKU, brand) Very reliable Often underweighted Stays reliably preserved
Paraphrased, semantic queries Finds no matches Very strong Additionally taken into account
Score comparability Own scale Own scale Solved via rank position instead of score
Implementation effort Low Medium Low thanks to the retriever mechanism
Robustness against outliers Good Good Very good, since rank based

Mironsoft

Search index setup, relevance tuning, and Magento search

Magento search that shows the wrong products first?

We set up Elasticsearch or OpenSearch for Magento cleanly, tune relevance and facets to the actual catalog, and optimize indexing processes for large catalogs.

Relevance Tuning

Match search results and facets to actual customer needs.

Search Migration

Guide a clean migration from Solr or MySQL search to Elasticsearch/OpenSearch.

Index Performance

Make indexing processes for large catalogs reliable and performant.

10. Summary

Hybrid Search With RRF: The Essentials at a Glance

Core problem

BM25 scores and vector distance values sit on incomparable scales, direct addition or comparison produces no meaningful value.

RRF solution

Reciprocal Rank Fusion compares rank positions instead of scores and sums a fusion score per document across all participating rankings.

Practical advantage

The retriever mechanism in Elasticsearch merges BM25 and kNN results directly in the search request, without custom fusion logic in the application.

When it beats

With mixed queries combining an exact term and a vague paraphrase, hybrid search typically delivers the overall most relevant result list.

11. FAQ: Hybrid Search With RRF: The Essentials at a Glance

1Why can BM25 scores and kNN scores not be compared directly?
Because they sit on completely different scales: BM25 values are theoretically unbounded and query dependent, kNN distance values typically fall between zero and one. Direct addition produces no meaningful value.
2What is Reciprocal Rank Fusion?
A method that looks not at the absolute scores but at the rank position of a document in each participating ranking, and computes a combined fusion score from that.
3How is the RRF score for a single document calculated?
For every ranking in which the document appears, one divided by the sum of rank_constant and the rank position is computed, and these values are summed across all rankings.
4What does the rank_constant parameter do?
It controls how strongly high rank positions are favored over lower ones. A smaller constant amplifies the influence of the top ranks, a larger one flattens the differences.
5How do you configure hybrid search in an Elasticsearch query?
Via the retriever mechanism with an rrf retriever that accepts a list of sub retrievers, typically a standard retriever for BM25 and a knn retriever for vector search.
6When does hybrid search beat pure vector search?
Especially with mixed queries combining an exact term such as an article number or brand together with a vague paraphrase, because vector search often underweights rare, exact terms.
7What does the rank_window_size parameter do?
It determines how many results from each sub retriever are considered for the fusion. A value that is too small risks excluding relevant documents before the fusion step.
8Is there an alternative to RRF for combining rankings?
Yes, a weighted linear combination of normalized scores, which allows finer control but requires a deliberate normalization strategy and is more sensitive to outliers.
9How do you measure the actual benefit of hybrid search?
With metrics such as Normalized Discounted Cumulative Gain or Mean Reciprocal Rank against real search queries with relevance labeled results, plus monitoring click behavior and conversion rates after going live.
10Do you have to implement fusion logic yourself in the application?
No, modern Elasticsearch versions offer the rrf retriever directly in the search request, so no custom fusion logic outside Elasticsearch is needed.