Skip to main content
The examples below use the document API, which is in public preview. Reciprocal rank fusion itself is a client-side method and works with the results of any Pinecone search.
When you rank the same set of documents two different ways, for example, a full-text (BM25) search and a semantic (dense-vector) search, the scores live on different, incomparable scales. Adding or averaging the raw scores is not meaningful, and one signal usually dominates. Reciprocal rank fusion (RRF) combines them by fusing the rankings instead of the scores, so no normalization or per-signal weighting is required. Today, you run each search separately, then apply RRF to their results in your client (server-side fusion is coming).

When to use it

Reach for RRF whenever you combine results from separate searches and want each to contribute to the final ranking, most commonly full-text (BM25) with semantic (dense-vector). It’s a robust default that works without normalizing scores or tuning per-signal weights.

How it works

RRF scores each document by summing 1 / (k + rank) across every ranking it appears in, where rank is the document’s 1-based position in that ranking and k is a constant (the original RRF paper uses k=60). A document ranked highly in multiple searches accumulates the highest fused score. A document absent from a ranking gets nothing from it. Because only rank position matters, scores never need to be normalized.
Python

Combine two searches

This assumes an index whose schema declares an FTS-enabled string field (body) and a dense_vector field (embedding). Run each search independently, pass the ranked _ids to reciprocal_rank_fusion, then sort by the fused score. Here, a full-text search and a semantic search over the same index are fused into one top-10 ranking:
Python

Tuning and extensions

  • fetch_k (a variable in this example, not an API parameter) controls how deep each ranking is fetched before fusing. Raise it so a document that ranks well in one search but outside the top of the other still contributes. It should be at least your final top_k.
  • k (default 60) controls how much a single ranking’s top positions dominate the fused order. A larger k flattens the influence of any single top-ranked result.
  • Latency. Run the searches in parallel (for example with asyncio or threads) so you pay the slowest search’s latency, not the sum.
  • Weighting. To favor one signal over another, weight each ranking’s contribution (multiply its 1 / (k + rank) terms by a per-ranking weight). It’s a powerful relevance-tuning lever and can warrant its own guide; this page uses the unweighted default.

Merge more than two rankings

RRF extends to any number of rankings. Pass more lists to reciprocal_rank_fusion; each additional search contributes another ranked list of _ids:
Python