diff --git a/meilisearch-core/src/update/documents_addition.rs b/meilisearch-core/src/update/documents_addition.rs index 668ce5613..350f5dd35 100644 --- a/meilisearch-core/src/update/documents_addition.rs +++ b/meilisearch-core/src/update/documents_addition.rs @@ -212,11 +212,6 @@ pub fn apply_addition<'a, 'b>( let stop_words = index.main.stop_words_fst(writer)?.map_data(Cow::into_owned)?; - // 3. index the documents fields in the stores - if let Some(attributes_for_facetting) = index.main.attributes_for_faceting(writer)? { - let facet_map = facets::facet_map_from_docs(&schema, &documents_additions, attributes_for_facetting.as_ref())?; - index.facets.add(writer, facet_map)?; - } let mut indexer = RawIndexer::new(stop_words); @@ -254,6 +249,13 @@ pub fn apply_addition<'a, 'b>( index.main.merge_external_docids(writer, &new_external_docids)?; index.main.merge_internal_docids(writer, &new_internal_docids)?; + // recompute all facet attributes after document update. + if let Some(attributes_for_facetting) = index.main.attributes_for_faceting(writer)? { + let docids = index.main.internal_docids(writer)?; + let facet_map = facets::facet_map_from_docids(writer, index, &docids, attributes_for_facetting.as_ref())?; + index.facets.add(writer, facet_map)?; + } + Ok(()) } @@ -344,6 +346,13 @@ pub fn reindex_all_documents(writer: &mut heed::RwTxn, index: &store::Ind index.main.put_schema(writer, &schema)?; + // recompute all facet attributes after document update. + if let Some(attributes_for_facetting) = index.main.attributes_for_faceting(writer)? { + let docids = index.main.internal_docids(writer)?; + let facet_map = facets::facet_map_from_docids(writer, index, &docids, attributes_for_facetting.as_ref())?; + index.facets.add(writer, facet_map)?; + } + Ok(()) } diff --git a/meilisearch-http/tests/search.rs b/meilisearch-http/tests/search.rs index 0ced0568f..3e78bad5b 100644 --- a/meilisearch-http/tests/search.rs +++ b/meilisearch-http/tests/search.rs @@ -1669,3 +1669,66 @@ async fn well_formated_error_with_bad_request_params() { assert!(response.get("errorType").is_some()); assert!(response.get("errorLink").is_some()); } + + +#[actix_rt::test] +async fn update_documents_with_facet_distribution() { + let mut server = common::Server::with_uid("test"); + let body = json!({ + "uid": "test", + "primaryKey": "id", + }); + + server.create_index(body).await; + let settings = json!({ + "attributesForFaceting": ["genre"], + "displayedAttributes": ["genre"], + "searchableAttributes": ["genre"] + }); + server.update_all_settings(settings).await; + let update1 = json!([ + { + "id": "1", + "type": "album", + "title": "Nevermind", + "genre": ["grunge", "alternative"] + }, + { + "id": "2", + "type": "album", + "title": "Mellon Collie and the Infinite Sadness", + "genre": ["alternative", "rock"] + }, + { + "id": "3", + "type": "album", + "title": "The Queen Is Dead", + "genre": ["indie", "rock"] + } + ]); + server.add_or_update_multiple_documents(update1).await; + let search = json!({ + "q": "album", + "facetsDistribution": ["genre"] + }); + let (response1, _) = server.search_post(search.clone()).await; + let expected_facet_distribution = json!({ + "genre": { + "grunge": 1, + "alternative": 2, + "rock": 2, + "indie": 1 + } + }); + assert_json_eq!(expected_facet_distribution.clone(), response1["facetsDistribution"].clone()); + + let update2 = json!([ + { + "id": "3", + "title": "The Queen Is Very Dead" + } + ]); + server.add_or_update_multiple_documents(update2).await; + let (response2, _) = server.search_post(search).await; + assert_json_eq!(expected_facet_distribution, response2["facetsDistribution"].clone()); +}