qail_core/ast/cmd/
vector.rs

1//! Vector database builder methods for Qdrant.
2
3use crate::ast::{Action, Qail};
4
5impl Qail {
6    /// Create a vector similarity search command.
7    ///
8    /// # Example
9    /// ```ignore
10    /// use qail_core::prelude::*;
11    ///
12    /// let cmd = Qail::search("products")
13    ///     .vector(vec![0.1, 0.2, 0.3])
14    ///     .limit(10);
15    /// ```
16    pub fn search(collection: &str) -> Self {
17        Self {
18            action: Action::Search,
19            table: collection.to_string(),
20            ..Default::default()
21        }
22    }
23
24    /// Create a vector upsert command (insert or update points).
25    ///
26    /// # Example
27    /// ```ignore
28    /// let cmd = Qail::upsert("products");
29    /// ```
30    pub fn upsert(collection: &str) -> Self {
31        Self {
32            action: Action::Upsert,
33            table: collection.to_string(),
34            ..Default::default()
35        }
36    }
37
38    /// Create a scroll command for paginated iteration.
39    ///
40    /// # Example
41    /// ```ignore
42    /// let cmd = Qail::scroll("products").limit(100);
43    /// ```
44    pub fn scroll(collection: &str) -> Self {
45        Self {
46            action: Action::Scroll,
47            table: collection.to_string(),
48            ..Default::default()
49        }
50    }
51
52    /// Set the query vector for similarity search.
53    ///
54    /// # Example
55    /// ```
56    /// use qail_core::prelude::*;
57    ///
58    /// let embedding = vec![0.1, 0.2, 0.3, 0.4];
59    /// let cmd = Qail::search("products").vector(embedding);
60    /// assert!(cmd.vector.is_some());
61    /// ```
62    pub fn vector(mut self, embedding: Vec<f32>) -> Self {
63        self.vector = Some(embedding);
64        self
65    }
66
67    /// Set minimum similarity score threshold.
68    ///
69    /// Points with similarity below this threshold will be filtered out.
70    ///
71    /// # Example
72    /// ```
73    /// use qail_core::prelude::*;
74    ///
75    /// let cmd = Qail::search("products")
76    ///     .vector(vec![0.1, 0.2])
77    ///     .score_threshold(0.8);
78    /// assert_eq!(cmd.score_threshold, Some(0.8));
79    /// ```
80    pub fn score_threshold(mut self, threshold: f32) -> Self {
81        self.score_threshold = Some(threshold);
82        self
83    }
84
85    /// Specify which named vector to search (for multi-vector collections).
86    ///
87    /// # Example
88    /// ```
89    /// use qail_core::prelude::*;
90    ///
91    /// // Collection with separate "title" and "content" vectors
92    /// let title_embedding = vec![0.1, 0.2, 0.3];
93    /// let cmd = Qail::search("articles")
94    ///     .vector_name("title")
95    ///     .vector(title_embedding);
96    /// ```
97    pub fn vector_name(mut self, name: &str) -> Self {
98        self.vector_name = Some(name.to_string());
99        self
100    }
101
102    /// Include vectors in search results.
103    ///
104    /// # Example
105    /// ```
106    /// use qail_core::prelude::*;
107    ///
108    /// let embedding = vec![0.1, 0.2, 0.3];
109    /// let cmd = Qail::search("products")
110    ///     .vector(embedding)
111    ///     .with_vectors();
112    /// assert!(cmd.with_vector);
113    /// ```
114    pub fn with_vectors(mut self) -> Self {
115        self.with_vector = true;
116        self
117    }
118}
119
120#[cfg(test)]
121mod tests {
122    use super::*;
123
124    #[test]
125    fn test_search_builder() {
126        let cmd = Qail::search("products")
127            .vector(vec![0.1, 0.2, 0.3])
128            .score_threshold(0.8)
129            .limit(10);
130        
131        assert_eq!(cmd.action, Action::Search);
132        assert_eq!(cmd.table, "products");
133        assert_eq!(cmd.vector, Some(vec![0.1, 0.2, 0.3]));
134        assert_eq!(cmd.score_threshold, Some(0.8));
135    }
136
137    #[test]
138    fn test_vector_name() {
139        let cmd = Qail::search("articles")
140            .vector_name("title")
141            .vector(vec![0.5, 0.5]);
142        
143        assert_eq!(cmd.vector_name, Some("title".to_string()));
144    }
145
146    #[test]
147    fn test_with_vectors() {
148        let cmd = Qail::search("products")
149            .vector(vec![0.1])
150            .with_vectors();
151        
152        assert!(cmd.with_vector);
153    }
154}