use std::collections::HashMap;
use dakera_client::{
AggregationRequest, BulkDeleteRequest, BulkUpdateRequest, CountVectorsRequest,
CreateNamespaceRequest, DakeraClient, ExportRequest, UpsertRequest, Vector,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let url =
std::env::var("DAKERA_API_URL").unwrap_or_else(|_| "http://localhost:3300".to_string());
let api_key = std::env::var("DAKERA_API_KEY").unwrap_or_else(|_| "dk-mykey".to_string());
let client = DakeraClient::builder(&url).api_key(&api_key).build()?;
let health = client.health().await?;
println!(
"Server: {} (healthy: {})",
health.version.as_deref().unwrap_or("unknown"),
health.healthy
);
let namespace = "example-vectors-ops";
client
.create_namespace(namespace, CreateNamespaceRequest::new().with_dimensions(4))
.await?;
println!("\n--- Bulk Upsert ---");
let vectors: Vec<Vector> = (0..20)
.map(|i| {
Vector::with_metadata(
&format!("vec-{:03}", i),
vec![i as f32 * 0.05, 0.1, 0.2, 0.3 + i as f32 * 0.01],
HashMap::from([
(
"category".into(),
serde_json::json!(if i % 2 == 0 { "even" } else { "odd" }),
),
("score".into(), serde_json::json!(i as f64 * 1.5)),
("batch".into(), serde_json::json!(i / 10)),
]),
)
})
.collect();
let upsert_resp = client.upsert(namespace, UpsertRequest { vectors }).await?;
println!("Upserted {} vectors", upsert_resp.upserted_count);
assert_eq!(
upsert_resp.upserted_count, 20,
"expected 20 vectors upserted"
);
println!("\n--- Count Vectors ---");
let count_all = client
.count_vectors(namespace, CountVectorsRequest { filter: None })
.await?;
println!(
"Total vectors in '{}': {}",
count_all.namespace, count_all.count
);
assert!(count_all.count >= 20, "expected at least 20 vectors");
let count_even = client
.count_vectors(
namespace,
CountVectorsRequest {
filter: Some(serde_json::json!({ "category": { "$eq": "even" } })),
},
)
.await?;
println!("Even vectors: {}", count_even.count);
assert_eq!(count_even.count, 10, "expected 10 even vectors");
println!("\n--- Bulk Update ---");
let update_resp = client
.bulk_update_vectors(
namespace,
BulkUpdateRequest {
filter: serde_json::json!({ "category": { "$eq": "even" } }),
update: serde_json::json!({ "status": "promoted", "priority": 1 }),
},
)
.await?;
println!(
"Updated {} vectors, failed: {}",
update_resp.updated, update_resp.failed
);
assert!(
update_resp.updated > 0,
"expected at least one vector updated"
);
println!("\n--- Aggregation ---");
let agg_resp = client
.aggregate(
namespace,
AggregationRequest::new()
.with_count("total_count")
.with_sum("total_score", "score")
.with_avg("avg_score", "score")
.with_min("min_score", "score")
.with_max("max_score", "score")
.with_group_by("category"),
)
.await?;
println!("Aggregation results:");
if let Some(groups) = &agg_resp.aggregation_groups {
for group in groups {
println!(" Group {:?}: {:?}", group.group_key, group.aggregations);
}
assert!(!groups.is_empty(), "expected non-empty aggregation groups");
}
println!("\n--- Export Vectors ---");
let export_resp = client
.export_vectors(
namespace,
ExportRequest::new().with_top_k(5).include_metadata(true),
)
.await?;
println!(
"Exported {} vectors (has more: {})",
export_resp.vectors.len(),
export_resp.next_cursor.is_some()
);
for v in &export_resp.vectors {
let dims = v.values.as_ref().map_or(0, |vals| vals.len());
println!(" {} — dims: {}", v.id, dims);
}
assert!(!export_resp.vectors.is_empty(), "expected non-empty export");
println!("\n--- Bulk Delete ---");
let del_resp = client
.bulk_delete_vectors(
namespace,
BulkDeleteRequest {
filter: serde_json::json!({ "category": { "$eq": "odd" } }),
},
)
.await?;
println!(
"Deleted {} vectors, failed: {}",
del_resp.deleted, del_resp.failed
);
assert!(del_resp.deleted > 0, "expected at least one vector deleted");
let count_after = client
.count_vectors(namespace, CountVectorsRequest { filter: None })
.await?;
println!("Remaining vectors: {}", count_after.count);
println!("\nVector operations example completed successfully.");
Ok(())
}