liveBook · Manning

Hybrid search

As explained in AI-Powered Search

Hybrid keyword and vector search combines lexical term matching with vector-similarity retrieval or ranking.

A search for a movie may need both exact words and results whose vector representations are similar to the query. Hybrid search combines ranked results from multiple search approaches, commonly keyword-based lexical search and dense vector search, to improve relevance. section 15.5

Lexical search typically uses an inverted index and BM25; vector search compares dense representations using a similarity calculation. An engine may combine both in one query. Alternatively, it can merge separate result lists—or the application can merge lists returned by different systems. section 15.5

Reciprocal rank fusion (RRF) is one way to merge those lists without combining their raw scores. For each document, add 1 / (k + rank) for every list containing it, then sort by the total. This favors documents ranked highly in either list and especially those found in both. Increasing k reduces the influence of one unusually high rank relative to appearing across lists; 60 is a commonly used setting. section 15.5.1

Compare the result lists

For the movie query “singin' in the rain,” run a lexical search over titles and overviews, encode the same query for vector search, and inspect the separate rankings before fusing them. The example produces a single lexical phrase result and a vector result list. A second comparison uses “the hobbit.” Seeing the lists separately helps reveal what each approach contributes to the hybrid ranking. section 15.5.1

Listing 15.17 RRF for combining multiple sets of search results
def reciprocal_rank_fusion(search_results, k=None):
  if k is None: k = 60
  scores = {}
  for ranked_docs in search_results:  #1
    for rank, doc in enumerate(ranked_docs, 1):  #2
      scores[doc["id"]] = (scores.get(doc["id"], 0) +  #3
                           (1.0 / (k + rank)))  #3
  sorted_scores = dict(sorted(scores.items(), #4
    key=lambda item: item[1], reverse=True))  #4
  return sorted_scores  #4

The Python implementation accepts ranked document lists, accumulates reciprocal-rank contributions by document ID, and returns IDs sorted by fused score. section 15.5.1

collection.hybrid_search([lexical_search, vector_search], limit=10,
                         algorithm="rrf", algorithm_params={"k": 60})

This collection call supplies lexical and vector searches together and selects RRF with k set to 60. It illustrates engine-supported fusion rather than manual merging. section 15.5.1

Choose the integration path your engine supports, then compare the lexical, vector, and fused rankings for representative queries. Engine APIs differ, so a collection interface may be convenient while direct engine APIs can offer more control. section 15.5 section 13.6.2

How AI-Powered Search covers it

How deep it goes
Works through rank-fusion mechanics, the k parameter, and Python calls for separate searches and engine-supported merging.
Examples
Compares lexical, vector, and fused movie results for “singin' in the rain” and “the hobbit.”
What it assumes
Assumes familiarity with lexical and dense vector search, then explains how to combine their ranked results.
What you can do after
Apply it via collection.hybrid_search with lexical and vector requests, selecting reciprocal rank fusion and configuring k.
How it connects
Connects lexical search, dense vector search, BM25, embeddings, and reciprocal rank fusion.

Also explained in

Compare how 8 books explain hybrid search →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of AI-Powered Search. The section links point to the parts of the book it draws on.