Vectoria combines BM25 full-text search with vector similarity and behavioral signals. Single binary. No external services. Runs on your server. Zero-result elimination included.
Clone, build, start. The embedding model downloads automatically on first run. No Python, no Docker, no search cluster to provision.
Works with NDJSON, CSV, and Parquet out of the box. POST products to the HTTP API — they're immediately searchable. BM25, semantic, and hybrid search on the same index with a single flag.
No microservices. No managed search cluster. No per-query API billing. Ship search on your own infrastructure.
Full-text precision for exact queries. Semantic fallback for concept queries ("jogging footwear" finds "Nike Air Max"). Scores are fused and re-ranked in a single pass.
100% query coverage on ESCI benchmark. Spell correction fires on zero-result queries only — compound splits ("whiteshoes" → "white shoes"), typo correction, space joining — without hurting precision on well-formed queries.
EdgeStore HNSW built automatically after reindex. Activates on
POST /admin/reindex. Approximate nearest-neighbor search
at 2ms p50 for a 5K product catalog.
Record clicks, purchases, views, and cart events via
POST /events. Popularity and conversion signals are
aggregated and fold into ranking scores automatically.
Ships with multilingual-e5-small (~40 MB, 100+ languages).
Swap to any OpenAI-compatible embedding provider via config —
no code changes required.
Three backends: in-memory (dev), SQLite + EdgeStore flat scan (light prod), EdgeStore HNSW (production). Switch with one config line, no data migration.
SymSpell seeded from your product catalog as items are indexed. Vocabulary grows with the catalog. No dictionary files to manage. Skips numeric tokens and product codes automatically.
Optional rerank: true flag in any search request.
Top-50 results re-scored with a cross-encoder model.
Enable with VECTORIA_ENABLE_RERANKER=1.
vectoria import products.ndjson handles NDJSON, CSV,
and Parquet. Batch size configurable. Progress reported per batch.
Re-embed all products after a model change with vectoria reindex.
Every search request goes through the same pipeline regardless of mode.
The original query string is used as-is. No pre-processing that could hurt precision.
Full-text search over the indexed catalog using BM25 scoring. If zero results, spell correction fires: compound splits + typo correction on alphabetic tokens, then BM25 retries with the corrected query.
Query embedded via multilingual-e5-small (or configured provider).
HNSW approximate nearest-neighbor search over product vectors.
Semantic candidates merged with BM25 candidates.
If BM25 returns fewer than limit/2 results, top semantic hits
are mined for expansion terms. BM25 retries with the enriched query.
Narrows the zero-result gap further without increasing latency for normal queries.
Final score = semantic × 0.6 + bm25 × w + popularity × 0.2 + availability × 0.1 + margin × 0.1.
All weights configurable in vectoria.toml or per-request.
With "rerank": true, top-50 results re-scored. Adds ~20–50ms latency. Off by default.
Amazon ESCI dataset — 5,000 US products, 107–119 judged queries,
multilingual-e5-small embedding.
ESCI labels represent three levels of query hardness.
| Label Set | Queries | BM25 MRR | Hybrid MRR | Semantic MRR | Coverage (all modes) |
|---|---|---|---|---|---|
| E — exact match | 107 | 0.5842 | 0.5882 | 0.4922 | 100% |
| E+S — exact + concept | 117 | 0.6595 | 0.6576 | 0.5690 | 100% |
| E+S+C — all labels | 119 | 0.6835 | 0.6803 | 0.5797 | 100% |
make esci-import && make esci-judges && make bench
Vectoria's niche is the gap between "just add SQLite FTS5" and "stand up Elasticsearch."
DOCKER — FULL IMAGE (~400 MB)
DOCKER — SLIM IMAGE (~50 MB)
FROM SOURCE (Rust 1.80+)
Both images include a HEALTHCHECK and the vectoria CLI binary.
The /data volume holds the persistent index.
Mount /root/.cache/fastembed to avoid re-downloading the ONNX model on container restart.
Place vectoria.toml in the working directory.
Every field has a sensible default and an environment variable override.
VECTOR BACKENDS
memoryEverything in-memory. Lost on restart. Development only.
sqliteSQLite metadata + EdgeStore flat vector scan. Light production use.
edgestore-hnsw — recommendedPersistent HNSW index. Activates after POST /admin/reindex. Recommended for production.
ENV OVERRIDES
Core endpoints. All except /health require Authorization: Bearer <api_key>.
No HTTP server needed. Add vectoria-core to your Cargo.toml
and get the full hybrid search engine in-process.
Available on crates.io.
In-memory storage + multilingual-e5-small ONNX — zero config needed for prototyping.
Swap storage (Sqlite, EdgeStore), vector index, embedding provider, or ranking weights via builder methods.
make publishPublish to crates.io with cargo login + make publish. Tag release with make tag.
Five minutes to a running demo with real Amazon product data and three search modes side by side. Requires accepting the ESCI dataset license.
ESCI data requires a separate license: github.com/amazon-science/esci-data
vectoria-algolia speaks the same protocol as Algolia Search. Point any InstantSearch or algoliasearch v5
app at localhost:8108 — no code changes beyond the host override. Ships with a React demo
and 550 sample products.
github.com/gleicon/vectoria-algolia
Wire up your InstantSearch app
API compatibility
| Feature | Status |
|---|---|
| Single-index search | ✓ |
| Multi-search (InstantSearch) | ✓ |
facets / facetFilters | ✓ |
_highlightResult + AIS tags | ✓ |
filters string syntax | ✓ |
numericFilters | ✓ |
| Batch index / delete | ✓ |
| React demo (InstantSearch UI) | ✓ |