stop updating the fields ids map when fields are only swapped

This commit is contained in:
Tamo 2024-05-13 16:49:08 +02:00
parent 9ecde41853
commit b0afe0972e
2 changed files with 17 additions and 13 deletions

View File

@ -2662,17 +2662,18 @@ pub(crate) mod tests {
settings.set_filterable_fields(HashSet::from([S("age")])); settings.set_filterable_fields(HashSet::from([S("age")]));
}) })
.unwrap(); .unwrap();
// The order of the field id map shouldn't change
db_snap!(index, fields_ids_map, @r###" db_snap!(index, fields_ids_map, @r###"
0 name | 0 name |
1 realName | 1 id |
2 id | 2 age |
3 age | 3 realName |
"###); "###);
db_snap!(index, searchable_fields, @r###"["name", "realName"]"###); db_snap!(index, searchable_fields, @r###"["name", "realName"]"###);
db_snap!(index, fieldids_weights_map, @r###" db_snap!(index, fieldids_weights_map, @r###"
fid weight fid weight
0 0 | 0 0 |
1 1 | 3 1 |
"###); "###);
} }
} }

View File

@ -12,6 +12,7 @@ use time::OffsetDateTime;
use super::index_documents::{IndexDocumentsConfig, Transform}; use super::index_documents::{IndexDocumentsConfig, Transform};
use super::IndexerConfig; use super::IndexerConfig;
use crate::criterion::Criterion; use crate::criterion::Criterion;
use crate::documents::FieldIdMapper;
use crate::error::UserError; use crate::error::UserError;
use crate::index::{DEFAULT_MIN_WORD_LEN_ONE_TYPO, DEFAULT_MIN_WORD_LEN_TWO_TYPOS}; use crate::index::{DEFAULT_MIN_WORD_LEN_ONE_TYPO, DEFAULT_MIN_WORD_LEN_TWO_TYPOS};
use crate::order_by_map::OrderByMap; use crate::order_by_map::OrderByMap;
@ -461,8 +462,7 @@ impl<'a, 't, 'i> Settings<'a, 't, 'i> {
Ok(true) Ok(true)
} }
/// Updates the index's searchable attributes. This causes the field map to be recomputed to /// Updates the index's searchable attributes.
/// reflect the order of the searchable attributes.
fn update_searchable(&mut self) -> Result<bool> { fn update_searchable(&mut self) -> Result<bool> {
match self.searchable_fields { match self.searchable_fields {
Setting::Set(ref fields) => { Setting::Set(ref fields) => {
@ -480,17 +480,20 @@ impl<'a, 't, 'i> Settings<'a, 't, 'i> {
// ids for any settings that uses the facets. (distinct_fields, filterable_fields). // ids for any settings that uses the facets. (distinct_fields, filterable_fields).
let old_fields_ids_map = self.index.fields_ids_map(self.wtxn)?; let old_fields_ids_map = self.index.fields_ids_map(self.wtxn)?;
let mut new_fields_ids_map = FieldsIdsMap::new(); // Since we're updating the settings we can only add new fields at the end of the field id map
let mut new_fields_ids_map = old_fields_ids_map.clone();
let names = fields
.iter()
// fields are deduplicated, only the first occurrence is taken into account // fields are deduplicated, only the first occurrence is taken into account
let names = fields.iter().unique().map(String::as_str).collect::<Vec<_>>(); .unique()
.map(String::as_str)
.collect::<Vec<_>>();
// Add all the searchable attributes to the field map, and then add the // Add all the searchable attributes to the field map, and then add the
// remaining fields from the old field map to the new one // remaining fields from the old field map to the new one
for name in names.iter() { for name in names.iter() {
new_fields_ids_map.insert(name).ok_or(UserError::AttributeLimitReached)?; // The fields ids map won't change the field id of already present elements thus only the
} // new fields will be inserted.
for (_, name) in old_fields_ids_map.iter() {
new_fields_ids_map.insert(name).ok_or(UserError::AttributeLimitReached)?; new_fields_ids_map.insert(name).ok_or(UserError::AttributeLimitReached)?;
} }