diff --git a/meilisearch-http/src/routes/setting.rs b/meilisearch-http/src/routes/setting.rs index c7abd6ce4..37fe5bda2 100644 --- a/meilisearch-http/src/routes/setting.rs +++ b/meilisearch-http/src/routes/setting.rs @@ -25,7 +25,10 @@ pub fn services(cfg: &mut web::ServiceConfig) { .service(update_displayed) .service(delete_displayed) .service(get_accept_new_fields) - .service(update_accept_new_fields); + .service(update_accept_new_fields) + .service(get_attributes_for_faceting) + .service(delete_attributes_for_faceting) + .service(update_attributes_for_faceting); } #[post("/indexes/{index_uid}/settings", wrap = "Authentication::Private")] @@ -92,15 +95,17 @@ async fn get_all( let attributes_for_faceting = match (&schema, &index.main.attributes_for_faceting(&reader)?) { (Some(schema), Some(attrs)) => { - Some(attrs + attrs .iter() - .filter_map(|&id| schema .name(id)) + .filter_map(|&id| schema.name(id)) .map(str::to_string) - .collect()) + .collect() } - _ => None, + _ => vec![], }; + println!("{:?}", attributes_for_faceting); + let searchable_attributes = schema.clone().map(|s| { s.indexed_name() .iter() @@ -125,7 +130,7 @@ async fn get_all( stop_words: Some(Some(stop_words)), synonyms: Some(Some(synonyms)), accept_new_fields: Some(accept_new_fields), - attributes_for_faceting: Some(attributes_for_faceting), + attributes_for_faceting: Some(Some(attributes_for_faceting)), }; Ok(HttpResponse::Ok().json(settings)) @@ -481,3 +486,85 @@ async fn update_accept_new_fields( Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) } + +#[get( + "/indexes/{index_uid}/settings/attributes-for-faceting", + wrap = "Authentication::Private" +)] +async fn get_attributes_for_faceting( + data: web::Data, + path: web::Path, +) -> Result { + let index = data + .db + .open_index(&path.index_uid) + .ok_or(Error::index_not_found(&path.index_uid))?; + + let attributes_for_faceting = data + .db + .main_read::<_, _, ResponseError>(|reader| { + let schema = index.main.schema(reader)?; + let attrs = index.main.attributes_for_faceting(reader)?; + let attr_names = match (&schema, &attrs) { + (Some(schema), Some(attrs)) => { + attrs + .iter() + .filter_map(|&id| schema.name(id)) + .map(str::to_string) + .collect() + } + _ => vec![] + }; + Ok(attr_names) + })?; + + Ok(HttpResponse::Ok().json(attributes_for_faceting)) +} + +#[post( + "/indexes/{index_uid}/settings/attributes-for-faceting", + wrap = "Authentication::Private" +)] +async fn update_attributes_for_faceting( + data: web::Data, + path: web::Path, + body: web::Json>>, +) -> Result { + let index = data + .db + .open_index(&path.index_uid) + .ok_or(Error::index_not_found(&path.index_uid))?; + + let settings = Settings { + attributes_for_faceting: Some(body.into_inner()), + ..Settings::default() + }; + + let settings = settings.into_update().map_err(Error::bad_request)?; + let update_id = data.db.update_write(|w| index.settings_update(w, settings))?; + + Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) +} + +#[delete( + "/indexes/{index_uid}/settings/attributes-for-faceting", + wrap = "Authentication::Private" +)] +async fn delete_attributes_for_faceting( + data: web::Data, + path: web::Path, +) -> Result { + let index = data + .db + .open_index(&path.index_uid) + .ok_or(Error::index_not_found(&path.index_uid))?; + + let settings = SettingsUpdate { + attributes_for_faceting: UpdateState::Clear, + ..SettingsUpdate::default() + }; + + let update_id = data.db.update_write(|w| index.settings_update(w, settings))?; + + Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id))) +} diff --git a/meilisearch-http/tests/settings.rs b/meilisearch-http/tests/settings.rs index ad2d8caab..dcbe5760f 100644 --- a/meilisearch-http/tests/settings.rs +++ b/meilisearch-http/tests/settings.rs @@ -120,7 +120,7 @@ async fn write_all_and_delete() { ], "stopWords": [], "synonyms": {}, - "attributesForFaceting": null, + "attributesForFaceting": [], "acceptNewFields": true, }); @@ -282,7 +282,7 @@ async fn test_default_settings() { "displayedAttributes": [], "stopWords": [], "synonyms": {}, - "attributesForFaceting": null, + "attributesForFaceting": [], "acceptNewFields": true, }); @@ -320,7 +320,7 @@ async fn test_default_settings_2() { ], "stopWords": [], "synonyms": {}, - "attributesForFaceting": null, + "attributesForFaceting": [], "acceptNewFields": true, }); @@ -428,7 +428,7 @@ async fn write_setting_and_update_partial() { "wolverine": ["xmen", "logan"], "logan": ["wolverine"], }, - "attributesForFaceting": null, + "attributesForFaceting": [], "acceptNewFields": false, }); @@ -436,3 +436,22 @@ async fn write_setting_and_update_partial() { assert_json_eq!(expected, response, ordered: false); } + +#[actix_rt::test] +async fn attributes_for_faceting_settings() { + let mut server = common::Server::test_server().await; + // initial attributes array should be empty + let (response, _status_code) = server.get_request("/indexes/test/settings/attributes-for-faceting").await; + assert_eq!(response, json!([])); + // add an attribute and test for its presence + let (_response, _status_code) = server.post_request_async( + "/indexes/test/settings/attributes-for-faceting", + json!(["foobar"])).await; + let (response, _status_code) = server.get_request("/indexes/test/settings/attributes-for-faceting").await; + assert_eq!(response, json!(["foobar"])); + // remove all attributes and test for emptiness + let (_response, _status_code) = server.delete_request_async( + "/indexes/test/settings/attributes-for-faceting").await; + let (response, _status_code) = server.get_request("/indexes/test/settings/attributes-for-faceting").await; + assert_eq!(response, json!([])); +} diff --git a/meilisearch-http/tests/settings_accept_new_fields.rs b/meilisearch-http/tests/settings_accept_new_fields.rs index 8d2ebe1d9..6cc14deed 100644 --- a/meilisearch-http/tests/settings_accept_new_fields.rs +++ b/meilisearch-http/tests/settings_accept_new_fields.rs @@ -341,7 +341,7 @@ async fn accept_new_fields_does_not_take_into_account_the_primary_key() { "displayedAttributes": ["title"], "stopWords": [], "synonyms": {}, - "attributesForFaceting": null, + "attributesForFaceting": [], "acceptNewFields": false, });