/// Retrieval query structure #[derive(Clone, Debug)] pub struct RetrievalQuery { /// Optional text query for keyword substring matching pub text: Option, /// Namespace to search in pub ns: String, /// Field filters (key=value pairs) pub filters: Vec<(String, String)>, /// Maximum number of results to return pub top_k: usize, } impl RetrievalQuery { /// Create a new retrieval query pub fn new(ns: String) -> Self { Self { text: None, ns, filters: Vec::new(), top_k: 10, } } /// Set the text query pub fn with_text(mut self, text: String) -> Self { self.text = Some(text); self } /// Add a filter pub fn with_filter(mut self, key: String, value: String) -> Self { self.filters.push((key, value)); self } /// Set the maximum number of results pub fn with_top_k(mut self, top_k: usize) -> Self { self.top_k = top_k; self } } /// Search result #[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] pub struct SearchResult { /// Object ID pub id: String, /// Match score (0.0 to 1.0) pub score: f32, /// Matched text snippet (if applicable) #[serde(skip_serializing_if = "Option::is_none")] pub snippet: Option, } impl SearchResult { pub fn new(id: String, score: f32) -> Self { Self { id, score, snippet: None, } } pub fn with_snippet(mut self, snippet: String) -> Self { self.snippet = Some(snippet); self } }