diff --git a/milli/src/index.rs b/milli/src/index.rs index c0be985da..f4e17d93c 100644 --- a/milli/src/index.rs +++ b/milli/src/index.rs @@ -53,6 +53,7 @@ pub mod main_key { pub const ONE_TYPO_WORD_LEN: &str = "one-typo-word-len"; pub const TWO_TYPOS_WORD_LEN: &str = "two-typos-word-len"; pub const EXACT_WORDS: &str = "exact-words"; + pub const EXACT_ATTRIBUTES: &str = "exact-attributes"; } pub mod db_name { @@ -949,6 +950,23 @@ impl Index { )?; Ok(()) } + + pub fn exact_attributes<'t>(&self, txn: &'t RoTxn) -> Result> { + Ok(self + .main + .get::<_, Str, SerdeBincode>>(txn, main_key::EXACT_ATTRIBUTES)? + .unwrap_or_default()) + } + + pub(crate) fn put_exact_attributes(&self, txn: &mut RwTxn, attrs: &[&str]) -> Result<()> { + self.main.put::<_, Str, SerdeBincode<&[&str]>>(txn, main_key::EXACT_ATTRIBUTES, &attrs)?; + Ok(()) + } + + pub(crate) fn delete_exact_attributes(&self, txn: &mut RwTxn) -> Result<()> { + self.main.delete::<_, Str>(txn, main_key::EXACT_ATTRIBUTES)?; + Ok(()) + } } #[cfg(test)] diff --git a/milli/src/update/settings.rs b/milli/src/update/settings.rs index 503fbd06e..3ed2a4152 100644 --- a/milli/src/update/settings.rs +++ b/milli/src/update/settings.rs @@ -93,6 +93,8 @@ pub struct Settings<'a, 't, 'u, 'i> { min_word_len_two_typos: Setting, min_word_len_one_typo: Setting, exact_words: Setting>, + /// attributes on which typo tolerance is not enabled. + exact_attributes: Setting>, } impl<'a, 't, 'u, 'i> Settings<'a, 't, 'u, 'i> { @@ -117,6 +119,7 @@ impl<'a, 't, 'u, 'i> Settings<'a, 't, 'u, 'i> { exact_words: Setting::NotSet, min_word_len_two_typos: Setting::Reset, min_word_len_one_typo: Setting::Reset, + exact_attributes: Setting::Reset, indexer_config, } } @@ -226,6 +229,14 @@ impl<'a, 't, 'u, 'i> Settings<'a, 't, 'u, 'i> { self.exact_words = Setting::Reset; } + pub fn set_exact_attributes(&mut self, attrs: HashSet) { + self.exact_attributes = Setting::Set(attrs); + } + + pub fn reset_exact_attributes(&mut self) { + self.exact_attributes = Setting::Reset; + } + fn reindex(&mut self, cb: &F, old_fields_ids_map: FieldsIdsMap) -> Result<()> where F: Fn(UpdateIndexingStep) + Sync, @@ -411,6 +422,21 @@ impl<'a, 't, 'u, 'i> Settings<'a, 't, 'u, 'i> { } } + fn update_exact_attributes(&mut self) -> Result { + match self.exact_attributes { + Setting::Set(ref attrs) => { + let attrs = attrs.iter().map(String::as_str).collect::>(); + self.index.put_exact_attributes(&mut self.wtxn, &attrs)?; + Ok(true) + } + Setting::Reset => { + self.index.delete_exact_attributes(&mut self.wtxn)?; + Ok(true) + } + Setting::NotSet => Ok(false), + } + } + fn update_filterable(&mut self) -> Result<()> { match self.filterable_fields { Setting::Set(ref fields) => { @@ -579,8 +605,14 @@ impl<'a, 't, 'u, 'i> Settings<'a, 't, 'u, 'i> { let stop_words_updated = self.update_stop_words()?; let synonyms_updated = self.update_synonyms()?; let searchable_updated = self.update_searchable()?; + let exact_attributes_updated = self.update_exact_attributes()?; - if stop_words_updated || faceted_updated || synonyms_updated || searchable_updated { + if stop_words_updated + || faceted_updated + || synonyms_updated + || searchable_updated + || exact_attributes_updated + { self.reindex(&progress_callback, old_fields_ids_map)?; }