use edgevec::filter::{parse, FilterStrategy, FilteredSearcher, VectorMetadataStore};
use edgevec::metadata::MetadataValue;
use edgevec::{HnswConfig, HnswIndex, VectorStorage};
use std::collections::HashMap;
fn main() {
println!("=== EdgeVec Basic Filtered Search Example ===\n");
let config = HnswConfig::new(4);
let mut storage = VectorStorage::new(&config, None);
let mut index = HnswIndex::new(config, &storage).expect("Failed to create index");
let mut metadata_store = VectorMetadataStore::new();
println!("Created index with 4 dimensions\n");
let items = vec![
("apple", "fruit", 1.50, vec![1.0, 0.0, 0.0, 0.0]),
("banana", "fruit", 0.75, vec![0.9, 0.1, 0.0, 0.0]),
("carrot", "vegetable", 0.50, vec![0.0, 1.0, 0.0, 0.0]),
("broccoli", "vegetable", 1.25, vec![0.0, 0.9, 0.1, 0.0]),
("chicken", "meat", 5.00, vec![0.0, 0.0, 1.0, 0.0]),
("beef", "meat", 8.00, vec![0.0, 0.0, 0.9, 0.1]),
("salmon", "seafood", 12.00, vec![0.0, 0.0, 0.0, 1.0]),
("shrimp", "seafood", 15.00, vec![0.0, 0.0, 0.1, 0.9]),
];
println!("Inserting {} items with metadata:", items.len());
for (name, category, price, vector) in items {
let id = index.insert(&vector, &mut storage).expect("Insert failed");
let mut meta = HashMap::new();
meta.insert("name".to_string(), MetadataValue::String(name.to_string()));
meta.insert(
"category".to_string(),
MetadataValue::String(category.to_string()),
);
meta.insert("price".to_string(), MetadataValue::Float(price));
metadata_store.set((id.0 - 1) as usize, meta);
println!(
" ID {}: {} (category={}, price=${:.2})",
id.0, name, category, price
);
}
println!("\n--- Running Filtered Searches ---\n");
println!("Filter: category = \"fruit\"");
let filter = parse(r#"category = "fruit""#).expect("Parse failed");
let query = vec![0.95, 0.05, 0.0, 0.0];
let mut searcher = FilteredSearcher::new(&index, &storage, &metadata_store);
let result = searcher
.search_filtered(&query, 10, Some(&filter), FilterStrategy::Auto)
.expect("Search failed");
println!(" Found {} results:", result.results.len());
for r in &result.results {
let meta = metadata_store.get((r.vector_id.0 - 1) as usize);
if let Some(m) = meta {
let name = m
.get("name")
.map(|v| format!("{:?}", v))
.unwrap_or_default();
println!(" - {} (score: {:.4})", name, r.distance);
}
}
println!("\nFilter: price < 2.00");
let filter = parse("price < 2.0").expect("Parse failed");
let query = vec![0.5, 0.5, 0.0, 0.0];
let result = searcher
.search_filtered(&query, 10, Some(&filter), FilterStrategy::Auto)
.expect("Search failed");
println!(" Found {} results:", result.results.len());
for r in &result.results {
let meta = metadata_store.get((r.vector_id.0 - 1) as usize);
if let Some(m) = meta {
let name = m
.get("name")
.map(|v| format!("{:?}", v))
.unwrap_or_default();
let price = m
.get("price")
.map(|v| format!("{:?}", v))
.unwrap_or_default();
println!(
" - {} (price: {}, score: {:.4})",
name, price, r.distance
);
}
}
println!("\nFilter: category = \"meat\" OR category = \"seafood\"");
let filter = parse(r#"category = "meat" OR category = "seafood""#).expect("Parse failed");
let query = vec![0.0, 0.0, 0.5, 0.5];
let result = searcher
.search_filtered(&query, 10, Some(&filter), FilterStrategy::Auto)
.expect("Search failed");
println!(" Found {} results:", result.results.len());
for r in &result.results {
let meta = metadata_store.get((r.vector_id.0 - 1) as usize);
if let Some(m) = meta {
let name = m
.get("name")
.map(|v| format!("{:?}", v))
.unwrap_or_default();
let cat = m
.get("category")
.map(|v| format!("{:?}", v))
.unwrap_or_default();
println!(
" - {} (category: {}, score: {:.4})",
name, cat, r.distance
);
}
}
println!("\nFilter: (category = \"fruit\" OR category = \"vegetable\") AND price < 1.0");
let filter = parse(r#"(category = "fruit" OR category = "vegetable") AND price < 1.0"#)
.expect("Parse failed");
let query = vec![0.5, 0.5, 0.0, 0.0];
let result = searcher
.search_filtered(&query, 10, Some(&filter), FilterStrategy::Auto)
.expect("Search failed");
println!(" Found {} results:", result.results.len());
for r in &result.results {
let meta = metadata_store.get((r.vector_id.0 - 1) as usize);
if let Some(m) = meta {
let name = m
.get("name")
.map(|v| format!("{:?}", v))
.unwrap_or_default();
let price = m
.get("price")
.map(|v| format!("{:?}", v))
.unwrap_or_default();
println!(
" - {} (price: {}, score: {:.4})",
name, price, r.distance
);
}
}
println!("\n=== Example Complete ===");
}