Skip to main content

qdrant_client/builders/
text_index_params_builder.rs

1use crate::qdrant::*;
2
3#[must_use]
4#[derive(Clone)]
5pub struct TextIndexParamsBuilder {
6    /// Tokenizer type
7    pub(crate) tokenizer: Option<i32>,
8    /// If true - all tokens will be lowercase
9    pub(crate) lowercase: Option<Option<bool>>,
10    /// Minimal token length
11    pub(crate) min_token_len: Option<Option<u64>>,
12    /// Maximal token length
13    pub(crate) max_token_len: Option<Option<u64>>,
14    /// If true - store index on disk.
15    pub(crate) on_disk: Option<Option<bool>>,
16    pub(crate) stopwords: Option<Option<StopwordsSet>>,
17    /// If true - support phrase matching.
18    pub(crate) phrase_matching: Option<Option<bool>>,
19    /// Set an algorithm for stemming.
20    pub(crate) stemmer: Option<Option<StemmingAlgorithm>>,
21    /// If true, normalize tokens by folding accented characters to ASCII (e.g., "ação" -> "acao"). Default: false.
22    pub(crate) ascii_folding: Option<Option<bool>>,
23    /// If true - enable HNSW index for this field.
24    pub(crate) enable_hnsw: Option<Option<bool>>,
25    /// Memory placement of the index.
26    pub(crate) memory: Option<Option<i32>>,
27}
28
29impl TextIndexParamsBuilder {
30    pub fn new(tokenizer: TokenizerType) -> Self {
31        let mut builder = Self::create_empty();
32        builder.tokenizer = Some(tokenizer.into());
33        builder
34    }
35
36    /// Tokenizer type
37    pub fn tokenizer(self, value: i32) -> Self {
38        let mut new = self;
39        new.tokenizer = Option::Some(value);
40        new
41    }
42    /// If true - all tokens will be lowercase
43    pub fn lowercase(self, value: bool) -> Self {
44        let mut new = self;
45        new.lowercase = Option::Some(Option::Some(value));
46        new
47    }
48    /// Minimal token length
49    pub fn min_token_len(self, value: u64) -> Self {
50        let mut new = self;
51        new.min_token_len = Option::Some(Option::Some(value));
52        new
53    }
54    /// Maximal token length
55    pub fn max_token_len(self, value: u64) -> Self {
56        let mut new = self;
57        new.max_token_len = Option::Some(Option::Some(value));
58        new
59    }
60    /// If true - store index on disk.
61    ///
62    /// Deprecated since 1.19.0, use [`memory`](Self::memory) instead.
63    pub fn on_disk(self, value: bool) -> Self {
64        let mut new = self;
65        new.on_disk = Option::Some(Option::Some(value));
66        new
67    }
68
69    /// Stopwords for a single language for the text index
70    pub fn stopwords_language(self, language: String) -> Self {
71        let mut new = self;
72        let stopwords_set = StopwordsSet {
73            languages: vec![language],
74            custom: vec![],
75        };
76        new.stopwords = Some(Some(stopwords_set));
77        new
78    }
79
80    /// Stopwords for the text index
81    pub fn stopwords(self, stopwords_set: StopwordsSet) -> Self {
82        let mut new = self;
83        new.stopwords = Some(Some(stopwords_set));
84        new
85    }
86
87    /// If true - support phrase matching. Default is false.
88    pub fn phrase_matching(self, phrase_matching: bool) -> Self {
89        let mut new = self;
90        new.phrase_matching = Some(Some(phrase_matching));
91        new
92    }
93
94    /// Set snowball stemmer with the provided language
95    pub fn snowball_stemmer(self, language: String) -> Self {
96        let mut new: TextIndexParamsBuilder = self;
97        let stemmer = StemmingAlgorithm {
98            stemming_params: Some(stemming_algorithm::StemmingParams::Snowball(
99                SnowballParams { language },
100            )),
101        };
102        new.stemmer = Some(Some(stemmer));
103        new
104    }
105
106    /// Explicitly disable stemming, overriding the language default
107    pub fn disabled_stemmer(self) -> Self {
108        let mut new = self;
109        let stemmer = StemmingAlgorithm {
110            stemming_params: Some(stemming_algorithm::StemmingParams::Disabled(
111                DisabledStemmer {},
112            )),
113        };
114        new.stemmer = Some(Some(stemmer));
115        new
116    }
117
118    /// Set an algorithm for stemming.
119    pub fn stemmer(self, stemming_params: stemming_algorithm::StemmingParams) -> Self {
120        let mut new = self;
121        let stemmer = StemmingAlgorithm {
122            stemming_params: Some(stemming_params),
123        };
124        new.stemmer = Some(Some(stemmer));
125        new
126    }
127
128    /// If true, normalize tokens by folding accented characters to ASCII (e.g., "ação" -> "acao"). Default: false.
129    pub fn ascii_folding(self, value: bool) -> Self {
130        let mut new = self;
131        new.ascii_folding = Option::Some(Option::Some(value));
132        new
133    }
134
135    /// If true - enable HNSW index for this field.
136    pub fn enable_hnsw(self, value: bool) -> Self {
137        let mut new = self;
138        new.enable_hnsw = Option::Some(Option::Some(value));
139        new
140    }
141
142    /// Memory placement of the index.
143    /// Overrides the deprecated `on_disk` flag if both are set.
144    pub fn memory<VALUE: core::convert::Into<i32>>(self, value: VALUE) -> Self {
145        let mut new = self;
146        new.memory = Option::Some(Option::Some(value.into()));
147        new
148    }
149
150    #[allow(deprecated)]
151    fn build_inner(self) -> Result<TextIndexParams, TextIndexParamsBuilderError> {
152        Ok(TextIndexParams {
153            tokenizer: match self.tokenizer {
154                Some(value) => value,
155                None => {
156                    return Result::Err(core::convert::Into::into(
157                        ::derive_builder::UninitializedFieldError::from("tokenizer"),
158                    ));
159                }
160            },
161            lowercase: self.lowercase.unwrap_or_default(),
162            min_token_len: self.min_token_len.unwrap_or_default(),
163            max_token_len: self.max_token_len.unwrap_or_default(),
164            on_disk: self.on_disk.unwrap_or_default(),
165            stopwords: self.stopwords.unwrap_or_default(),
166            phrase_matching: self.phrase_matching.unwrap_or_default(),
167            stemmer: self.stemmer.unwrap_or_default(),
168            ascii_folding: self.ascii_folding.unwrap_or_default(),
169            enable_hnsw: self.enable_hnsw.unwrap_or_default(),
170            memory: self.memory.unwrap_or_default(),
171        })
172    }
173
174    /// Create an empty builder, with all fields set to `None` or `PhantomData`.
175    fn create_empty() -> Self {
176        Self {
177            tokenizer: Default::default(),
178            lowercase: Default::default(),
179            min_token_len: Default::default(),
180            max_token_len: Default::default(),
181            on_disk: Default::default(),
182            stopwords: Default::default(),
183            phrase_matching: Default::default(),
184            stemmer: Default::default(),
185            ascii_folding: Default::default(),
186            enable_hnsw: Default::default(),
187            memory: Default::default(),
188        }
189    }
190}
191
192impl From<TextIndexParamsBuilder> for TextIndexParams {
193    fn from(value: TextIndexParamsBuilder) -> Self {
194        value.build_inner().unwrap_or_else(|_| {
195            panic!(
196                "Failed to convert {0} to {1}",
197                "TextIndexParamsBuilder", "TextIndexParams"
198            )
199        })
200    }
201}
202
203impl TextIndexParamsBuilder {
204    /// Builds the desired type. Can often be omitted.
205    pub fn build(self) -> TextIndexParams {
206        self.build_inner().unwrap_or_else(|_| {
207            panic!(
208                "Failed to build {0} into {1}",
209                "TextIndexParamsBuilder", "TextIndexParams"
210            )
211        })
212    }
213}
214
215#[non_exhaustive]
216#[derive(Debug)]
217pub enum TextIndexParamsBuilderError {
218    /// Uninitialized field
219    UninitializedField(&'static str),
220    /// Custom validation error
221    ValidationError(String),
222}
223
224// Implementing the Display trait for better error messages
225impl std::fmt::Display for TextIndexParamsBuilderError {
226    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
227        match self {
228            Self::UninitializedField(field) => {
229                write!(f, "`{field}` must be initialized")
230            }
231            Self::ValidationError(error) => write!(f, "{error}"),
232        }
233    }
234}
235
236// Implementing the Error trait
237impl std::error::Error for TextIndexParamsBuilderError {}
238
239// Implementing From trait for conversion from UninitializedFieldError
240impl From<derive_builder::UninitializedFieldError> for TextIndexParamsBuilderError {
241    fn from(error: derive_builder::UninitializedFieldError) -> Self {
242        Self::UninitializedField(error.field_name())
243    }
244}
245
246// Implementing From trait for conversion from String
247impl From<String> for TextIndexParamsBuilderError {
248    fn from(error: String) -> Self {
249        Self::ValidationError(error)
250    }
251}