RuVe
A hybrid vector + full-text search database written in Rust.
RuVe combines an HNSW approximate nearest-neighbour graph with a BM25 keyword index.
Features
- HNSW index — sub-linear approximate nearest-neighbour search with configurable exploration factor
- BM25 index — IDF-weighted full-text ranking with tokenisation and stop-word filtering
- Append-only binary storage — fast sequential writes, O(1) random-access reads via stored offsets
- Fully persistent — all data, graph edges, and indices are written to disk; no in-memory-only state
Installation
Add RuVe to your Cargo.toml:
[]
= "0.1"
The default feature set includes the embedder (OpenAI / Ollama). If you only need the core library and will supply your own vectors:
[]
= { = "0.1", = false }
Library Usage
Insert and search with your own vectors
use Database;
let mut db = new;
// Insert with an auto-generated UUID
let vector: = vec!;
db.insert_raw;
// Insert with a custom key
let vector2: = vec!;
db.insert_raw;
// HNSW approximate nearest-neighbour search
// ef is the exploration factor — higher = better recall, slower
let query = vec!;
let records = db.search_hnsw;
for record in &records
// BM25 full-text search
let results = db.text_search;
for record in &results
// Delete by id
db.delete;
// Wipe everything
db.wipe;
Embedder (feature = "embedder")
Use RuVe's built-in embedding backends to turn text into vectors automatically.
OpenAI (requires OPENAI_API_KEY in your environment or a .env file):
use Embedder;
let embedder = openai;
let vector = embedder.embed;
db.insert_raw;
Ollama (requires ollama running locally with nomic-embed-text pulled):
let embedder = ollama;
let vector = embedder.embed;
db.insert_raw;
CLI
An interactive REPL for exploring your database directly from the terminal.
# default features already include embedder + cli
# or explicitly
RuVe v0.1.0 — type help for available commands, quit to exit
ruve> insert The quick brown fox jumps over the lazy dog
inserted
ruve> search text quick fox 3
01980... — Some("The quick brown fox jumps over the lazy dog")
ruve> search vec The quick brown fox 3
query vector dim: 3072
0.9821 | dim=3072 | 01980... — Some("The quick brown fox jumps over the lazy dog")
ruve> list
01980... — Some("The quick brown fox jumps over the lazy dog")
ruve> delete 01980...
deleted
ruve> wipe
wiped
Commands
| Command | Description |
|---|---|
insert <text> |
Embed the text and insert a record |
insert raw [1.0, 2.0, ...] <text> |
Insert with a pre-computed vector |
search vec <query> <k> |
Embed the query and run HNSW vector search |
search text <query> <k> |
BM25 full-text search |
delete <id> |
Delete a record by UUID |
wipe |
Delete all records and indices |
load <filename> |
Batch-embed and index every line from books/<filename> |
list |
List all stored records |
help |
Show this help text |
quit / exit |
Exit the REPL |
Benchmark
Measure insert throughput, vector search latency, text search latency, and Recall@k against brute-force ground truth.
# run the two smallest scenarios by default
# pick specific scenarios
License
MIT