This guide covers everything you need to start embedding and querying vectors with Vectrust.
Add vectrust and serde_json to your Cargo.toml:
[dependencies]
vectrust = "0.1.0"
serde_json = "1.0"
Ideal for testing, scratchpads, caching layers, or CLI tools:
use vectrust::prelude::*;
let db = Vectrust::in_memory();
Stores snapshots and WAL logs on disk:
use vectrust::prelude::*;
let db = Vectrust::open("./my_vector_db")?;
Each collection stores vectors of a fixed dimension, compared with a specified metric.
use vectrust::prelude::*;
// Configure a collection with 128 dimensions and Cosine similarity
let config = CollectionConfig::builder(128, Metric::Cosine)
.index_type(IndexType::Hnsw)
.hnsw_config(HnswConfig {
m: 16, // Max connections per node
m0: 32, // Max connections at layer 0 (typically 2 * m)
ef_construction: 128, // Quality of graph during build
ef_search: 64, // Search beam width
})
.sync_on_write(false) // True for instant fsync durability
.build();
let collection = db.get_or_create_collection("articles", config)?;
A Point consists of:
id: A unique PointId (accepts u64, &str, or String).vector: A Vec<f32> matching the collection’s dimension.payload: An optional JSON metadata payload (serde_json::Value).use serde_json::json;
collection.insert(
Point::new("doc_1", vec![0.1; 128])
.with_payload(json!({
"title": "Introduction to Rust",
"category": "programming",
"year": 2024
}))
)?;
let points = vec![
Point::new(101u64, vec![0.2; 128]).with_payload(json!({"tag": "ai"})),
Point::new(102u64, vec![0.4; 128]).with_payload(json!({"tag": "database"})),
];
collection.insert_batch(points)?;
Execute nearest neighbor queries using SearchQuery:
let query_vector = vec![0.15; 128];
// Find top 5 closest vectors
let query = SearchQuery::new(query_vector, 5)
.include_payload(true)
.include_vector(false);
let results = collection.search(query)?;
for r in results {
println!("ID: {}, Distance: {:.4}, Score: {:.4}", r.id, r.distance, r.score);
if let Some(payload) = r.payload {
println!("Metadata: {}", payload);
}
}
Combine semantic vector search with exact metadata filters:
let query = SearchQuery::new(vec![0.15; 128], 3)
.with_filter(Filter::and(vec![
Filter::eq("category", "programming"),
Filter::gte("year", 2023.0),
]));
let results = collection.search(query)?;
if let Some(point) = collection.get("doc_1")? {
println!("Found vector of length: {}", point.vector.len());
}
collection.update_payload("doc_1", Some(json!({"status": "archived"})))?;
let removed = collection.delete("doc_1")?;
assert!(removed);
To commit pending Write-Ahead Log records into a clean, compact snapshot file:
collection.compact()?;