Filtering, Hybrid Search, and Recall

Real search is never pure vector similarity. Users want "similar documents from this project, updated this year" and they expect an exact product code to match exactly. Combining similarity with metadata filters and keyword search — without wrecking recall — is where academic ANN meets production requirements, and it's harder than it looks.

The previous posts built fast, memory-efficient similarity search. But production search has constraints similarity alone can’t express: access control (“only this user’s documents”), freshness (“last 30 days”), and exact matches (a part number, a name) that embeddings handle poorly. This post covers metadata filtering, hybrid search (dense + sparse), and how both interact with the recall you worked to achieve. This is where the vector-search internals meet the retrieval-quality lessons of the Agentic RAG series.

Metadata filtering: similarity with conditions

Almost every real query combines “similar to X” with structured predicates: find chunks similar to this query and from this tenant and of type ‘manual’ and updated this year. The vectors carry the semantic part; metadata attached to each vector (tenant, type, date, tags) carries the structured part. Filtering is essential for:

The subtlety is when the filter is applied relative to the ANN search, and it creates a genuine dilemma:

This filtering problem is a real engineering challenge in vector databases, and different systems solve it differently — filtered HNSW traversal, partitioned indexes per filter value, or hybrid strategies that switch between pre- and post-filtering based on filter selectivity. The practical points: understand which strategy your vector database uses, be aware that highly selective filters are the hard case (where naive post-filtering silently returns too few results), and test recall with your filters applied, not just on unfiltered search.

Hybrid search: dense meets sparse

Vector (dense) search is superb at semantic similarity but has a well-known blind spot: it can miss exact matches — specific keywords, names, product codes, error codes, rare terms — because embeddings capture meaning, not exact tokens. A query for error code “E-4021” or a specific person’s name may not retrieve the document that contains it verbatim, because that exact string isn’t semantically distinctive to the embedding.

Hybrid search fixes this by combining dense (vector) search with sparse (keyword/lexical) search — classic term-based retrieval like BM25:

query → ┌─ dense (vector) search  → semantically similar results
        └─ sparse (keyword) search → exact-term matches (BM25)
              │
              ▼  fuse the two ranked lists
        combined ranking (e.g. Reciprocal Rank Fusion)

Each covers the other’s weakness:

The two result lists are fused into one ranking — a common method is Reciprocal Rank Fusion (RRF), which combines rankings by how highly each result appears in each list, without needing the scores to be on the same scale. Hybrid search reliably outperforms either method alone for real-world queries, which is why it’s now standard in serious retrieval systems and a key recommendation from the RAG series. If your search must handle both natural-language questions and exact identifiers (most do), hybrid is the answer.

Reranking: the recall recovery step

Both filtering and quantization (previous post) can cost recall, and the ANN trade itself means the first-pass results are approximate. Reranking is the standard way to recover quality: retrieve a generous candidate set with fast approximate search, then reorder it with a slower, more accurate model that scores true relevance to the query.

This “retrieve broadly, rerank precisely” pattern (from the Agentic RAG series) is especially valuable in vector search because:

The design principle: don’t ask one stage to be both fast and perfectly accurate. Retrieve broadly and approximately, then rerank narrowly and precisely — the two-stage pipeline hits both speed and quality.

Putting real queries together

A production retrieval query typically layers all of these:

  1. Apply metadata filters (pre-filter for correctness, especially for access control — never leak across tenants).
  2. Run hybrid retrieval (dense + sparse) over the filtered set to catch both semantic and exact matches.
  3. Fuse the dense and sparse results (e.g. RRF) into one candidate list.
  4. Rerank the fused candidates with a precise model to recover recall and order by true relevance.
  5. Return the top few to the LLM (in RAG) or the user.

Each stage addresses a specific gap: filters for correctness/scope, hybrid for exact-match blind spots, reranking for approximation loss. Skipping stages is where retrieval quietly underperforms — pure vector search with post-filtering and no reranking is a common, fixable cause of “RAG that misses the obvious answer.”

Key takeaways

Further reading

Sources & References

Filtered and hybrid retrieval