Combine sparse lexical BM25 search (vchord_bm25) and dense vector search (vchord) with Reciprocal Rank Fusion (RRF) and ColBERT reranking.
Modern retrieval pipelines combine dense vector search (vchord, which captures semantic similarity) with sparse lexical BM25 search (vchord_bm25, which captures exact keyword, identifier, and rare-term matches). Because both extensions run natively inside PostgreSQL, you can execute end-to-end hybrid search in a single SQL query with zero external orchestration.
Schema Setup for Hybrid Search
CREATEEXTENSIONIFNOTEXISTSvchordCASCADE;CREATEEXTENSIONIFNOTEXISTSpg_tokenizerCASCADE;CREATEEXTENSIONIFNOTEXISTSvchord_bm25CASCADE;SETsearch_pathTO"$user",public,bm25_catalog,tokenizer_catalog;-- 1. Create a BM25 tokenizer
SELECTcreate_tokenizer('bert',$$model="bert_base_uncased"$$);-- 2. Create a table storing both dense vectors and sparse bm25vectors
CREATETABLEchunks(idSERIALPRIMARYKEY,contentTEXTNOTNULL,dense_embvector(768),bm25_embbm25vector);-- 3. Create VectorChord dense index (vchordrq) and BM25 lexical index (bm25)
CREATEINDEXchunks_dense_idxONchunksUSINGvchordrq(dense_embvector_l2_ops);CREATEINDEXchunks_bm25_idxONchunksUSINGbm25(bm25_embbm25_ops);
Method 1: Reciprocal Rank Fusion (RRF) in Pure SQL
Reciprocal Rank Fusion (RRF) combines rankings from multiple retrieval systems without requiring score calibration between L2/cosine distance and BM25 scores:
For even higher accuracy, you can retrieve candidate documents using vchordrq (dense) + vchord_bm25 (lexical) and rerank the union of candidates in PostgreSQL using VectorChord’s @# (max_sim) multivector ColBERT operator: