Class HybridSearcher

Hybrid dense+sparse searcher combining vector embeddings with BM25.

Uses Reciprocal Rank Fusion (RRF) to merge results from both retrieval systems, capturing both semantic similarity and exact keyword matches.

Example: Basic usage

const bm25 = new BM25Index();
bm25.addDocuments(documents);

const hybrid = new HybridSearcher(vectorStore, embeddingManager, bm25, {
denseWeight: 0.7,
sparseWeight: 0.3,
fusionMethod: 'rrf',
});

const results = await hybrid.search(
'error TS2304 type declarations',
'my-collection',
10,
);

Example: Weighted sum fusion (when you have calibrated scores)

const hybrid = new HybridSearcher(vectorStore, embeddingManager, bm25, {
fusionMethod: 'weighted-sum',
denseWeight: 0.6,
sparseWeight: 0.4,
});

Constructors

Methods

Constructors

Methods

  • Searches both dense and sparse indexes, then fuses results.

    Pipeline:

    1. Generate query embedding via the embedding manager
    2. Query the dense vector store for semantically similar documents
    3. Query the BM25 sparse index for keyword-matching documents
    4. Fuse both result sets using the configured fusion method (RRF by default)
    5. Return the top K results sorted by fused score

    Parameters

    • query: string

      The search query text.

    • collectionName: string

      Vector store collection to search.

    • Optional topK: number = 10

      Maximum number of results to return.

    • Optional queryOptions: Partial<QueryOptions>

      Additional options for the vector store query.

    Returns Promise<HybridResult[]>

    Fused results sorted by relevance.

    Throws

    If embedding generation fails.

    Example

    const results = await hybrid.search('error TS2304', 'knowledge-base', 5);
    for (const r of results) {
    console.log(`${r.id}: fused=${r.score.toFixed(4)} dense=${r.denseRank} sparse=${r.sparseRank}`);
    }