mirror of
				https://github.com/meilisearch/meilisearch.git
				synced 2025-10-31 07:56:28 +00:00 
			
		
		
		
	stops storing the whole fieldids weights map when no searchable are defined
This commit is contained in:
		| @@ -4,7 +4,7 @@ use std::collections::HashMap; | ||||
|  | ||||
| use serde::{Deserialize, Serialize}; | ||||
|  | ||||
| use crate::{FieldId, Weight}; | ||||
| use crate::{FieldId, FieldsIdsMap, Weight}; | ||||
|  | ||||
| #[derive(Debug, Default, Serialize, Deserialize)] | ||||
| pub struct FieldidsWeightsMap { | ||||
| @@ -19,6 +19,13 @@ impl FieldidsWeightsMap { | ||||
|         self.map.insert(fid, weight) | ||||
|     } | ||||
|  | ||||
|     /// Create the map from the fields ids maps. | ||||
|     /// Should only be called in the case there are NO searchable attributes. | ||||
|     /// The weights and the fields ids will have the same values. | ||||
|     pub fn from_field_id_map_without_searchable(fid_map: &FieldsIdsMap) -> Self { | ||||
|         FieldidsWeightsMap { map: fid_map.ids().map(|fid| (fid, fid)).collect() } | ||||
|     } | ||||
|  | ||||
|     /// Removes a field id from the map, returning the associated weight previously in the map. | ||||
|     pub fn remove(&mut self, fid: FieldId) -> Option<Weight> { | ||||
|         self.map.remove(&fid) | ||||
|   | ||||
| @@ -436,11 +436,20 @@ impl Index { | ||||
|  | ||||
|     /// Get the fieldids weights map which associates the field ids to their weights | ||||
|     pub fn fieldids_weights_map(&self, rtxn: &RoTxn) -> heed::Result<FieldidsWeightsMap> { | ||||
|         Ok(self | ||||
|             .main | ||||
|         self.main | ||||
|             .remap_types::<Str, SerdeJson<_>>() | ||||
|             .get(rtxn, main_key::FIELDIDS_WEIGHTS_MAP_KEY)? | ||||
|             .unwrap_or_default()) | ||||
|             .map(Ok) | ||||
|             .unwrap_or_else(|| { | ||||
|                 Ok(FieldidsWeightsMap::from_field_id_map_without_searchable( | ||||
|                     &self.fields_ids_map(rtxn)?, | ||||
|                 )) | ||||
|             }) | ||||
|     } | ||||
|  | ||||
|     /// Delete the fieldsids weights map | ||||
|     pub fn delete_fieldids_weights_map(&self, wtxn: &mut RwTxn) -> heed::Result<bool> { | ||||
|         self.main.remap_key_type::<Str>().delete(wtxn, main_key::FIELDIDS_WEIGHTS_MAP_KEY) | ||||
|     } | ||||
|  | ||||
|     pub fn searchable_fields_and_weights<'a>( | ||||
| @@ -629,29 +638,13 @@ impl Index { | ||||
|     pub(crate) fn put_all_searchable_fields_from_fields_ids_map( | ||||
|         &self, | ||||
|         wtxn: &mut RwTxn, | ||||
|         user_fields: Option<&[&str]>, | ||||
|         user_fields: &[&str], | ||||
|         fields_ids_map: &FieldsIdsMap, | ||||
|     ) -> Result<()> { | ||||
|         // Special case if there is no user defined fields. | ||||
|         // Then the whole field id map is marked as searchable. | ||||
|         if user_fields.is_none() { | ||||
|             let mut weights = self.fieldids_weights_map(wtxn)?; | ||||
|             let mut searchable = Vec::new(); | ||||
|             for (weight, (fid, name)) in fields_ids_map.iter().enumerate() { | ||||
|                 searchable.push(name); | ||||
|                 weights.insert(fid, weight as u16); | ||||
|             } | ||||
|             self.put_searchable_fields(wtxn, &searchable)?; | ||||
|             self.put_fieldids_weights_map(wtxn, &weights)?; | ||||
|             return Ok(()); | ||||
|         } | ||||
|  | ||||
|         let user_fields = user_fields.unwrap(); | ||||
|  | ||||
|         // We can write the user defined searchable fields as-is. | ||||
|         self.put_user_defined_searchable_fields(wtxn, user_fields)?; | ||||
|  | ||||
|         let mut weights = self.fieldids_weights_map(wtxn)?; | ||||
|         let mut weights = FieldidsWeightsMap::default(); | ||||
|  | ||||
|         // Now we generate the real searchable fields: | ||||
|         // 1. Take the user defined searchable fields as-is to keep the priority defined by the attributes criterion. | ||||
| @@ -682,6 +675,7 @@ impl Index { | ||||
|     pub(crate) fn delete_all_searchable_fields(&self, wtxn: &mut RwTxn) -> heed::Result<bool> { | ||||
|         let did_delete_searchable = self.delete_searchable_fields(wtxn)?; | ||||
|         let did_delete_user_defined = self.delete_user_defined_searchable_fields(wtxn)?; | ||||
|         self.delete_fieldids_weights_map(wtxn)?; | ||||
|         Ok(did_delete_searchable || did_delete_user_defined) | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -490,7 +490,7 @@ impl<'a, 't, 'i> Settings<'a, 't, 'i> { | ||||
|  | ||||
|                 self.index.put_all_searchable_fields_from_fields_ids_map( | ||||
|                     self.wtxn, | ||||
|                     Some(&names), | ||||
|                     &names, | ||||
|                     &fields_ids_map, | ||||
|                 )?; | ||||
|                 self.index.put_fields_ids_map(self.wtxn, &fields_ids_map)?; | ||||
| @@ -1228,11 +1228,13 @@ impl InnerIndexSettings { | ||||
|             .map(|searchable| searchable.iter().map(|s| s.as_str()).collect::<Vec<_>>()); | ||||
|  | ||||
|         // in case new fields were introduced we're going to recreate the searchable fields. | ||||
|         index.put_all_searchable_fields_from_fields_ids_map( | ||||
|             wtxn, | ||||
|             searchable_fields.as_deref(), | ||||
|             &self.fields_ids_map, | ||||
|         )?; | ||||
|         if let Some(searchable_fields) = searchable_fields { | ||||
|             index.put_all_searchable_fields_from_fields_ids_map( | ||||
|                 wtxn, | ||||
|                 &searchable_fields, | ||||
|                 &self.fields_ids_map, | ||||
|             )?; | ||||
|         } | ||||
|         let searchable_fields_ids = index.searchable_fields_ids(wtxn)?; | ||||
|         self.searchable_fields_ids = searchable_fields_ids; | ||||
|  | ||||
| @@ -1513,7 +1515,7 @@ mod tests { | ||||
|     use crate::error::Error; | ||||
|     use crate::index::tests::TempIndex; | ||||
|     use crate::update::ClearDocuments; | ||||
|     use crate::{Criterion, Filter, SearchResult}; | ||||
|     use crate::{db_snap, Criterion, Filter, SearchResult}; | ||||
|  | ||||
|     #[test] | ||||
|     fn set_and_reset_searchable_fields() { | ||||
| @@ -1542,6 +1544,17 @@ mod tests { | ||||
|  | ||||
|         wtxn.commit().unwrap(); | ||||
|  | ||||
|         db_snap!(index, fields_ids_map, @r###" | ||||
|         0   id               | | ||||
|         1   name             | | ||||
|         2   age              | | ||||
|         "###); | ||||
|         db_snap!(index, searchable_fields, @r###"["name"]"###); | ||||
|         db_snap!(index, fieldids_weights_map, @r###" | ||||
|         fid weight | ||||
|         1   0   | | ||||
|         "###); | ||||
|  | ||||
|         // Check that the searchable field is correctly set to "name" only. | ||||
|         let rtxn = index.read_txn().unwrap(); | ||||
|         // When we search for something that is not in | ||||
| @@ -1565,6 +1578,19 @@ mod tests { | ||||
|             }) | ||||
|             .unwrap(); | ||||
|  | ||||
|         db_snap!(index, fields_ids_map, @r###" | ||||
|         0   id               | | ||||
|         1   name             | | ||||
|         2   age              | | ||||
|         "###); | ||||
|         db_snap!(index, searchable_fields, @r###"["id", "name", "age"]"###); | ||||
|         db_snap!(index, fieldids_weights_map, @r###" | ||||
|         fid weight | ||||
|         0   0   | | ||||
|         1   1   | | ||||
|         2   2   | | ||||
|         "###); | ||||
|  | ||||
|         // Check that the searchable field have been reset and documents are found now. | ||||
|         let rtxn = index.read_txn().unwrap(); | ||||
|         let fid_map = index.fields_ids_map(&rtxn).unwrap(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user