Hybrid Search
Hybrid Search
Combine vector similarity with full-text search for best-in-class retrieval. Get the semantic understanding of embeddings plus the precision of keyword matching.
What is Hybrid Search?
Hybrid search combines vector similarity (semantic meaning) with full-text search (keyword matching) to provide superior search results that understand both context and exact terms.
Vector Search Alone
- ✓ Understands semantic meaning
- ✓ Finds conceptually similar content
- ✗ May miss exact keyword matches
- ✗ Can return loosely related results
Full-Text Search Alone
- ✓ Precise keyword matching
- ✓ Fast for exact terms
- ✗ No semantic understanding
- ✗ Misses synonyms and context
Hybrid Search = Best of Both
- Semantic understanding from vector embeddings
- Precise keyword matching from full-text search
- Weighted scoring to balance both approaches
- Superior relevance and recall
Basic Hybrid Search
Setup Table
-- Create table with vector and text columns
CREATE TABLE knowledge_base (
id SERIAL PRIMARY KEY,
title TEXT,
content TEXT,
embedding vector(384),
ts_vector tsvector
);
-- Create indexes
CREATE INDEX ON knowledge_base USING hnsw (embedding vector_l2_ops);
CREATE INDEX ON knowledge_base USING gin (ts_vector);
-- Insert data with embeddings and text index
INSERT INTO knowledge_base (title, content, embedding, ts_vector)
VALUES (
'PostgreSQL Performance',
'Optimize queries with indexes and EXPLAIN',
embed_text('Optimize queries with indexes and EXPLAIN'),
to_tsvector('Optimize queries with indexes and EXPLAIN')
);Perform Hybrid Search
-- Hybrid search: 70% vector + 30% text
SELECT * FROM hybrid_search(
'knowledge_base', -- table name
'content', -- text column
'embedding', -- vector column
'database optimization', -- query
10, -- limit
0.7, -- vector weight (70%)
0.3 -- text weight (30%)
);
-- Returns: id, title, content, vector_score, text_score, hybrid_scoreReranking for Precision
Cross-Encoder Reranking
Cross-encoders jointly encode the query and each candidate for higher precision scoring.
-- Rerank search results with cross-encoder
SELECT rerank_cross_encoder(
'What is PostgreSQL?', -- query
ARRAY[ -- candidate documents
'PostgreSQL is a database',
'MySQL is also a database',
'Redis is a cache'
],
'ms-marco-MiniLM-L-6-v2', -- model
3 -- top_n
);
-- Returns:
-- idx | score
-- -----+-------
-- 0 | 0.945 (most relevant)
-- 1 | 0.678
-- 2 | 0.123 (least relevant)MMR (Maximal Marginal Relevance)
MMR balances relevance with diversity to avoid redundant results.
-- MMR reranking for diverse results
SELECT * FROM mmr_rerank(
'knowledge_base', -- table
'embedding', -- vector column
embed_text('database'), -- query vector
20, -- fetch top 20 candidates
5, -- return top 5 diverse results
0.7 -- lambda (0.7 = 70% relevance, 30% diversity)
);
-- Returns: id, title, score, diversityBest Practices
1. Tune Vector/Text Weights
Adjust the balance based on your use case:
0.9/0.1- Heavily semantic (concepts matter more than exact terms)0.7/0.3- Balanced (default, works for most cases)0.5/0.5- Equal weight (both semantic and keywords important)0.3/0.7- Keyword-focused (exact terms critical)
2. Index Both Columns
-- Always index both for performance
CREATE INDEX ON docs USING hnsw (embedding vector_l2_ops);
CREATE INDEX ON docs USING gin (ts_vector);3. Use Reranking for Top Results
Fetch 50-100 candidates with hybrid search, then rerank top 10-20 for best precision.