Skip to main content

zvec-db

Version Python 3.12+ License Documentation ![Tests](https://img.shields.io/badge/tests-480+ passed-brightgreen.svg)

Sparse/dense vectorization and document reranking toolkit for zvec.

Requires: zvec >= 0.7.0

zvec-db provides:

  • 🚀 Hybrid search - Combine sparse (BM25) and dense (semantic) vectors with full-text search
  • 🔄 Score fusion - Weighted fusion and Reciprocal Rank Fusion (RRF)
  • 🎯 Cross-encoder reranking - Two-stage retrieval with local or API-based rerankers
  • 📦 6 sparse embedders - BM25, BM25L, BM25+, TF-IDF, Count, DisMax
  • 🔧 Normalization - Bayesian, minmax, percentile, and arctan-based normalization
  • ⚡ Native fast path - C++ acceleration for fusion rerankers

Quick Start

pip install zvec-db

Complete Example: Hybrid Search with RerankPipeline

from zvec_db import search, RerankPipeline, ScoreNormalizer, WeightedReranker
from zvec_db.rerankers import SentenceTransformerReranker
from zvec_db.embedders import BM25Embedder, SentenceTransformersEmbedder
import zvec

# 1. Open collection and initialize embedders
collection = zvec.open("./my_collection")
bm25 = BM25Embedder(max_features=4096).load("./bm25.joblib")
dense = SentenceTransformersEmbedder(model_name="all-MiniLM-L6-v2")

# 2. Create rerank pipeline with auto-detection from schema
reranker = RerankPipeline(
    normalizer=ScoreNormalizer(
        method="bayes",
        schema=collection.schema,  # Auto-detect metrics (COSINE, L2, IP)
    ),
    fusion=WeightedReranker(
        weights={"sparse": 0.5, "dense": 0.3, "text": 0.2},
        topk=16,  # Top 16 after fusion
    ),
    cross_encoder=SentenceTransformerReranker(
        model_name="cross-encoder/ms-marco-MiniLM-L-6-v2",
        topk=8,  # Top 8 after cross-encoder
    ),
)

# 3. Search with full pipeline
results = search(
    collection=collection,
    query="neural networks",
    sparse_fields={"sparse": bm25},
    dense_fields={"dense": dense},
    fts_fields="text",
    reranker=reranker,
    topk=32,  # Fetch 32 candidates
)

for doc in results:
    print(f"{doc.fields['text']} (score: {doc.score:.4f})")

Simple Search (No Reranking)

from zvec_db import search

results = search(
    collection=collection,
    query="neural networks",
    sparse_fields={"sparse": bm25},
    dense_fields={"dense": dense},
    topk=10,
)

Search with Filter

from zvec_db import search

# Filter with SQL-like WHERE clause
results = search(
    collection=collection,
    query="neural networks",
    sparse_fields={"sparse": bm25},
    dense_fields={"dense": dense},
    filter="publish_year >= 2020 AND category == 'research'",
    topk=10,
)

Custom Fusion Only

from zvec_db.rerankers import WeightedReranker

# List weights enable C++ fast path (2-5x faster)
reranker = WeightedReranker(weights=[0.7, 0.3])

results = search(
    collection=collection,
    query="neural networks",
    sparse_fields={"sparse": bm25},
    dense_fields={"dense": dense},
    reranker=reranker,
)

Search with Minimum Score

from zvec_db import search

# Filter out results with score below 0.5
results = search(
    collection=collection,
    query="neural networks",
    sparse_fields={"sparse": bm25},
    dense_fields={"dense": dense},
    min_score=0.5,  # Only keep results with score >= 0.5
    topk=10,
)

Full-Text Search with the Native ngram Tokenizer

zvec ships native C++ tokenizers for its full-text search (FTS) indexes: standard (default), ngram, jieba, and whitespace. The ngram tokenizer indexes every substring of n characters, enabling partial-word and typo-tolerant matching (e.g. searching "vector" matches "vectors", "vectorize") and works on any language without a dictionary.

Configure it on the FTS field when creating the collection with FtsIndexParam:

import zvec

schema = zvec.CollectionSchema(
    name="my_collection",
    fields=[
        zvec.FieldSchema(
            name="text",
            data_type=zvec.DataType.STRING,
            index_param=zvec.FtsIndexParam(
                tokenizer_name="ngram",
                filters=["lowercase"],
                extra_params='{"ngram_min": 2, "ngram_max": 3, "token_chars": ["letter", "digit"]}',
            ),
        )
    ],
)
collection = zvec.create_and_open("./my_collection", schema)

Then search the field with fts_fields="text" as usual — the query is tokenized with the same ngram pipeline at query time:

results = search(
    collection=collection,
    query="vector",
    fts_fields="text",
    topk=10,
)

extra_params keys for the ngram tokenizer:

Key Values Default Description
ngram_min positive integer 2 Minimum n-gram length
ngram_max positive integer 2 Maximum n-gram length
token_chars array of "letter", "digit", "whitespace", "punctuation", "symbol" [] (all valid UTF-8 characters) Character classes kept for n-gram building

Note: Larger ngram_max values increase index size. For most use cases {"ngram_min": 2, "ngram_max": 3} is a good trade-off between recall and index footprint. The other native tokenizers (standard, jieba for Chinese, whitespace) accept their own extra_params — see the zvec FtsIndexParam documentation.


API Reference

search() Parameters

Parameter Type Description
collection zvec.Collection Collection to search
query str Query text
sparse_fields dict[str, Embedder] Sparse fields (e.g., {"sparse": bm25})
dense_fields dict[str, Embedder] Dense fields (e.g., {"dense": dense})
fts_fields str | list[str] FTS fields
reranker Reranker Reranker instance
topk int Number of candidates to fetch (before filtering)
min_score float Minimum score threshold (filter out low scores)
output_fields list[str] Fields to include in results
filter str Conditional filter (SQL-like WHERE clause)

Reranker Types

Type Description
WeightedReranker(weights={...}) Weighted fusion
RrfReranker() Reciprocal Rank Fusion
SentenceTransformerReranker() Cross-encoder
RerankPipeline(normalizer=..., fusion=..., cross_encoder=...) Full pipeline

Embedders

Sparse (lexical): BM25Embedder (recommended), BM25LEmbedder, BM25PlusEmbedder, TfidfEmbedder, CountEmbedder, DisMaxEmbedder

Dense (semantic): SentenceTransformersEmbedder, OpenAIEmbedder

from zvec_db import BM25Embedder, SentenceTransformersEmbedder

bm25 = BM25Embedder(max_features=4096).load("./bm25.joblib")
dense = SentenceTransformersEmbedder(model_name="all-MiniLM-L6-v2")

bm25.save("bm25.joblib")

Rerankers

Fusion: WeightedReranker (weighted sum), RrfReranker (rank-based)

Cross-Encoder: SentenceTransformerReranker, OpenAIReranker

Pipeline: RerankPipeline (normalization + fusion + cross-encoder)

from zvec_db import RerankPipeline, ScoreNormalizer, WeightedReranker
from zvec_db.rerankers import SentenceTransformerReranker

# Full pipeline with schema auto-detection
pipeline = RerankPipeline(
    normalizer=ScoreNormalizer(method="bayes", schema=collection.schema),
    fusion=WeightedReranker(weights={"sparse": 0.7, "dense": 0.3}),
    cross_encoder=SentenceTransformerReranker(topk=10),
)

Performance tip: Use list weights for C++ fast path: WeightedReranker(weights=[0.7, 0.3])


Documentation


License

MIT License

Metadata

Release files for zvec-db 0.18.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for zvec-db 0.18.0
File Size Uploaded
zvec_db-0.18.0.tar.gz 87.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for zvec-db 0.18.0
File Interpreter ABI Platform
zvec_db-0.18.0-py3-none-any.whl Python 3 none any Details

Total release size: 196.4 kB

Release files / zvec_db-0.18.0.tar.gz

Download URL zvec_db-0.18.0.tar.gz
Size 87.4 kB
Tags Source
SHA-256 checksum
How to use checksums
a5b4482e9822554493a691c3dbfd3502b14d5d3bf390edb529411e6919f9e226
BLAKE2b-256 checksum
How to use checksums
8391ca99fa558db035de1dab19dd1326348aa84c874c83b980dd8cf214816fd3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / zvec_db-0.18.0-py3-none-any.whl

Download URL zvec_db-0.18.0-py3-none-any.whl
Size 109.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
76869da8f4744b8f2dff604d4e4c5fe0913fbbeb6f471349135633dacdcd1c09
BLAKE2b-256 checksum
How to use checksums
da67091473e51c840a29a9b57e3ae74d69b15642a16545650e829962bb123912
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.18.0 This release

2 release files

0.17.0

2 release files

0.16.0

2 release files

0.15.0

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page