From 4f0ead625b68bc58e86da3062534dc3c428b8d0f Mon Sep 17 00:00:00 2001 From: qdequele Date: Tue, 14 Jan 2020 17:26:27 +0100 Subject: [PATCH] adapt meilisearch-http to the new schemaless option --- Cargo.lock | 1 + meilisearch-core/Cargo.toml | 1 + meilisearch-core/src/settings.rs | 52 +++++++- meilisearch-core/src/store/main.rs | 9 +- meilisearch-core/src/store/mod.rs | 17 --- meilisearch-http/src/data.rs | 4 +- meilisearch-http/src/helpers/meilisearch.rs | 130 ++++++-------------- meilisearch-http/src/models/mod.rs | 1 - meilisearch-http/src/models/schema.rs | 118 ------------------ meilisearch-http/src/routes/document.rs | 46 ++++--- meilisearch-http/src/routes/index.rs | 110 +++-------------- meilisearch-http/src/routes/mod.rs | 8 +- meilisearch-http/src/routes/search.rs | 5 +- 13 files changed, 143 insertions(+), 359 deletions(-) delete mode 100644 meilisearch-http/src/models/schema.rs diff --git a/Cargo.lock b/Cargo.lock index 1cf7abef2..cdb159ae5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -970,6 +970,7 @@ dependencies = [ "meilisearch-types 0.8.4", "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustyline 5.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "sdset 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/meilisearch-core/Cargo.toml b/meilisearch-core/Cargo.toml index 790acb3fb..6bd3a4789 100644 --- a/meilisearch-core/Cargo.toml +++ b/meilisearch-core/Cargo.toml @@ -32,6 +32,7 @@ serde_json = "1.0.41" siphasher = "0.3.1" slice-group-by = "0.2.6" zerocopy = "0.2.8" +regex = "1" [dev-dependencies] assert_matches = "1.3" diff --git a/meilisearch-core/src/settings.rs b/meilisearch-core/src/settings.rs index 2f5a0510b..8131b1714 100644 --- a/meilisearch-core/src/settings.rs +++ b/meilisearch-core/src/settings.rs @@ -1,6 +1,14 @@ +use std::sync::Mutex; use std::collections::{BTreeMap, BTreeSet}; use serde::{Deserialize, Serialize}; +use once_cell::sync::Lazy; + +static RANKING_RULE_REGEX: Lazy> = Lazy::new(|| { + let regex = regex::Regex::new(r"(asc|dsc)\(([a-zA-Z0-9-_]*)\)").unwrap(); + Mutex::new(regex) +}); + #[derive(Default, Clone, Serialize, Deserialize)] pub struct Settings { @@ -17,8 +25,36 @@ pub struct Settings { impl Into for Settings { fn into(self) -> SettingsUpdate { let settings = self.clone(); + + let ranking_rules = match settings.ranking_rules { + Some(rules) => { + let mut final_rules = Vec::new(); + for rule in rules { + let parsed_rule = match rule.as_str() { + "_typo" => RankingRule::Typo, + "_words" => RankingRule::Words, + "_proximity" => RankingRule::Proximity, + "_attribute" => RankingRule::Attribute, + "_words_position" => RankingRule::WordsPosition, + "_exact" => RankingRule::Exact, + _ => { + let captures = RANKING_RULE_REGEX.lock().unwrap().captures(&rule).unwrap(); + match captures[0].as_ref() { + "asc" => RankingRule::Asc(captures[1].to_string()), + "dsc" => RankingRule::Dsc(captures[1].to_string()), + _ => continue + } + } + }; + final_rules.push(parsed_rule); + } + Some(final_rules) + } + None => None + }; + SettingsUpdate { - ranking_rules: settings.ranking_rules.into(), + ranking_rules: ranking_rules.into(), ranking_distinct: settings.ranking_distinct.into(), attribute_identifier: settings.attribute_identifier.into(), attributes_searchable: settings.attributes_searchable.into(), @@ -57,9 +93,21 @@ impl UpdateState { } } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum RankingRule { + Typo, + Words, + Proximity, + Attribute, + WordsPosition, + Exact, + Asc(String), + Dsc(String), +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SettingsUpdate { - pub ranking_rules: UpdateState>, + pub ranking_rules: UpdateState>, pub ranking_distinct: UpdateState, pub attribute_identifier: UpdateState, pub attributes_searchable: UpdateState>, diff --git a/meilisearch-core/src/store/main.rs b/meilisearch-core/src/store/main.rs index eec225503..96afc8263 100644 --- a/meilisearch-core/src/store/main.rs +++ b/meilisearch-core/src/store/main.rs @@ -8,6 +8,7 @@ use meilisearch_schema::Schema; use crate::database::MainT; use crate::RankedMap; +use crate::settings::RankingRule; const CREATED_AT_KEY: &str = "created-at"; const RANKING_RULES_KEY: &str = "ranking-rules-key"; @@ -188,12 +189,12 @@ impl Main { } } - pub fn ranking_rules<'txn>(&self, reader: &'txn heed::RoTxn) -> ZResult>> { - self.main.get::<_, Str, SerdeBincode>>(reader, RANKING_RULES_KEY) + pub fn ranking_rules<'txn>(&self, reader: &'txn heed::RoTxn) -> ZResult>> { + self.main.get::<_, Str, SerdeBincode>>(reader, RANKING_RULES_KEY) } - pub fn put_ranking_rules(self, writer: &mut heed::RwTxn, value: Vec) -> ZResult<()> { - self.main.put::<_, Str, SerdeBincode>>(writer, RANKING_RULES_KEY, &value) + pub fn put_ranking_rules(self, writer: &mut heed::RwTxn, value: Vec) -> ZResult<()> { + self.main.put::<_, Str, SerdeBincode>>(writer, RANKING_RULES_KEY, &value) } pub fn delete_ranking_rules(self, writer: &mut heed::RwTxn) -> ZResult { diff --git a/meilisearch-core/src/store/mod.rs b/meilisearch-core/src/store/mod.rs index 1c6eb5a91..d6d4e0ae2 100644 --- a/meilisearch-core/src/store/mod.rs +++ b/meilisearch-core/src/store/mod.rs @@ -43,22 +43,6 @@ use crate::{query_builder::QueryBuilder, update, DocIndex, DocumentId, Error, MR type BEU64 = zerocopy::U64; type BEU16 = zerocopy::U16; -// #[derive(Debug, Copy, Clone, AsBytes, FromBytes)] -// #[repr(C)] -// pub struct DocumentAttrKey { -// docid: BEU64, -// indexed_pos: BEU16, -// } - -// impl DocumentAttrKey { -// fn new(docid: DocumentId, indexed_pos: IndexedPos) -> DocumentAttrKey { -// DocumentAttrKey { -// docid: BEU64::new(docid.0), -// indexed_pos: BEU16::new(indexed_pos.0), -// } -// } -// } - #[derive(Debug, Copy, Clone, AsBytes, FromBytes)] #[repr(C)] pub struct DocumentFieldIndexedKey { @@ -271,7 +255,6 @@ impl Index { } } - pub fn customs_update(&self, writer: &mut heed::RwTxn, customs: Vec) -> ZResult { let _ = self.updates_notifier.send(UpdateEvent::NewUpdate); update::push_customs_update(writer, self.updates, self.updates_results, customs) diff --git a/meilisearch-http/src/data.rs b/meilisearch-http/src/data.rs index bc9f9effd..47c50ec72 100644 --- a/meilisearch-http/src/data.rs +++ b/meilisearch-http/src/data.rs @@ -84,13 +84,13 @@ impl DataInner { let mut fields_frequency = HashMap::<_, usize>::new(); for result in all_documents_fields { let (_, attr, _) = result?; - *fields_frequency.entry(attr).or_default() += 1; + *fields_frequency.entry(schema.indexed_pos_to_field_id(attr).unwrap()).or_default() += 1; } // convert attributes to their names let frequency: HashMap<_, _> = fields_frequency .into_iter() - .map(|(a, c)| (schema.attribute_name(a).to_owned(), c)) + .map(|(a, c)| (schema.get_name(a).unwrap(), c)) .collect(); index diff --git a/meilisearch-http/src/helpers/meilisearch.rs b/meilisearch-http/src/helpers/meilisearch.rs index 8741aa2a4..6f689d83b 100644 --- a/meilisearch-http/src/helpers/meilisearch.rs +++ b/meilisearch-http/src/helpers/meilisearch.rs @@ -1,11 +1,11 @@ -use crate::routes::setting::{RankingOrdering, Setting}; use indexmap::IndexMap; -use log::{error, warn}; +use log::error; use meilisearch_core::criterion::*; use meilisearch_core::Highlight; use meilisearch_core::{Index, RankedMap}; use meilisearch_core::MainT; -use meilisearch_schema::{Schema, SchemaAttr}; +use meilisearch_core::settings::RankingRule; +use meilisearch_schema::{Schema, FieldId}; use serde::{Deserialize, Serialize}; use serde_json::Value; use std::cmp::Ordering; @@ -172,7 +172,7 @@ impl<'a> SearchBuilder<'a> { let ref_index = &self.index; let value = value.trim().to_lowercase(); - let attr = match schema.attribute(attr) { + let attr = match schema.get_id(attr) { Some(attr) => attr, None => return Err(Error::UnknownFilteredAttribute), }; @@ -274,75 +274,24 @@ impl<'a> SearchBuilder<'a> { ranked_map: &'a RankedMap, schema: &Schema, ) -> Result>, Error> { - let current_settings = match self.index.main.customs(reader).unwrap() { - Some(bytes) => bincode::deserialize(bytes).unwrap(), - None => Setting::default(), - }; - - let ranking_rules = ¤t_settings.ranking_rules; - let ranking_order = ¤t_settings.ranking_order; + let ranking_rules = self.index.main.ranking_rules(reader).unwrap(); if let Some(ranking_rules) = ranking_rules { let mut builder = CriteriaBuilder::with_capacity(7 + ranking_rules.len()); - if let Some(ranking_rules_order) = ranking_order { - for rule in ranking_rules_order { - match rule.as_str() { - "_typo" => builder.push(Typo), - "_words" => builder.push(Words), - "_proximity" => builder.push(Proximity), - "_attribute" => builder.push(Attribute), - "_words_position" => builder.push(WordsPosition), - "_exact" => builder.push(Exact), - _ => { - let order = match ranking_rules.get(rule.as_str()) { - Some(o) => o, - None => continue, - }; - - let custom_ranking = match order { - RankingOrdering::Asc => { - SortByAttr::lower_is_better(&ranked_map, &schema, &rule) - .unwrap() - } - RankingOrdering::Dsc => { - SortByAttr::higher_is_better(&ranked_map, &schema, &rule) - .unwrap() - } - }; - - builder.push(custom_ranking); - } - } - } - builder.push(DocumentId); - return Ok(Some(builder.build())); - } else { - builder.push(Typo); - builder.push(Words); - builder.push(Proximity); - builder.push(Attribute); - builder.push(WordsPosition); - builder.push(Exact); - for (rule, order) in ranking_rules.iter() { - let custom_ranking = match order { - RankingOrdering::Asc => { - SortByAttr::lower_is_better(&ranked_map, &schema, &rule) - } - RankingOrdering::Dsc => { - SortByAttr::higher_is_better(&ranked_map, &schema, &rule) - } - }; - if let Ok(custom_ranking) = custom_ranking { - builder.push(custom_ranking); - } else { - // TODO push this warning to a log tree - warn!("Custom ranking cannot be added; Attribute {} not registered for ranking", rule) - } - - } - builder.push(DocumentId); - return Ok(Some(builder.build())); + for rule in ranking_rules { + match rule { + RankingRule::Typo => builder.push(Typo), + RankingRule::Words => builder.push(Words), + RankingRule::Proximity => builder.push(Proximity), + RankingRule::Attribute => builder.push(Attribute), + RankingRule::WordsPosition => builder.push(WordsPosition), + RankingRule::Exact => builder.push(Exact), + RankingRule::Asc(field) => builder.push(SortByAttr::lower_is_better(&ranked_map, &schema, &field).unwrap()), + RankingRule::Dsc(field) => builder.push(SortByAttr::higher_is_better(&ranked_map, &schema, &field).unwrap()), + }; } + builder.push(DocumentId); + return Ok(Some(builder.build())); } Ok(None) @@ -421,14 +370,14 @@ fn crop_document( matches.sort_unstable_by_key(|m| (m.char_index, m.char_length)); for (field, length) in fields { - let attribute = match schema.attribute(field) { + let attribute = match schema.get_id(field) { Some(attribute) => attribute, None => continue, }; let selected_matches = matches .iter() - .filter(|m| SchemaAttr::new(m.attribute) == attribute) + .filter(|m| FieldId::new(m.attribute) == attribute) .cloned(); if let Some(Value::String(ref mut original_text)) = document.get_mut(field) { @@ -437,7 +386,7 @@ fn crop_document( *original_text = cropped_text; - matches.retain(|m| SchemaAttr::new(m.attribute) != attribute); + matches.retain(|m| FieldId::new(m.attribute) != attribute); matches.extend_from_slice(&cropped_matches); } } @@ -450,26 +399,25 @@ fn calculate_matches( ) -> MatchesInfos { let mut matches_result: HashMap> = HashMap::new(); for m in matches.iter() { - let attribute = schema - .attribute_name(SchemaAttr::new(m.attribute)) - .to_string(); - if let Some(attributes_to_retrieve) = attributes_to_retrieve.clone() { - if !attributes_to_retrieve.contains(attribute.as_str()) { - continue; + if let Some(attribute) = schema.get_name(FieldId::new(m.attribute)) { + if let Some(attributes_to_retrieve) = attributes_to_retrieve.clone() { + if !attributes_to_retrieve.contains(attribute.as_str()) { + continue; + } + }; + if let Some(pos) = matches_result.get_mut(&attribute) { + pos.push(MatchPosition { + start: m.char_index as usize, + length: m.char_length as usize, + }); + } else { + let mut positions = Vec::new(); + positions.push(MatchPosition { + start: m.char_index as usize, + length: m.char_length as usize, + }); + matches_result.insert(attribute, positions); } - }; - if let Some(pos) = matches_result.get_mut(&attribute) { - pos.push(MatchPosition { - start: m.char_index as usize, - length: m.char_length as usize, - }); - } else { - let mut positions = Vec::new(); - positions.push(MatchPosition { - start: m.char_index as usize, - length: m.char_length as usize, - }); - matches_result.insert(attribute, positions); } } for (_, val) in matches_result.iter_mut() { diff --git a/meilisearch-http/src/models/mod.rs b/meilisearch-http/src/models/mod.rs index a6ce812e7..5f26bab01 100644 --- a/meilisearch-http/src/models/mod.rs +++ b/meilisearch-http/src/models/mod.rs @@ -1,3 +1,2 @@ -pub mod schema; pub mod token; pub mod update_operation; diff --git a/meilisearch-http/src/models/schema.rs b/meilisearch-http/src/models/schema.rs deleted file mode 100644 index 40e1183cb..000000000 --- a/meilisearch-http/src/models/schema.rs +++ /dev/null @@ -1,118 +0,0 @@ -use std::collections::HashSet; - -use indexmap::IndexMap; -use meilisearch_schema::{Schema, SchemaBuilder, SchemaProps}; -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub enum FieldProperties { - Identifier, - Indexed, - Displayed, - Ranked, -} - -#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] -pub struct SchemaBody(IndexMap>); - -impl From for SchemaBody { - fn from(value: Schema) -> SchemaBody { - let mut map = IndexMap::new(); - for (name, _attr, props) in value.iter() { - let old_properties = map.entry(name.to_owned()).or_insert(HashSet::new()); - if props.is_indexed() { - old_properties.insert(FieldProperties::Indexed); - } - if props.is_displayed() { - old_properties.insert(FieldProperties::Displayed); - } - if props.is_ranked() { - old_properties.insert(FieldProperties::Ranked); - } - } - let old_properties = map - .entry(value.identifier_name().to_string()) - .or_insert(HashSet::new()); - old_properties.insert(FieldProperties::Identifier); - old_properties.insert(FieldProperties::Displayed); - SchemaBody(map) - } -} - -impl Into for SchemaBody { - fn into(self) -> Schema { - let mut identifier = "documentId".to_string(); - let mut attributes = IndexMap::new(); - for (field, properties) in self.0 { - let mut indexed = false; - let mut displayed = false; - let mut ranked = false; - for property in properties { - match property { - FieldProperties::Indexed => indexed = true, - FieldProperties::Displayed => displayed = true, - FieldProperties::Ranked => ranked = true, - FieldProperties::Identifier => identifier = field.clone(), - } - } - attributes.insert( - field, - SchemaProps { - indexed, - displayed, - ranked, - }, - ); - } - - let mut builder = SchemaBuilder::with_identifier(identifier); - for (field, props) in attributes { - builder.new_attribute(field, props); - } - builder.build() - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_schema_body_conversion() { - let schema_body = r#" - { - "id": ["identifier", "indexed", "displayed"], - "title": ["indexed", "displayed"], - "date": ["displayed"] - } - "#; - - let schema_builder = r#" - { - "identifier": "id", - "attributes": { - "id": { - "indexed": true, - "displayed": true - }, - "title": { - "indexed": true, - "displayed": true - }, - "date": { - "displayed": true - } - } - } - "#; - - let schema_body: SchemaBody = serde_json::from_str(schema_body).unwrap(); - let schema_builder: SchemaBuilder = serde_json::from_str(schema_builder).unwrap(); - - let schema_from_body: Schema = schema_body.into(); - let schema_from_builder: Schema = schema_builder.build(); - - assert_eq!(schema_from_body, schema_from_builder); - } -} diff --git a/meilisearch-http/src/routes/document.rs b/meilisearch-http/src/routes/document.rs index ebb3851be..3312975db 100644 --- a/meilisearch-http/src/routes/document.rs +++ b/meilisearch-http/src/routes/document.rs @@ -1,3 +1,4 @@ + use std::collections::{BTreeSet, HashSet}; use http::StatusCode; @@ -7,6 +8,7 @@ use serde_json::Value; use tide::querystring::ContextExt as QSContextExt; use tide::response::IntoResponse; use tide::{Context, Response}; +use meilisearch_core::settings::Settings; use crate::error::{ResponseError, SResult}; use crate::helpers::tide::ContextExt; @@ -117,27 +119,13 @@ pub async fn get_all_documents(ctx: Context) -> SResult { Ok(tide::response::json(response_body)) } -fn infered_schema(document: &IndexMap, identifier: Option) -> Option { - use meilisearch_schema::{SchemaBuilder, DISPLAYED, INDEXED}; - - let mut identifier = identifier; +fn find_identifier(document: &IndexMap) -> Option { for key in document.keys() { - if identifier.is_none() && key.to_lowercase().contains("id") { - identifier = Some(key.to_string()); - break; + if key.to_lowercase().contains("id") { + return Some(key.to_string()) } } - - match identifier { - Some(identifier) => { - let mut builder = SchemaBuilder::with_identifier(identifier); - for key in document.keys() { - builder.new_attribute(key, DISPLAYED | INDEXED); - } - Some(builder.build()) - } - None => None, - } + return None } #[derive(Default, Deserialize)] @@ -165,14 +153,22 @@ async fn update_multiple_documents(mut ctx: Context, is_partial: bool) -> .schema(&reader) .map_err(ResponseError::internal)?; if current_schema.is_none() { - match data.first().and_then(|docs| infered_schema(docs, query.identifier)) { - Some(schema) => { - index - .schema_update(&mut update_writer, schema) - .map_err(ResponseError::internal)?; + let id = match query.identifier { + Some(id) => id, + None => { + match data.first().and_then(|docs| find_identifier(docs)) { + Some(id) => id, + None => return Err(ResponseError::bad_request("Could not infer a schema")), + } } - None => return Err(ResponseError::bad_request("Could not infer a schema")), - } + }; + let settings = Settings { + attribute_identifier: Some(id), + ..Settings::default() + }; + index + .settings_update(&mut update_writer, settings.into()) + .map_err(ResponseError::internal)?; } let mut document_addition = if is_partial { diff --git a/meilisearch-http/src/routes/index.rs b/meilisearch-http/src/routes/index.rs index 61691923a..379a4d40f 100644 --- a/meilisearch-http/src/routes/index.rs +++ b/meilisearch-http/src/routes/index.rs @@ -2,19 +2,16 @@ use chrono::{DateTime, Utc}; use http::StatusCode; use log::error; use meilisearch_core::ProcessedUpdateResult; -use meilisearch_schema::{Schema, SchemaBuilder}; +// use meilisearch_schema::Schema; use rand::seq::SliceRandom; use serde::{Deserialize, Serialize}; use serde_json::json; -use tide::querystring::ContextExt as QSContextExt; use tide::response::IntoResponse; use tide::{Context, Response}; use crate::error::{ResponseError, SResult}; use crate::helpers::tide::ContextExt; -use crate::models::schema::SchemaBody; use crate::models::token::ACL::*; -use crate::routes::document::IndexUpdateResponse; use crate::Data; fn generate_uid() -> String { @@ -124,7 +121,7 @@ pub async fn get_index(ctx: Context) -> SResult { struct IndexCreateRequest { name: String, uid: Option, - schema: Option, + // schema: Option, } #[derive(Debug, Serialize)] @@ -132,9 +129,9 @@ struct IndexCreateRequest { struct IndexCreateResponse { name: String, uid: String, - schema: Option, - #[serde(skip_serializing_if = "Option::is_none")] - update_id: Option, + // schema: Option, + // #[serde(skip_serializing_if = "Option::is_none")] + // update_id: Option, created_at: DateTime, updated_at: DateTime, } @@ -165,30 +162,29 @@ pub async fn create_index(mut ctx: Context) -> SResult { }; let mut writer = db.main_write_txn().map_err(ResponseError::internal)?; - let mut update_writer = db.update_write_txn().map_err(ResponseError::internal)?; created_index .main .put_name(&mut writer, &body.name) .map_err(ResponseError::internal)?; - let schema: Option = body.schema.clone().map(Into::into); - let mut response_update_id = None; - if let Some(schema) = schema { - let update_id = created_index - .schema_update(&mut update_writer, schema) - .map_err(ResponseError::internal)?; - response_update_id = Some(update_id) - } + // let schema: Option = body.schema.clone().map(Into::into); + // let mut response_update_id = None; + // if let Some(schema) = schema { + // let update_id = created_index + // .schema_update(&mut update_writer, schema) + // .map_err(ResponseError::internal)?; + // response_update_id = Some(update_id) + // } - writer.commit().map_err(ResponseError::internal)?; - update_writer.commit().map_err(ResponseError::internal)?; + // writer.commit().map_err(ResponseError::internal)?; + // update_writer.commit().map_err(ResponseError::internal)?; let response_body = IndexCreateResponse { name: body.name, uid, - schema: body.schema, - update_id: response_update_id, + // schema: body.schema, + // update_id: update_id, created_at: Utc::now(), updated_at: Utc::now(), }; @@ -263,78 +259,6 @@ pub async fn update_index(mut ctx: Context) -> SResult { .into_response()) } -#[derive(Default, Deserialize)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -struct SchemaParams { - raw: bool, -} - -pub async fn get_index_schema(ctx: Context) -> SResult { - ctx.is_allowed(IndexesRead)?; - - let index = ctx.index()?; - - // Tide doesn't support "no query param" - let params: SchemaParams = ctx.url_query().unwrap_or_default(); - - let db = &ctx.state().db; - let reader = db.main_read_txn().map_err(ResponseError::internal)?; - - let schema = index - .main - .schema(&reader) - .map_err(ResponseError::open_index)?; - - match schema { - Some(schema) => { - if params.raw { - Ok(tide::response::json(schema)) - } else { - Ok(tide::response::json(SchemaBody::from(schema))) - } - } - None => Err(ResponseError::not_found("missing index schema")), - } -} - -pub async fn update_schema(mut ctx: Context) -> SResult { - ctx.is_allowed(IndexesWrite)?; - - let index_uid = ctx.url_param("index")?; - - let params: SchemaParams = ctx.url_query().unwrap_or_default(); - - let schema = if params.raw { - ctx.body_json::() - .await - .map_err(ResponseError::bad_request)? - .build() - } else { - ctx.body_json::() - .await - .map_err(ResponseError::bad_request)? - .into() - }; - - let db = &ctx.state().db; - let mut writer = db.update_write_txn().map_err(ResponseError::internal)?; - - let index = db - .open_index(&index_uid) - .ok_or(ResponseError::index_not_found(index_uid))?; - - let update_id = index - .schema_update(&mut writer, schema.clone()) - .map_err(ResponseError::internal)?; - - writer.commit().map_err(ResponseError::internal)?; - - let response_body = IndexUpdateResponse { update_id }; - Ok(tide::response::json(response_body) - .with_status(StatusCode::ACCEPTED) - .into_response()) -} - pub async fn get_update_status(ctx: Context) -> SResult { ctx.is_allowed(IndexesRead)?; diff --git a/meilisearch-http/src/routes/mod.rs b/meilisearch-http/src/routes/mod.rs index a0463075a..128ceeddd 100644 --- a/meilisearch-http/src/routes/mod.rs +++ b/meilisearch-http/src/routes/mod.rs @@ -51,10 +51,10 @@ pub fn load_routes(app: &mut tide::App) { .put(index::update_index) .delete(index::delete_index); - router - .at("/schema") - .get(index::get_index_schema) - .put(index::update_schema); + // router + // .at("/schema") + // .get(index::get_index_schema) + // .put(index::update_schema); router.at("/documents").nest(|router| { router diff --git a/meilisearch-http/src/routes/search.rs b/meilisearch-http/src/routes/search.rs index 69f64c932..88ac24fd0 100644 --- a/meilisearch-http/src/routes/search.rs +++ b/meilisearch-http/src/routes/search.rs @@ -64,8 +64,9 @@ pub async fn search_with_url_query(ctx: Context) -> SResult { let crop_length = query.crop_length.unwrap_or(200); if attributes_to_crop == "*" { let attributes_to_crop = schema + .get_displayed_name() .iter() - .map(|(attr, ..)| (attr.to_string(), crop_length)) + .map(|attr| (attr.to_string(), crop_length)) .collect(); search_builder.attributes_to_crop(attributes_to_crop); } else { @@ -79,7 +80,7 @@ pub async fn search_with_url_query(ctx: Context) -> SResult { if let Some(attributes_to_highlight) = query.attributes_to_highlight { let attributes_to_highlight = if attributes_to_highlight == "*" { - schema.iter().map(|(attr, ..)| attr.to_string()).collect() + schema.get_displayed_name() } else { attributes_to_highlight .split(',')