diff --git a/crates/meili-snap/src/lib.rs b/crates/meili-snap/src/lib.rs index 1641a6335..efe57f8df 100644 --- a/crates/meili-snap/src/lib.rs +++ b/crates/meili-snap/src/lib.rs @@ -43,23 +43,28 @@ pub fn default_snapshot_settings_for_test<'a>( } } - settings.add_dynamic_redaction(".message", uuid_in_message_redaction); - settings.add_dynamic_redaction(".error.message", uuid_in_message_redaction); - settings.add_dynamic_redaction(".indexUid", |content, _content_path| match &content { - Content::String(s) => match uuid::Uuid::parse_str(s) { - Ok(_) => Content::String("[uuid]".to_owned()), - Err(_) => content, - }, - _ => content, - }); - - settings.add_dynamic_redaction(".error.message", |content, _content_path| match &content { - Content::String(s) => { - let uuid_replaced = UUID_IN_MESSAGE_RE.replace_all(s, "$before[uuid]$after"); - Content::String(uuid_replaced.to_string()) + fn uuid_in_json_key_redaction(content: Content, _content_path: ContentPath) -> Content { + match content { + Content::Map(map) => { + let new_map = map + .iter() + .map(|(key, value)| match key { + Content::String(s) => { + let uuid_replaced = UUID_IN_MESSAGE_RE.replace_all(s, "[uuid]"); + (Content::String(uuid_replaced.to_string()), value.clone()) + } + _ => (key.clone(), value.clone()), + }) + .collect(); + Content::Map(new_map) + } + _ => content, } - _ => content, - }); + } + + settings.add_dynamic_redaction(".**.message", uuid_in_message_redaction); + settings.add_dynamic_redaction(".**.indexUid", uuid_in_message_redaction); + settings.add_dynamic_redaction(".**.facetsByIndex", uuid_in_json_key_redaction); let test_name = test_name.strip_suffix("::{{closure}}").unwrap_or(test_name); let test_name = test_name.rsplit("::").next().unwrap().to_owned(); diff --git a/crates/meilisearch/tests/common/mod.rs b/crates/meilisearch/tests/common/mod.rs index 373f89f78..1a73a7532 100644 --- a/crates/meilisearch/tests/common/mod.rs +++ b/crates/meilisearch/tests/common/mod.rs @@ -269,7 +269,7 @@ pub async fn shared_index_with_score_documents() -> &'static Index<'static, Shar static INDEX: OnceCell> = OnceCell::const_new(); INDEX.get_or_init(|| async { let server = Server::new_shared(); - let index = server._index("SCORE_DOCUMENTS").to_shared(); + let index = server._index("SHARED_SCORE_DOCUMENTS").to_shared(); let documents = SCORE_DOCUMENTS.clone(); let (response, _code) = index._add_documents(documents, None).await; index.wait_task(response.uid()).await.succeeded(); diff --git a/crates/meilisearch/tests/common/server.rs b/crates/meilisearch/tests/common/server.rs index 431972983..1f5688a02 100644 --- a/crates/meilisearch/tests/common/server.rs +++ b/crates/meilisearch/tests/common/server.rs @@ -347,6 +347,16 @@ impl Server { } } + pub fn unique_index_with_prefix(&self, prefix: &str) -> Index<'_> { + let uuid = Uuid::new_v4(); + Index { + uid: format!("{prefix}-{}", uuid), + service: &self.service, + encoder: Encoder::Plain, + marker: PhantomData, + } + } + pub fn unique_index_with_encoder(&self, encoder: Encoder) -> Index<'_> { let uuid = Uuid::new_v4(); Index { uid: uuid.to_string(), service: &self.service, encoder, marker: PhantomData } diff --git a/crates/meilisearch/tests/index/create_index.rs b/crates/meilisearch/tests/index/create_index.rs index e8efd14e2..3422e8b3f 100644 --- a/crates/meilisearch/tests/index/create_index.rs +++ b/crates/meilisearch/tests/index/create_index.rs @@ -46,8 +46,10 @@ async fn create_index_with_gzip_encoded_request_and_receiving_brotli_encoded_res let server = Server::new_shared(); let app = server.init_web_app().await; + let index = server.unique_index_with_prefix("test"); + let body = serde_json::to_string(&json!({ - "uid": "test", + "uid": index.uid.clone(), "primaryKey": None::<&str>, })) .unwrap(); @@ -68,7 +70,7 @@ async fn create_index_with_gzip_encoded_request_and_receiving_brotli_encoded_res let parsed_response = serde_json::from_slice::(decoded.into().as_ref()).expect("Expecting valid json"); - assert_eq!(parsed_response["indexUid"], "test"); + assert_eq!(parsed_response["indexUid"], index.uid); } #[actix_rt::test] diff --git a/crates/meilisearch/tests/search/multi/mod.rs b/crates/meilisearch/tests/search/multi/mod.rs index 8a83fd3c0..cf98baa10 100644 --- a/crates/meilisearch/tests/search/multi/mod.rs +++ b/crates/meilisearch/tests/search/multi/mod.rs @@ -1,15 +1,82 @@ use meili_snap::{json_string, snapshot}; +use tokio::sync::OnceCell; use super::{DOCUMENTS, FRUITS_DOCUMENTS, NESTED_DOCUMENTS}; -use crate::common::Server; +use crate::common::index::Index; +use crate::common::{ + shared_index_with_documents, shared_index_with_nested_documents, + shared_index_with_score_documents, Server, Shared, +}; use crate::json; use crate::search::{SCORE_DOCUMENTS, VECTOR_DOCUMENTS}; mod proxy; +pub async fn shared_movies_index() -> &'static Index<'static, Shared> { + static INDEX: OnceCell> = OnceCell::const_new(); + INDEX + .get_or_init(|| async { + let server = Server::new_shared(); + let movies_index = server.unique_index_with_prefix("movies"); + + let documents = DOCUMENTS.clone(); + let (response, _code) = movies_index.add_documents(documents, None).await; + movies_index.wait_task(response.uid()).await.succeeded(); + + let (value, _) = movies_index + .update_settings(json!({ + "sortableAttributes": ["title"], + "filterableAttributes": ["title", "color"], + "rankingRules": [ + "sort", + "words", + "typo", + "proximity", + "attribute", + "exactness" + ] + })) + .await; + movies_index.wait_task(value.uid()).await.succeeded(); + movies_index.to_shared() + }) + .await +} + +pub async fn shared_batman_index() -> &'static Index<'static, Shared> { + static INDEX: OnceCell> = OnceCell::const_new(); + INDEX + .get_or_init(|| async { + let server = Server::new_shared(); + let batman_index = server.unique_index_with_prefix("batman"); + + let documents = SCORE_DOCUMENTS.clone(); + let (response, _code) = batman_index.add_documents(documents, None).await; + batman_index.wait_task(response.uid()).await.succeeded(); + + let (value, _) = batman_index + .update_settings(json!({ + "sortableAttributes": ["id", "title"], + "filterableAttributes": ["title"], + "rankingRules": [ + "sort", + "words", + "typo", + "proximity", + "attribute", + "exactness" + ] + })) + .await; + batman_index.wait_task(value.uid()).await.succeeded(); + batman_index.to_shared() + }) + .await +} + #[actix_rt::test] async fn search_empty_list() { - let server = Server::new().await; + let server = Server::new_shared(); let (response, code) = server.multi_search(json!({"queries": []})).await; snapshot!(code, @"200 OK"); @@ -22,14 +89,14 @@ async fn search_empty_list() { #[actix_rt::test] async fn federation_empty_list() { - let server = Server::new().await; + let server = Server::new_shared(); let (response, code) = server.multi_search(json!({"federation": {}, "queries": []})).await; snapshot!(code, @"200 OK"); - snapshot!(json_string!(response, {".processingTimeMs" => "[time]"}), @r###" + snapshot!(response, @r###" { "hits": [], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 0 @@ -39,7 +106,7 @@ async fn federation_empty_list() { #[actix_rt::test] async fn search_json_object() { - let server = Server::new().await; + let server = Server::new_shared(); let (response, code) = server.multi_search(json!({})).await; snapshot!(code, @"400 Bad Request"); @@ -55,7 +122,7 @@ async fn search_json_object() { #[actix_rt::test] async fn federation_no_queries() { - let server = Server::new().await; + let server = Server::new_shared(); let (response, code) = server.multi_search(json!({"federation": {}})).await; snapshot!(code, @"400 Bad Request"); @@ -71,7 +138,7 @@ async fn federation_no_queries() { #[actix_rt::test] async fn search_json_array() { - let server = Server::new().await; + let server = Server::new_shared(); let (response, code) = server.multi_search(json!([])).await; snapshot!(code, @"400 Bad Request"); @@ -87,24 +154,20 @@ async fn search_json_array() { #[actix_rt::test] async fn simple_search_single_index() { - let server = Server::new().await; - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; let (response, code) = server .multi_search(json!({"queries": [ - {"indexUid": "test", "q": "glass"}, - {"indexUid": "test", "q": "captain"}, + {"indexUid": index.uid, "q": "glass"}, + {"indexUid": index.uid, "q": "captain"}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response["results"], { "[].processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response["results"], { ".**.processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" [ { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "hits": [ { "title": "Gläss", @@ -116,13 +179,13 @@ async fn simple_search_single_index() { } ], "query": "glass", - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 1 }, { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "hits": [ { "title": "Captain Marvel", @@ -134,7 +197,7 @@ async fn simple_search_single_index() { } ], "query": "captain", - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 1 @@ -145,20 +208,16 @@ async fn simple_search_single_index() { #[actix_rt::test] async fn federation_single_search_single_index() { - let server = Server::new().await; - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "test", "q": "glass"}, + {"indexUid" : index.uid, "q": "glass"}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { @@ -169,13 +228,13 @@ async fn federation_single_search_single_index() { "red" ], "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 0, "weightedRankingScore": 1.0 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 1 @@ -185,30 +244,26 @@ async fn federation_single_search_single_index() { #[actix_rt::test] async fn federation_multiple_search_single_index() { - let server = Server::new().await; - let index = server.index("test"); - - let documents = SCORE_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_score_documents().await; let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid": "test", "q": "the bat"}, - {"indexUid": "test", "q": "badman returns"}, - {"indexUid" : "test", "q": "batman"}, - {"indexUid": "test", "q": "batman returns"}, + {"indexUid": index.uid, "q": "the bat"}, + {"indexUid": index.uid, "q": "badman returns"}, + {"indexUid" : index.uid, "q": "batman"}, + {"indexUid": index.uid, "q": "batman returns"}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { "title": "Batman", "id": "D", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -217,7 +272,7 @@ async fn federation_multiple_search_single_index() { "title": "Batman Returns", "id": "C", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 3, "weightedRankingScore": 1.0 } @@ -226,7 +281,7 @@ async fn federation_multiple_search_single_index() { "title": "Batman the dark knight returns: Part 1", "id": "A", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 2, "weightedRankingScore": 0.9848484848484848 } @@ -235,7 +290,7 @@ async fn federation_multiple_search_single_index() { "title": "Batman the dark knight returns: Part 2", "id": "B", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 2, "weightedRankingScore": 0.9848484848484848 } @@ -244,13 +299,13 @@ async fn federation_multiple_search_single_index() { "title": "Badman", "id": "E", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 0.5 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 5 @@ -260,21 +315,17 @@ async fn federation_multiple_search_single_index() { #[actix_rt::test] async fn federation_two_search_single_index() { - let server = Server::new().await; - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "test", "q": "glass"}, - {"indexUid": "test", "q": "captain"}, + {"indexUid" : index.uid, "q": "glass"}, + {"indexUid": index.uid, "q": "captain"}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { @@ -285,7 +336,7 @@ async fn federation_two_search_single_index() { "red" ], "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -298,13 +349,13 @@ async fn federation_two_search_single_index() { "blue" ], "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 0.9848484848484848 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 2 @@ -314,12 +365,7 @@ async fn federation_two_search_single_index() { #[actix_rt::test] async fn simple_search_missing_index_uid() { - let server = Server::new().await; - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); let (response, code) = server .multi_search(json!({"queries": [ @@ -327,7 +373,7 @@ async fn simple_search_missing_index_uid() { ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, @r###" + snapshot!(response, @r###" { "message": "Missing field `indexUid` inside `.queries[0]`", "code": "missing_index_uid", @@ -339,12 +385,7 @@ async fn simple_search_missing_index_uid() { #[actix_rt::test] async fn federation_simple_search_missing_index_uid() { - let server = Server::new().await; - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ @@ -352,7 +393,7 @@ async fn federation_simple_search_missing_index_uid() { ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, @r###" + snapshot!(response, @r###" { "message": "Missing field `indexUid` inside `.queries[0]`", "code": "missing_index_uid", @@ -364,12 +405,7 @@ async fn federation_simple_search_missing_index_uid() { #[actix_rt::test] async fn simple_search_illegal_index_uid() { - let server = Server::new().await; - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); let (response, code) = server .multi_search(json!({"queries": [ @@ -377,7 +413,7 @@ async fn simple_search_illegal_index_uid() { ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, @r###" + snapshot!(response, @r###" { "message": "Invalid value at `.queries[0].indexUid`: `hé` is not a valid index uid. Index uid can be an integer or a string containing only alphanumeric characters, hyphens (-) and underscores (_), and can not be more than 512 bytes.", "code": "invalid_index_uid", @@ -389,12 +425,7 @@ async fn simple_search_illegal_index_uid() { #[actix_rt::test] async fn federation_search_illegal_index_uid() { - let server = Server::new().await; - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ @@ -402,7 +433,7 @@ async fn federation_search_illegal_index_uid() { ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, @r###" + snapshot!(response, @r###" { "message": "Invalid value at `.queries[0].indexUid`: `hé` is not a valid index uid. Index uid can be an integer or a string containing only alphanumeric characters, hyphens (-) and underscores (_), and can not be more than 512 bytes.", "code": "invalid_index_uid", @@ -414,29 +445,22 @@ async fn federation_search_illegal_index_uid() { #[actix_rt::test] async fn simple_search_two_indexes() { - let server = Server::new().await; - let index = server.index("test"); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("nested"); - let documents = NESTED_DOCUMENTS.clone(); - let (add_task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(add_task.uid()).await.succeeded(); + let nested_index = shared_index_with_nested_documents().await; let (response, code) = server .multi_search(json!({"queries": [ - {"indexUid" : "test", "q": "glass"}, - {"indexUid": "nested", "q": "pésti"}, + {"indexUid" : index.uid, "q": "glass"}, + {"indexUid": nested_index.uid, "q": "pésti"}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response["results"], { "[].processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response["results"], { ".**.processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" [ { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "hits": [ { "title": "Gläss", @@ -448,13 +472,13 @@ async fn simple_search_two_indexes() { } ], "query": "glass", - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 1 }, { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "hits": [ { "id": 852, @@ -489,7 +513,7 @@ async fn simple_search_two_indexes() { } ], "query": "pésti", - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 2 @@ -500,26 +524,18 @@ async fn simple_search_two_indexes() { #[actix_rt::test] async fn federation_two_search_two_indexes() { - let server = Server::new().await; - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("nested"); - let documents = NESTED_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; + let nested_index = shared_index_with_nested_documents().await; let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "test", "q": "glass"}, - {"indexUid": "nested", "q": "pésti"}, + {"indexUid" : index.uid, "q": "glass"}, + {"indexUid": nested_index.uid, "q": "pésti"}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { @@ -530,7 +546,7 @@ async fn federation_two_search_two_indexes() { "red" ], "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -551,7 +567,7 @@ async fn federation_two_search_two_indexes() { ], "cattos": "pésti", "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -571,13 +587,13 @@ async fn federation_two_search_two_indexes() { "pestiféré" ], "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 0.7803030303030303 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 3 @@ -587,40 +603,30 @@ async fn federation_two_search_two_indexes() { #[actix_rt::test] async fn federation_multiple_search_multiple_indexes() { - let server = Server::new().await; - let index = server.index("test"); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let nested_index = shared_index_with_nested_documents().await; - let index = server.index("nested"); - let documents = NESTED_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("score"); - let documents = SCORE_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let score_index = shared_index_with_score_documents().await; let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "test", "q": "glass"}, - {"indexUid" : "test", "q": "captain"}, - {"indexUid": "nested", "q": "pésti"}, - {"indexUid" : "test", "q": "Escape"}, - {"indexUid": "nested", "q": "jean"}, - {"indexUid": "score", "q": "jean"}, - {"indexUid": "test", "q": "the bat"}, - {"indexUid": "score", "q": "the bat"}, - {"indexUid": "score", "q": "badman returns"}, - {"indexUid" : "score", "q": "batman"}, - {"indexUid": "score", "q": "batman returns"}, + {"indexUid" : index.uid, "q": "glass"}, + {"indexUid" : index.uid, "q": "captain"}, + {"indexUid": nested_index.uid, "q": "pésti"}, + {"indexUid" : index.uid, "q": "Escape"}, + {"indexUid": nested_index.uid, "q": "jean"}, + {"indexUid": score_index.uid, "q": "jean"}, + {"indexUid": index.uid, "q": "the bat"}, + {"indexUid": score_index.uid, "q": "the bat"}, + {"indexUid": score_index.uid, "q": "badman returns"}, + {"indexUid" : score_index.uid, "q": "batman"}, + {"indexUid": score_index.uid, "q": "batman returns"}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { @@ -631,7 +637,7 @@ async fn federation_multiple_search_multiple_indexes() { "red" ], "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -652,7 +658,7 @@ async fn federation_multiple_search_multiple_indexes() { ], "cattos": "pésti", "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -661,7 +667,7 @@ async fn federation_multiple_search_multiple_indexes() { "title": "Batman", "id": "D", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 1.0 } @@ -670,7 +676,7 @@ async fn federation_multiple_search_multiple_indexes() { "title": "Batman Returns", "id": "C", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 10, "weightedRankingScore": 1.0 } @@ -683,7 +689,7 @@ async fn federation_multiple_search_multiple_indexes() { "blue" ], "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 0.9848484848484848 } @@ -696,7 +702,7 @@ async fn federation_multiple_search_multiple_indexes() { "red" ], "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 3, "weightedRankingScore": 0.9848484848484848 } @@ -720,7 +726,7 @@ async fn federation_multiple_search_multiple_indexes() { "gomez" ], "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 4, "weightedRankingScore": 0.9848484848484848 } @@ -729,7 +735,7 @@ async fn federation_multiple_search_multiple_indexes() { "title": "Batman the dark knight returns: Part 1", "id": "A", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 0.9848484848484848 } @@ -738,7 +744,7 @@ async fn federation_multiple_search_multiple_indexes() { "title": "Batman the dark knight returns: Part 2", "id": "B", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 0.9848484848484848 } @@ -758,7 +764,7 @@ async fn federation_multiple_search_multiple_indexes() { "pestiféré" ], "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 2, "weightedRankingScore": 0.7803030303030303 } @@ -767,7 +773,7 @@ async fn federation_multiple_search_multiple_indexes() { "title": "Badman", "id": "E", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 8, "weightedRankingScore": 0.5 } @@ -780,13 +786,13 @@ async fn federation_multiple_search_multiple_indexes() { "red" ], "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 6, "weightedRankingScore": 0.4166666666666667 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 12 @@ -796,16 +802,12 @@ async fn federation_multiple_search_multiple_indexes() { #[actix_rt::test] async fn search_one_index_doesnt_exist() { - let server = Server::new().await; - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; let (response, code) = server .multi_search(json!({"queries": [ - {"indexUid" : "test", "q": "glass"}, + {"indexUid" : index.uid, "q": "glass"}, {"indexUid": "nested", "q": "pésti"}, ]})) .await; @@ -822,16 +824,12 @@ async fn search_one_index_doesnt_exist() { #[actix_rt::test] async fn federation_one_index_doesnt_exist() { - let server = Server::new().await; - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "test", "q": "glass"}, + {"indexUid" : index.uid, "q": "glass"}, {"indexUid": "nested", "q": "pésti"}, ]})) .await; @@ -848,7 +846,7 @@ async fn federation_one_index_doesnt_exist() { #[actix_rt::test] async fn search_multiple_indexes_dont_exist() { - let server = Server::new().await; + let server = Server::new_shared(); let (response, code) = server .multi_search(json!({"queries": [ @@ -869,12 +867,15 @@ async fn search_multiple_indexes_dont_exist() { #[actix_rt::test] async fn federation_multiple_indexes_dont_exist() { - let server = Server::new().await; + let server = Server::new_shared(); + + let index_1 = server.unique_index_with_prefix("index_1"); + let index_2 = server.unique_index_with_prefix("index_2"); let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "test", "q": "glass"}, - {"indexUid": "nested", "q": "pésti"}, + {"indexUid" : index_1.uid, "q": "glass"}, + {"indexUid": index_2.uid, "q": "pésti"}, ]})) .await; snapshot!(code, @"400 Bad Request"); @@ -882,7 +883,7 @@ async fn federation_multiple_indexes_dont_exist() { // the query index is the lowest index with that index snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[1]`: Index `nested` not found.", + "message": "Inside `.queries[0]`: Index `index_1-[uuid]` not found.", "code": "index_not_found", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#index_not_found" @@ -892,29 +893,20 @@ async fn federation_multiple_indexes_dont_exist() { #[actix_rt::test] async fn search_one_query_error() { - let server = Server::new().await; - - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("nested"); - let documents = NESTED_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; + let nested_index = shared_index_with_nested_documents().await; let (response, code) = server .multi_search(json!({"queries": [ - {"indexUid" : "test", "q": "glass", "facets": ["title"]}, - {"indexUid": "nested", "q": "pésti"}, + {"indexUid" : index.uid, "q": "glass", "facets": ["color"]}, + {"indexUid": nested_index.uid, "q": "pésti"}, ]})) .await; snapshot!(code, @"400 Bad Request"); snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[0]`: Invalid facet distribution: Attribute `title` is not filterable. This index does not have configured filterable attributes.", + "message": "Inside `.queries[0]`: Invalid facet distribution: Attribute `color` is not filterable. Available filterable attributes patterns are: `id, title`.", "code": "invalid_search_facets", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_search_facets" @@ -924,29 +916,21 @@ async fn search_one_query_error() { #[actix_rt::test] async fn federation_one_query_error() { - let server = Server::new().await; + let server = Server::new_shared(); + let index = shared_index_with_documents().await; - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("nested"); - let documents = NESTED_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let nested_index = shared_index_with_nested_documents().await; let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "test", "q": "glass"}, - {"indexUid": "nested", "q": "pésti", "filter": ["title = toto"]}, + {"indexUid" : index.uid, "q": "glass"}, + {"indexUid": nested_index.uid, "q": "pésti", "filter": ["title = toto"]}, ]})) .await; snapshot!(code, @"400 Bad Request"); snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[1]`: Index `nested`: Attribute `title` is not filterable. This index does not have configured filterable attributes.\n1:6 title = toto", + "message": "Inside `.queries[1]`: Index `SHARED_NESTED_DOCUMENTS`: Attribute `title` is not filterable. Available filterable attribute patterns are: `cattos`, `doggos`, `father`.\n1:6 title = toto", "code": "invalid_search_filter", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_search_filter" @@ -956,29 +940,20 @@ async fn federation_one_query_error() { #[actix_rt::test] async fn federation_one_query_sort_error() { - let server = Server::new().await; - - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("nested"); - let documents = NESTED_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; + let nested_index = shared_index_with_nested_documents().await; let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "test", "q": "glass"}, - {"indexUid": "nested", "q": "pésti", "sort": ["doggos:desc"]}, + {"indexUid" : index.uid, "q": "glass"}, + {"indexUid": nested_index.uid, "q": "pésti", "sort": ["mother:desc"]}, ]})) .await; snapshot!(code, @"400 Bad Request"); snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[1]`: Index `nested`: Attribute `doggos` is not sortable. This index does not have configured sortable attributes.", + "message": "Inside `.queries[1]`: Index `SHARED_NESTED_DOCUMENTS`: Attribute `mother` is not sortable. Available sortable attributes are: `doggos`.", "code": "invalid_search_sort", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_search_sort" @@ -988,29 +963,20 @@ async fn federation_one_query_sort_error() { #[actix_rt::test] async fn search_multiple_query_errors() { - let server = Server::new().await; - - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("nested"); - let documents = NESTED_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; + let nested_index = shared_index_with_nested_documents().await; let (response, code) = server .multi_search(json!({"queries": [ - {"indexUid" : "test", "q": "glass", "facets": ["title"]}, - {"indexUid": "nested", "q": "pésti", "facets": ["doggos"]}, + {"indexUid" : index.uid, "q": "glass", "facets": ["color"]}, + {"indexUid": nested_index.uid, "q": "pésti", "facets": ["doggos"]}, ]})) .await; snapshot!(code, @"400 Bad Request"); snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[0]`: Invalid facet distribution: Attribute `title` is not filterable. This index does not have configured filterable attributes.", + "message": "Inside `.queries[0]`: Invalid facet distribution: Attribute `color` is not filterable. Available filterable attributes patterns are: `id, title`.", "code": "invalid_search_facets", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_search_facets" @@ -1020,29 +986,20 @@ async fn search_multiple_query_errors() { #[actix_rt::test] async fn federation_multiple_query_errors() { - let server = Server::new().await; - - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("nested"); - let documents = NESTED_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; + let nested_index = shared_index_with_nested_documents().await; let (response, code) = server .multi_search(json!({"queries": [ - {"indexUid" : "test", "q": "glass", "filter": ["title = toto"]}, - {"indexUid": "nested", "q": "pésti", "filter": ["doggos IN [intel, kefir]"]}, + {"indexUid" : index.uid, "q": "glass", "filter": ["color = toto"]}, + {"indexUid": nested_index.uid, "q": "pésti", "filter": ["mother IN [intel, kefir]"]}, ]})) .await; snapshot!(code, @"400 Bad Request"); snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[0]`: Index `test`: Attribute `title` is not filterable. This index does not have configured filterable attributes.\n1:6 title = toto", + "message": "Inside `.queries[0]`: Index `SHARED_DOCUMENTS`: Attribute `color` is not filterable. Available filterable attribute patterns are: `id`, `title`.\n1:6 color = toto", "code": "invalid_search_filter", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_search_filter" @@ -1052,29 +1009,20 @@ async fn federation_multiple_query_errors() { #[actix_rt::test] async fn federation_multiple_query_sort_errors() { - let server = Server::new().await; - - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("nested"); - let documents = NESTED_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; + let nested_index = shared_index_with_nested_documents().await; let (response, code) = server .multi_search(json!({"queries": [ - {"indexUid" : "test", "q": "glass", "sort": ["title:desc"]}, - {"indexUid": "nested", "q": "pésti", "sort": ["doggos:desc"]}, + {"indexUid" : index.uid, "q": "glass", "sort": ["color:desc"]}, + {"indexUid": nested_index.uid, "q": "pésti", "sort": ["doggos:desc"]}, ]})) .await; snapshot!(code, @"400 Bad Request"); snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[0]`: Index `test`: Attribute `title` is not sortable. This index does not have configured sortable attributes.", + "message": "Inside `.queries[0]`: Index `SHARED_DOCUMENTS`: Attribute `color` is not sortable. Available sortable attributes are: `id, title`.", "code": "invalid_search_sort", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_search_sort" @@ -1084,30 +1032,21 @@ async fn federation_multiple_query_sort_errors() { #[actix_rt::test] async fn federation_multiple_query_errors_interleaved() { - let server = Server::new().await; - - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("nested"); - let documents = NESTED_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; + let nested_index = shared_index_with_nested_documents().await; let (response, code) = server .multi_search(json!({"queries": [ - {"indexUid" : "test", "q": "glass"}, - {"indexUid": "nested", "q": "pésti", "filter": ["doggos IN [intel, kefir]"]}, - {"indexUid" : "test", "q": "glass", "filter": ["title = toto"]}, + {"indexUid" : index.uid, "q": "glass"}, + {"indexUid": nested_index.uid, "q": "pésti", "filter": ["mother IN [intel, kefir]"]}, + {"indexUid" : index.uid, "q": "glass", "filter": ["title = toto"]}, ]})) .await; snapshot!(code, @"400 Bad Request"); snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[1]`: Index `nested`: Attribute `doggos` is not filterable. This index does not have configured filterable attributes.\n1:7 doggos IN [intel, kefir]", + "message": "Inside `.queries[1]`: Index `SHARED_NESTED_DOCUMENTS`: Attribute `mother` is not filterable. Available filterable attribute patterns are: `cattos`, `doggos`, `father`.\n1:7 mother IN [intel, kefir]", "code": "invalid_search_filter", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_search_filter" @@ -1117,30 +1056,21 @@ async fn federation_multiple_query_errors_interleaved() { #[actix_rt::test] async fn federation_multiple_query_sort_errors_interleaved() { - let server = Server::new().await; - - let index = server.index("test"); - - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("nested"); - let documents = NESTED_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; + let nested_index = shared_index_with_nested_documents().await; let (response, code) = server .multi_search(json!({"queries": [ - {"indexUid" : "test", "q": "glass"}, - {"indexUid": "nested", "q": "pésti", "sort": ["doggos:desc"]}, - {"indexUid" : "test", "q": "glass", "sort": ["title:desc"]}, + {"indexUid" : index.uid, "q": "glass"}, + {"indexUid": nested_index.uid, "q": "pésti", "sort": ["mother:desc"]}, + {"indexUid" : index.uid, "q": "glass", "sort": ["title:desc"]}, ]})) .await; snapshot!(code, @"400 Bad Request"); snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[1]`: Index `nested`: Attribute `doggos` is not sortable. This index does not have configured sortable attributes.", + "message": "Inside `.queries[1]`: Index `SHARED_NESTED_DOCUMENTS`: Attribute `mother` is not sortable. Available sortable attributes are: `doggos`.", "code": "invalid_search_sort", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_search_sort" @@ -1150,9 +1080,8 @@ async fn federation_multiple_query_sort_errors_interleaved() { #[actix_rt::test] async fn federation_filter() { - let server = Server::new().await; - - let index = server.index("fruits"); + let server = Server::new_shared(); + let index = server.unique_index(); let documents = FRUITS_DOCUMENTS.clone(); let (value, _) = index.add_documents(documents, None).await; @@ -1167,12 +1096,12 @@ async fn federation_filter() { let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "fruits", "q": "apple red", "filter": "BOOST = true", "showRankingScore": true, "federationOptions": {"weight": 3.0}}, - {"indexUid": "fruits", "q": "apple red", "showRankingScore": true}, + {"indexUid" : index.uid, "q": "apple red", "filter": "BOOST = true", "showRankingScore": true, "federationOptions": {"weight": 3.0}}, + {"indexUid": index.uid, "q": "apple red", "showRankingScore": true}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(response, @r###" { "hits": [ { @@ -1180,7 +1109,7 @@ async fn federation_filter() { "id": "red-delicious-boosted", "BOOST": true, "_federation": { - "indexUid": "fruits", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 2.7281746031746033 }, @@ -1191,7 +1120,7 @@ async fn federation_filter() { "id": "green-apple-boosted", "BOOST": true, "_federation": { - "indexUid": "fruits", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.318181818181818 }, @@ -1201,14 +1130,14 @@ async fn federation_filter() { "name": "Red apple gala", "id": "red-apple-gala", "_federation": { - "indexUid": "fruits", + "indexUid": "[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.953042328042328 }, "_rankingScore": 0.953042328042328 } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 3 @@ -1218,9 +1147,8 @@ async fn federation_filter() { #[actix_rt::test] async fn federation_sort_same_indexes_same_criterion_same_direction() { - let server = Server::new().await; - - let index = server.index("nested"); + let server = Server::new_shared(); + let index = server.unique_index(); let documents = NESTED_DOCUMENTS.clone(); let (value, _) = index.add_documents(documents, None).await; @@ -1241,15 +1169,15 @@ async fn federation_sort_same_indexes_same_criterion_same_direction() { .await; index.wait_task(value.uid()).await.succeeded(); - // two identical placeholder search should have all results from first query + // two identical placeholder searches should have all results from the first query let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "nested", "q": "", "sort": ["mother:asc"], "showRankingScore": true }, - {"indexUid" : "nested", "q": "", "sort": ["mother:asc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "", "sort": ["mother:asc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "", "sort": ["mother:asc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { @@ -1268,7 +1196,7 @@ async fn federation_sort_same_indexes_same_criterion_same_direction() { ], "cattos": "pésti", "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -1282,7 +1210,7 @@ async fn federation_sort_same_indexes_same_criterion_same_direction() { "enigma" ], "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -1303,7 +1231,7 @@ async fn federation_sort_same_indexes_same_criterion_same_direction() { "pestiféré" ], "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -1328,14 +1256,14 @@ async fn federation_sort_same_indexes_same_criterion_same_direction() { "gomez" ], "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, "_rankingScore": 1.0 } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 4 @@ -1345,12 +1273,12 @@ async fn federation_sort_same_indexes_same_criterion_same_direction() { // mix and match query let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "nested", "q": "pésti", "sort": ["mother:asc"], "showRankingScore": true }, - {"indexUid" : "nested", "q": "jean", "sort": ["mother:asc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "pésti", "sort": ["mother:asc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "jean", "sort": ["mother:asc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { @@ -1369,7 +1297,7 @@ async fn federation_sort_same_indexes_same_criterion_same_direction() { ], "cattos": "pésti", "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -1390,7 +1318,7 @@ async fn federation_sort_same_indexes_same_criterion_same_direction() { "pestiféré" ], "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.7803030303030303 }, @@ -1415,14 +1343,14 @@ async fn federation_sort_same_indexes_same_criterion_same_direction() { "gomez" ], "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.9848484848484848 }, "_rankingScore": 0.9848484848484848 } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 3 @@ -1432,9 +1360,8 @@ async fn federation_sort_same_indexes_same_criterion_same_direction() { #[actix_rt::test] async fn federation_sort_same_indexes_same_criterion_opposite_direction() { - let server = Server::new().await; - - let index = server.index("nested"); + let server = Server::new_shared(); + let index = server.unique_index(); let documents = NESTED_DOCUMENTS.clone(); let (value, _) = index.add_documents(documents, None).await; @@ -1455,17 +1382,17 @@ async fn federation_sort_same_indexes_same_criterion_opposite_direction() { .await; index.wait_task(value.uid()).await.succeeded(); - // two identical placeholder search should have all results from first query + // two identical placeholder searches should have all results from the first query let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "nested", "q": "", "sort": ["mother:asc"], "showRankingScore": true }, - {"indexUid" : "nested", "q": "", "sort": ["mother:desc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "", "sort": ["mother:asc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "", "sort": ["mother:desc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[1]`: The results of queries #0 and #1 are incompatible: \n 1. `queries[0].sort[0]`, `nested.rankingRules[0]`: ascending sort rule(s) on field `mother`\n 2. `queries[1].sort[0]`, `nested.rankingRules[0]`: descending sort rule(s) on field `mother`\n - cannot compare two sort rules in opposite directions\n - note: The ranking rules of query #0 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n - note: The ranking rules of query #1 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n", + "message": "Inside `.queries[1]`: The results of queries #0 and #1 are incompatible: \n 1. `queries[0].sort[0]`, `[uuid].rankingRules[0]`: ascending sort rule(s) on field `mother`\n 2. `queries[1].sort[0]`, `[uuid].rankingRules[0]`: descending sort rule(s) on field `mother`\n - cannot compare two sort rules in opposite directions\n - note: The ranking rules of query #0 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n - note: The ranking rules of query #1 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n", "code": "invalid_multi_search_query_ranking_rules", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_query_ranking_rules" @@ -1475,14 +1402,14 @@ async fn federation_sort_same_indexes_same_criterion_opposite_direction() { // mix and match query: should be ranked by ranking score let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "nested", "q": "pésti", "sort": ["mother:asc"], "showRankingScore": true }, - {"indexUid" : "nested", "q": "jean", "sort": ["mother:desc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "pésti", "sort": ["mother:asc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "jean", "sort": ["mother:desc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[1]`: The results of queries #0 and #1 are incompatible: \n 1. `queries[0].sort[0]`, `nested.rankingRules[0]`: ascending sort rule(s) on field `mother`\n 2. `queries[1].sort[0]`, `nested.rankingRules[0]`: descending sort rule(s) on field `mother`\n - cannot compare two sort rules in opposite directions\n", + "message": "Inside `.queries[1]`: The results of queries #0 and #1 are incompatible: \n 1. `queries[0].sort[0]`, `[uuid].rankingRules[0]`: ascending sort rule(s) on field `mother`\n 2. `queries[1].sort[0]`, `[uuid].rankingRules[0]`: descending sort rule(s) on field `mother`\n - cannot compare two sort rules in opposite directions\n", "code": "invalid_multi_search_query_ranking_rules", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_query_ranking_rules" @@ -1492,9 +1419,8 @@ async fn federation_sort_same_indexes_same_criterion_opposite_direction() { #[actix_rt::test] async fn federation_sort_same_indexes_different_criterion_same_direction() { - let server = Server::new().await; - - let index = server.index("nested"); + let server = Server::new_shared(); + let index = server.unique_index(); let documents = NESTED_DOCUMENTS.clone(); let (value, _) = index.add_documents(documents, None).await; @@ -1515,15 +1441,15 @@ async fn federation_sort_same_indexes_different_criterion_same_direction() { .await; index.wait_task(value.uid()).await.succeeded(); - // return mothers and fathers ordered accross fields. + // return mothers and fathers ordered across fields. let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "nested", "q": "", "sort": ["mother:asc"], "showRankingScore": true }, - {"indexUid" : "nested", "q": "", "sort": ["father:asc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "", "sort": ["mother:asc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "", "sort": ["father:asc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { @@ -1542,7 +1468,7 @@ async fn federation_sort_same_indexes_different_criterion_same_direction() { ], "cattos": "pésti", "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -1567,7 +1493,7 @@ async fn federation_sort_same_indexes_different_criterion_same_direction() { "gomez" ], "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -1581,7 +1507,7 @@ async fn federation_sort_same_indexes_different_criterion_same_direction() { "enigma" ], "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -1602,14 +1528,14 @@ async fn federation_sort_same_indexes_different_criterion_same_direction() { "pestiféré" ], "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 }, "_rankingScore": 1.0 } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 4 @@ -1619,13 +1545,13 @@ async fn federation_sort_same_indexes_different_criterion_same_direction() { // mix and match query: will be sorted across mother and father names let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "nested", "q": "pésti", "sort": ["mother:desc"], "showRankingScore": true }, - {"indexUid" : "nested", "q": "jean-bap", "sort": ["father:desc"], "showRankingScore": true }, - {"indexUid" : "nested", "q": "jea", "sort": ["father:desc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "pésti", "sort": ["mother:desc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "jean-bap", "sort": ["father:desc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "jea", "sort": ["father:desc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { @@ -1643,7 +1569,7 @@ async fn federation_sort_same_indexes_different_criterion_same_direction() { "pestiféré" ], "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.7803030303030303 }, @@ -1665,7 +1591,7 @@ async fn federation_sort_same_indexes_different_criterion_same_direction() { ], "cattos": "pésti", "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -1690,14 +1616,14 @@ async fn federation_sort_same_indexes_different_criterion_same_direction() { "gomez" ], "_federation": { - "indexUid": "nested", + "indexUid": "[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.9991181657848324 }, "_rankingScore": 0.9991181657848324 } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 3 @@ -1707,9 +1633,8 @@ async fn federation_sort_same_indexes_different_criterion_same_direction() { #[actix_rt::test] async fn federation_sort_same_indexes_different_criterion_opposite_direction() { - let server = Server::new().await; - - let index = server.index("nested"); + let server = Server::new_shared(); + let index = server.unique_index_with_prefix("nested"); let documents = NESTED_DOCUMENTS.clone(); let (value, _) = index.add_documents(documents, None).await; @@ -1730,17 +1655,17 @@ async fn federation_sort_same_indexes_different_criterion_opposite_direction() { .await; index.wait_task(value.uid()).await.succeeded(); - // two identical placeholder search should have all results from first query + // two identical placeholder searches should have all results from the first query let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "nested", "q": "", "sort": ["mother:asc"], "showRankingScore": true }, - {"indexUid" : "nested", "q": "", "sort": ["father:desc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "", "sort": ["mother:asc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "", "sort": ["father:desc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[1]`: The results of queries #0 and #1 are incompatible: \n 1. `queries[0].sort[0]`, `nested.rankingRules[0]`: ascending sort rule(s) on field `mother`\n 2. `queries[1].sort[0]`, `nested.rankingRules[0]`: descending sort rule(s) on field `father`\n - cannot compare two sort rules in opposite directions\n - note: The ranking rules of query #0 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n - note: The ranking rules of query #1 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n", + "message": "Inside `.queries[1]`: The results of queries #0 and #1 are incompatible: \n 1. `queries[0].sort[0]`, `nested-[uuid].rankingRules[0]`: ascending sort rule(s) on field `mother`\n 2. `queries[1].sort[0]`, `nested-[uuid].rankingRules[0]`: descending sort rule(s) on field `father`\n - cannot compare two sort rules in opposite directions\n - note: The ranking rules of query #0 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n - note: The ranking rules of query #1 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n", "code": "invalid_multi_search_query_ranking_rules", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_query_ranking_rules" @@ -1750,14 +1675,14 @@ async fn federation_sort_same_indexes_different_criterion_opposite_direction() { // mix and match query: should be ranked by ranking score let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "nested", "q": "pésti", "sort": ["mother:asc"], "showRankingScore": true }, - {"indexUid" : "nested", "q": "jean", "sort": ["father:desc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "pésti", "sort": ["mother:asc"], "showRankingScore": true }, + {"indexUid" : index.uid, "q": "jean", "sort": ["father:desc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[1]`: The results of queries #0 and #1 are incompatible: \n 1. `queries[0].sort[0]`, `nested.rankingRules[0]`: ascending sort rule(s) on field `mother`\n 2. `queries[1].sort[0]`, `nested.rankingRules[0]`: descending sort rule(s) on field `father`\n - cannot compare two sort rules in opposite directions\n", + "message": "Inside `.queries[1]`: The results of queries #0 and #1 are incompatible: \n 1. `queries[0].sort[0]`, `nested-[uuid].rankingRules[0]`: ascending sort rule(s) on field `mother`\n 2. `queries[1].sort[0]`, `nested-[uuid].rankingRules[0]`: descending sort rule(s) on field `father`\n - cannot compare two sort rules in opposite directions\n", "code": "invalid_multi_search_query_ranking_rules", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_query_ranking_rules" @@ -1767,66 +1692,26 @@ async fn federation_sort_same_indexes_different_criterion_opposite_direction() { #[actix_rt::test] async fn federation_sort_different_indexes_same_criterion_same_direction() { - let server = Server::new().await; + let server = Server::new_shared(); + let movies_index = shared_movies_index().await; + let batman_index = shared_batman_index().await; - let index = server.index("movies"); - - let documents = DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); - - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["title"], - "rankingRules": [ - "sort", - "words", - "typo", - "proximity", - "attribute", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); - - let index = server.index("batman"); - - let documents = SCORE_DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); - - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["title"], - "rankingRules": [ - "sort", - "words", - "typo", - "proximity", - "attribute", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); - - // return titles ordered accross indexes + // return titles ordered across indexes let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "movies", "q": "", "sort": ["title:asc"], "showRankingScore": true }, - {"indexUid" : "batman", "q": "", "sort": ["title:asc"], "showRankingScore": true }, + {"indexUid" : movies_index.uid, "q": "", "sort": ["title:asc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "", "sort": ["title:asc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { "title": "Badman", "id": "E", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -1836,7 +1721,7 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "title": "Batman", "id": "D", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -1846,7 +1731,7 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "title": "Batman Returns", "id": "C", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -1856,7 +1741,7 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "title": "Batman the dark knight returns: Part 1", "id": "A", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -1866,7 +1751,7 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "title": "Batman the dark knight returns: Part 2", "id": "B", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -1880,7 +1765,7 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "blue" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -1894,7 +1779,7 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "red" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -1908,7 +1793,7 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "red" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -1922,7 +1807,7 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "red" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -1936,14 +1821,14 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "blue" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, "_rankingScore": 1.0 } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 10 @@ -1953,13 +1838,13 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { // mix and match query: will be sorted across indexes let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "batman", "q": "badman returns", "sort": ["title:desc"], "showRankingScore": true }, - {"indexUid" : "movies", "q": "captain", "sort": ["title:desc"], "showRankingScore": true }, - {"indexUid" : "batman", "q": "the bat", "sort": ["title:desc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "badman returns", "sort": ["title:desc"], "showRankingScore": true }, + {"indexUid" : movies_index.uid, "q": "captain", "sort": ["title:desc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "the bat", "sort": ["title:desc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { @@ -1970,7 +1855,7 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "blue" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.9848484848484848 }, @@ -1980,7 +1865,7 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "title": "Batman the dark knight returns: Part 2", "id": "B", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 2, "weightedRankingScore": 0.9528218694885362 }, @@ -1990,7 +1875,7 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "title": "Batman the dark knight returns: Part 1", "id": "A", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 2, "weightedRankingScore": 0.9528218694885362 }, @@ -2000,7 +1885,7 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "title": "Batman Returns", "id": "C", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.8317901234567902 }, @@ -2010,7 +1895,7 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "title": "Batman", "id": "D", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.23106060606060605 }, @@ -2020,14 +1905,14 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { "title": "Badman", "id": "E", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.5 }, "_rankingScore": 0.5 } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 6 @@ -2037,66 +1922,28 @@ async fn federation_sort_different_indexes_same_criterion_same_direction() { #[actix_rt::test] async fn federation_sort_different_ranking_rules() { - let server = Server::new().await; + let server = Server::new_shared(); - let index = server.index("movies"); + let movies_index = shared_movies_index().await; - let documents = DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); + let batman_index = shared_index_with_score_documents().await; - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["title"], - "rankingRules": [ - "sort", - "words", - "typo", - "proximity", - "attribute", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); - - let index = server.index("batman"); - - let documents = SCORE_DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); - - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["title"], - "rankingRules": [ - "words", - "typo", - "proximity", - "attribute", - "sort", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); - - // return titles ordered accross indexes + // return titles ordered across indexes let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "movies", "q": "", "sort": ["title:asc"], "showRankingScore": true }, - {"indexUid" : "batman", "q": "", "sort": ["title:asc"], "showRankingScore": true }, + {"indexUid" : movies_index.uid, "q": "", "sort": ["title:asc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "", "sort": ["title:asc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { "title": "Badman", "id": "E", "_federation": { - "indexUid": "batman", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -2106,7 +1953,7 @@ async fn federation_sort_different_ranking_rules() { "title": "Batman", "id": "D", "_federation": { - "indexUid": "batman", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -2116,7 +1963,7 @@ async fn federation_sort_different_ranking_rules() { "title": "Batman Returns", "id": "C", "_federation": { - "indexUid": "batman", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -2126,7 +1973,7 @@ async fn federation_sort_different_ranking_rules() { "title": "Batman the dark knight returns: Part 1", "id": "A", "_federation": { - "indexUid": "batman", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -2136,7 +1983,7 @@ async fn federation_sort_different_ranking_rules() { "title": "Batman the dark knight returns: Part 2", "id": "B", "_federation": { - "indexUid": "batman", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -2150,7 +1997,7 @@ async fn federation_sort_different_ranking_rules() { "blue" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -2164,7 +2011,7 @@ async fn federation_sort_different_ranking_rules() { "red" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -2178,7 +2025,7 @@ async fn federation_sort_different_ranking_rules() { "red" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -2192,7 +2039,7 @@ async fn federation_sort_different_ranking_rules() { "red" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -2206,14 +2053,14 @@ async fn federation_sort_different_ranking_rules() { "blue" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, "_rankingScore": 1.0 } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 10 @@ -2223,15 +2070,15 @@ async fn federation_sort_different_ranking_rules() { // mix and match query: order difficult to understand let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "batman", "q": "badman returns", "sort": ["title:desc"], "showRankingScore": true }, - {"indexUid" : "movies", "q": "captain", "sort": ["title:desc"], "showRankingScore": true }, - {"indexUid" : "batman", "q": "the bat", "sort": ["title:desc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "badman returns", "sort": ["title:desc"], "showRankingScore": true }, + {"indexUid" : movies_index.uid, "q": "captain", "sort": ["title:desc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "the bat", "sort": ["title:desc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[1]`: The results of queries #2 and #1 are incompatible: \n 1. `queries[2]`, `batman.rankingRules[0..=3]`: relevancy rule(s) words, typo, proximity, attribute\n 2. `queries[1].sort[0]`, `movies.rankingRules[0]`: descending sort rule(s) on field `title`\n - cannot compare a relevancy rule with a sort rule\n", + "message": "Inside `.queries[1]`: The results of queries #2 and #1 are incompatible: \n 1. `queries[2]`, `SHARED_SCORE_DOCUMENTS.rankingRules[0..=3]`: relevancy rule(s) words, typo, proximity, attribute\n 2. `queries[1].sort[0]`, `movies-[uuid].rankingRules[0]`: descending sort rule(s) on field `title`\n - cannot compare a relevancy rule with a sort rule\n", "code": "invalid_multi_search_query_ranking_rules", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_query_ranking_rules" @@ -2241,61 +2088,21 @@ async fn federation_sort_different_ranking_rules() { #[actix_rt::test] async fn federation_sort_different_indexes_same_criterion_opposite_direction() { - let server = Server::new().await; - - let index = server.index("movies"); - - let documents = DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); - - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["title"], - "rankingRules": [ - "sort", - "words", - "typo", - "proximity", - "attribute", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); - - let index = server.index("batman"); - - let documents = SCORE_DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); - - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["title"], - "rankingRules": [ - "sort", - "words", - "typo", - "proximity", - "attribute", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); + let server = Server::new_shared(); + let movies_index = shared_movies_index().await; + let batman_index = shared_batman_index().await; // all results from query 0 let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "movies", "q": "", "sort": ["title:asc"], "showRankingScore": true }, - {"indexUid" : "batman", "q": "", "sort": ["title:desc"], "showRankingScore": true }, + {"indexUid" : movies_index.uid, "q": "", "sort": ["title:asc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "", "sort": ["title:desc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[0]`: The results of queries #1 and #0 are incompatible: \n 1. `queries[1].sort[0]`, `batman.rankingRules[0]`: descending sort rule(s) on field `title`\n 2. `queries[0].sort[0]`, `movies.rankingRules[0]`: ascending sort rule(s) on field `title`\n - cannot compare two sort rules in opposite directions\n - note: The ranking rules of query #1 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n - note: The ranking rules of query #0 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n", + "message": "Inside `.queries[0]`: The results of queries #1 and #0 are incompatible: \n 1. `queries[1].sort[0]`, `batman-[uuid].rankingRules[0]`: descending sort rule(s) on field `title`\n 2. `queries[0].sort[0]`, `movies-[uuid].rankingRules[0]`: ascending sort rule(s) on field `title`\n - cannot compare two sort rules in opposite directions\n - note: The ranking rules of query #1 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n - note: The ranking rules of query #0 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n", "code": "invalid_multi_search_query_ranking_rules", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_query_ranking_rules" @@ -2305,15 +2112,15 @@ async fn federation_sort_different_indexes_same_criterion_opposite_direction() { // mix and match query: will be sorted by ranking score let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "batman", "q": "badman returns", "sort": ["title:asc"], "showRankingScore": true }, - {"indexUid" : "movies", "q": "captain", "sort": ["title:desc"], "showRankingScore": true }, - {"indexUid" : "batman", "q": "the bat", "sort": ["title:asc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "badman returns", "sort": ["title:asc"], "showRankingScore": true }, + {"indexUid" : movies_index.uid, "q": "captain", "sort": ["title:desc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "the bat", "sort": ["title:asc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[1]`: The results of queries #2 and #1 are incompatible: \n 1. `queries[2].sort[0]`, `batman.rankingRules[0]`: ascending sort rule(s) on field `title`\n 2. `queries[1].sort[0]`, `movies.rankingRules[0]`: descending sort rule(s) on field `title`\n - cannot compare two sort rules in opposite directions\n", + "message": "Inside `.queries[1]`: The results of queries #2 and #1 are incompatible: \n 1. `queries[2].sort[0]`, `batman-[uuid].rankingRules[0]`: ascending sort rule(s) on field `title`\n 2. `queries[1].sort[0]`, `movies-[uuid].rankingRules[0]`: descending sort rule(s) on field `title`\n - cannot compare two sort rules in opposite directions\n", "code": "invalid_multi_search_query_ranking_rules", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_query_ranking_rules" @@ -2323,66 +2130,26 @@ async fn federation_sort_different_indexes_same_criterion_opposite_direction() { #[actix_rt::test] async fn federation_sort_different_indexes_different_criterion_same_direction() { - let server = Server::new().await; + let server = Server::new_shared(); + let movies_index = shared_movies_index().await; + let batman_index = shared_batman_index().await; - let index = server.index("movies"); - - let documents = DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); - - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["title"], - "rankingRules": [ - "sort", - "words", - "typo", - "proximity", - "attribute", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); - - let index = server.index("batman"); - - let documents = SCORE_DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); - - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["id"], - "rankingRules": [ - "sort", - "words", - "typo", - "proximity", - "attribute", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); - - // return titles ordered accross indexes + // return titles ordered across indexes let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "movies", "q": "", "sort": ["title:asc"], "showRankingScore": true }, - {"indexUid" : "batman", "q": "", "sort": ["id:asc"], "showRankingScore": true }, + {"indexUid" : movies_index.uid, "q": "", "sort": ["title:asc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "", "sort": ["id:asc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { "title": "Batman the dark knight returns: Part 1", "id": "A", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -2392,7 +2159,7 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "title": "Batman the dark knight returns: Part 2", "id": "B", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -2402,7 +2169,7 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "title": "Batman Returns", "id": "C", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -2416,7 +2183,7 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "blue" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -2426,7 +2193,7 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "title": "Batman", "id": "D", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -2436,7 +2203,7 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "title": "Badman", "id": "E", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 }, @@ -2450,7 +2217,7 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "red" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -2464,7 +2231,7 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "red" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -2478,7 +2245,7 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "red" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -2492,14 +2259,14 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "blue" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 }, "_rankingScore": 1.0 } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 10 @@ -2509,20 +2276,20 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() // mix and match query: will be sorted across indexes and criterion let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "batman", "q": "badman returns", "sort": ["id:desc"], "showRankingScore": true }, - {"indexUid" : "movies", "q": "captain", "sort": ["title:desc"], "showRankingScore": true }, - {"indexUid" : "batman", "q": "the bat", "sort": ["id:desc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "badman returns", "sort": ["id:desc"], "showRankingScore": true }, + {"indexUid" : movies_index.uid, "q": "captain", "sort": ["title:desc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "the bat", "sort": ["id:desc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { "title": "Badman", "id": "E", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.5 }, @@ -2532,7 +2299,7 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "title": "Batman", "id": "D", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.23106060606060605 }, @@ -2546,7 +2313,7 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "blue" ], "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.9848484848484848 }, @@ -2556,7 +2323,7 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "title": "Batman Returns", "id": "C", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.8317901234567902 }, @@ -2566,7 +2333,7 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "title": "Batman the dark knight returns: Part 2", "id": "B", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 2, "weightedRankingScore": 0.9528218694885362 }, @@ -2576,14 +2343,14 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() "title": "Batman the dark knight returns: Part 1", "id": "A", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 2, "weightedRankingScore": 0.9528218694885362 }, "_rankingScore": 0.9528218694885362 } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 6 @@ -2593,61 +2360,21 @@ async fn federation_sort_different_indexes_different_criterion_same_direction() #[actix_rt::test] async fn federation_sort_different_indexes_different_criterion_opposite_direction() { - let server = Server::new().await; - - let index = server.index("movies"); - - let documents = DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); - - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["title"], - "rankingRules": [ - "sort", - "words", - "typo", - "proximity", - "attribute", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); - - let index = server.index("batman"); - - let documents = SCORE_DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); - - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["id"], - "rankingRules": [ - "sort", - "words", - "typo", - "proximity", - "attribute", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); + let server = Server::new_shared(); + let movies_index = shared_movies_index().await; + let batman_index = shared_batman_index().await; // all results from query 0 first let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "movies", "q": "", "sort": ["title:asc"], "showRankingScore": true }, - {"indexUid" : "batman", "q": "", "sort": ["id:desc"], "showRankingScore": true }, + {"indexUid" : movies_index.uid, "q": "", "sort": ["title:asc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "", "sort": ["id:desc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[0]`: The results of queries #1 and #0 are incompatible: \n 1. `queries[1].sort[0]`, `batman.rankingRules[0]`: descending sort rule(s) on field `id`\n 2. `queries[0].sort[0]`, `movies.rankingRules[0]`: ascending sort rule(s) on field `title`\n - cannot compare two sort rules in opposite directions\n - note: The ranking rules of query #1 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n - note: The ranking rules of query #0 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n", + "message": "Inside `.queries[0]`: The results of queries #1 and #0 are incompatible: \n 1. `queries[1].sort[0]`, `batman-[uuid].rankingRules[0]`: descending sort rule(s) on field `id`\n 2. `queries[0].sort[0]`, `movies-[uuid].rankingRules[0]`: ascending sort rule(s) on field `title`\n - cannot compare two sort rules in opposite directions\n - note: The ranking rules of query #1 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n - note: The ranking rules of query #0 were modified during canonicalization:\n 1. Removed relevancy rule `words` at position #1 in ranking rules because the query is a placeholder search (`q`: \"\")\n 2. Removed relevancy rule `typo` at position #2 in ranking rules because the query is a placeholder search (`q`: \"\")\n 3. Removed relevancy rule `proximity` at position #3 in ranking rules because the query is a placeholder search (`q`: \"\")\n 4. Removed relevancy rule `attribute` at position #4 in ranking rules because the query is a placeholder search (`q`: \"\")\n 5. Removed relevancy rule `exactness` at position #5 in ranking rules because the query is a placeholder search (`q`: \"\")\n", "code": "invalid_multi_search_query_ranking_rules", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_query_ranking_rules" @@ -2657,15 +2384,15 @@ async fn federation_sort_different_indexes_different_criterion_opposite_directio // mix and match query: more or less by ranking score let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "batman", "q": "badman returns", "sort": ["id:desc"], "showRankingScore": true }, - {"indexUid" : "movies", "q": "captain", "sort": ["title:asc"], "showRankingScore": true }, - {"indexUid" : "batman", "q": "the bat", "sort": ["id:desc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "badman returns", "sort": ["id:desc"], "showRankingScore": true }, + {"indexUid" : movies_index.uid, "q": "captain", "sort": ["title:asc"], "showRankingScore": true }, + {"indexUid" : batman_index.uid, "q": "the bat", "sort": ["id:desc"], "showRankingScore": true }, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[1]`: The results of queries #2 and #1 are incompatible: \n 1. `queries[2].sort[0]`, `batman.rankingRules[0]`: descending sort rule(s) on field `id`\n 2. `queries[1].sort[0]`, `movies.rankingRules[0]`: ascending sort rule(s) on field `title`\n - cannot compare two sort rules in opposite directions\n", + "message": "Inside `.queries[1]`: The results of queries #2 and #1 are incompatible: \n 1. `queries[2].sort[0]`, `batman-[uuid].rankingRules[0]`: descending sort rule(s) on field `id`\n 2. `queries[1].sort[0]`, `movies-[uuid].rankingRules[0]`: ascending sort rule(s) on field `title`\n - cannot compare two sort rules in opposite directions\n", "code": "invalid_multi_search_query_ranking_rules", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_query_ranking_rules" @@ -2675,46 +2402,35 @@ async fn federation_sort_different_indexes_different_criterion_opposite_directio #[actix_rt::test] async fn federation_limit_offset() { - let server = Server::new().await; - let index = server.index("test"); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; + let nested_index = shared_index_with_nested_documents().await; + let score_index = shared_index_with_score_documents().await; - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("nested"); - let documents = NESTED_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("score"); - let documents = SCORE_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); { let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "test", "q": "glass", "attributesToRetrieve": ["title"]}, - {"indexUid" : "test", "q": "captain", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "pésti", "attributesToRetrieve": ["id"]}, - {"indexUid" : "test", "q": "Escape", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "jean", "attributesToRetrieve": ["id"]}, - {"indexUid": "score", "q": "jean", "attributesToRetrieve": ["title"]}, - {"indexUid": "test", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "badman returns", "attributesToRetrieve": ["title"]}, - {"indexUid" : "score", "q": "batman", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "batman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "glass", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "captain", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "pésti", "attributesToRetrieve": ["id"]}, + {"indexUid" : index.uid, "q": "Escape", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "jean", "attributesToRetrieve": ["id"]}, + {"indexUid" : score_index.uid, "q": "jean", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "badman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman returns", "attributesToRetrieve": ["title"]}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { "title": "Gläss", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -2722,7 +2438,7 @@ async fn federation_limit_offset() { { "id": 852, "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -2730,7 +2446,7 @@ async fn federation_limit_offset() { { "title": "Batman", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 1.0 } @@ -2738,7 +2454,7 @@ async fn federation_limit_offset() { { "title": "Batman Returns", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 10, "weightedRankingScore": 1.0 } @@ -2746,7 +2462,7 @@ async fn federation_limit_offset() { { "title": "Captain Marvel", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 0.9848484848484848 } @@ -2754,7 +2470,7 @@ async fn federation_limit_offset() { { "title": "Escape Room", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 3, "weightedRankingScore": 0.9848484848484848 } @@ -2762,7 +2478,7 @@ async fn federation_limit_offset() { { "id": 951, "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 4, "weightedRankingScore": 0.9848484848484848 } @@ -2770,7 +2486,7 @@ async fn federation_limit_offset() { { "title": "Batman the dark knight returns: Part 1", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 0.9848484848484848 } @@ -2778,7 +2494,7 @@ async fn federation_limit_offset() { { "title": "Batman the dark knight returns: Part 2", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 0.9848484848484848 } @@ -2786,7 +2502,7 @@ async fn federation_limit_offset() { { "id": 654, "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 2, "weightedRankingScore": 0.7803030303030303 } @@ -2794,7 +2510,7 @@ async fn federation_limit_offset() { { "title": "Badman", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 8, "weightedRankingScore": 0.5 } @@ -2802,13 +2518,13 @@ async fn federation_limit_offset() { { "title": "How to Train Your Dragon: The Hidden World", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 6, "weightedRankingScore": 0.4166666666666667 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 12 @@ -2819,33 +2535,33 @@ async fn federation_limit_offset() { { let (response, code) = server .multi_search(json!({"federation": {"limit": 1}, "queries": [ - {"indexUid" : "test", "q": "glass", "attributesToRetrieve": ["title"]}, - {"indexUid" : "test", "q": "captain", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "pésti", "attributesToRetrieve": ["id"]}, - {"indexUid" : "test", "q": "Escape", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "jean", "attributesToRetrieve": ["id"]}, - {"indexUid": "score", "q": "jean", "attributesToRetrieve": ["title"]}, - {"indexUid": "test", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "badman returns", "attributesToRetrieve": ["title"]}, - {"indexUid" : "score", "q": "batman", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "batman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "glass", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "captain", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "pésti", "attributesToRetrieve": ["id"]}, + {"indexUid" : index.uid, "q": "Escape", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "jean", "attributesToRetrieve": ["id"]}, + {"indexUid" : score_index.uid, "q": "jean", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "badman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman returns", "attributesToRetrieve": ["title"]}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { "title": "Gläss", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 0, "weightedRankingScore": 1.0 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 1, "offset": 0, "estimatedTotalHits": 12 @@ -2856,27 +2572,27 @@ async fn federation_limit_offset() { { let (response, code) = server .multi_search(json!({"federation": {"offset": 2}, "queries": [ - {"indexUid" : "test", "q": "glass", "attributesToRetrieve": ["title"]}, - {"indexUid" : "test", "q": "captain", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "pésti", "attributesToRetrieve": ["id"]}, - {"indexUid" : "test", "q": "Escape", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "jean", "attributesToRetrieve": ["id"]}, - {"indexUid": "score", "q": "jean", "attributesToRetrieve": ["title"]}, - {"indexUid": "test", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "badman returns", "attributesToRetrieve": ["title"]}, - {"indexUid" : "score", "q": "batman", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "batman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "glass", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "captain", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "pésti", "attributesToRetrieve": ["id"]}, + {"indexUid" : index.uid, "q": "Escape", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "jean", "attributesToRetrieve": ["id"]}, + {"indexUid" : score_index.uid, "q": "jean", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "badman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman returns", "attributesToRetrieve": ["title"]}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { "title": "Batman", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 1.0 } @@ -2884,7 +2600,7 @@ async fn federation_limit_offset() { { "title": "Batman Returns", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 10, "weightedRankingScore": 1.0 } @@ -2892,7 +2608,7 @@ async fn federation_limit_offset() { { "title": "Captain Marvel", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 0.9848484848484848 } @@ -2900,7 +2616,7 @@ async fn federation_limit_offset() { { "title": "Escape Room", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 3, "weightedRankingScore": 0.9848484848484848 } @@ -2908,7 +2624,7 @@ async fn federation_limit_offset() { { "id": 951, "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 4, "weightedRankingScore": 0.9848484848484848 } @@ -2916,7 +2632,7 @@ async fn federation_limit_offset() { { "title": "Batman the dark knight returns: Part 1", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 0.9848484848484848 } @@ -2924,7 +2640,7 @@ async fn federation_limit_offset() { { "title": "Batman the dark knight returns: Part 2", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 0.9848484848484848 } @@ -2932,7 +2648,7 @@ async fn federation_limit_offset() { { "id": 654, "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 2, "weightedRankingScore": 0.7803030303030303 } @@ -2940,7 +2656,7 @@ async fn federation_limit_offset() { { "title": "Badman", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 8, "weightedRankingScore": 0.5 } @@ -2948,13 +2664,13 @@ async fn federation_limit_offset() { { "title": "How to Train Your Dragon: The Hidden World", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 6, "weightedRankingScore": 0.4166666666666667 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 2, "estimatedTotalHits": 12 @@ -2965,24 +2681,24 @@ async fn federation_limit_offset() { { let (response, code) = server .multi_search(json!({"federation": {"offset": 12}, "queries": [ - {"indexUid" : "test", "q": "glass", "attributesToRetrieve": ["title"]}, - {"indexUid" : "test", "q": "captain", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "pésti", "attributesToRetrieve": ["id"]}, - {"indexUid" : "test", "q": "Escape", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "jean", "attributesToRetrieve": ["id"]}, - {"indexUid": "score", "q": "jean", "attributesToRetrieve": ["title"]}, - {"indexUid": "test", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "badman returns", "attributesToRetrieve": ["title"]}, - {"indexUid" : "score", "q": "batman", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "batman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "glass", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "captain", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "pésti", "attributesToRetrieve": ["id"]}, + {"indexUid" : index.uid, "q": "Escape", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "jean", "attributesToRetrieve": ["id"]}, + {"indexUid" : score_index.uid, "q": "jean", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "badman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman returns", "attributesToRetrieve": ["title"]}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 12, "estimatedTotalHits": 12 @@ -2993,46 +2709,35 @@ async fn federation_limit_offset() { #[actix_rt::test] async fn federation_formatting() { - let server = Server::new().await; - let index = server.index("test"); + let server = Server::new_shared(); + let index = shared_index_with_documents().await; + let nested_index = shared_index_with_nested_documents().await; + let score_index = shared_index_with_score_documents().await; - let documents = DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("nested"); - let documents = NESTED_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); - - let index = server.index("score"); - let documents = SCORE_DOCUMENTS.clone(); - let (task, _status_code) = index.add_documents(documents, None).await; - index.wait_task(task.uid()).await.succeeded(); { let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "test", "q": "glass", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, - {"indexUid" : "test", "q": "captain", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, - {"indexUid": "nested", "q": "pésti", "attributesToRetrieve": ["id"]}, - {"indexUid" : "test", "q": "Escape", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, - {"indexUid": "nested", "q": "jean", "attributesToRetrieve": ["id"]}, - {"indexUid": "score", "q": "jean", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, - {"indexUid": "test", "q": "the bat", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, - {"indexUid": "score", "q": "the bat", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, - {"indexUid": "score", "q": "badman returns", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, - {"indexUid" : "score", "q": "batman", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, - {"indexUid": "score", "q": "batman returns", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, + {"indexUid" : index.uid, "q": "glass", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, + {"indexUid" : index.uid, "q": "captain", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, + {"indexUid" : nested_index.uid, "q": "pésti", "attributesToRetrieve": ["id"]}, + {"indexUid" : index.uid, "q": "Escape", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, + {"indexUid" : nested_index.uid, "q": "jean", "attributesToRetrieve": ["id"]}, + {"indexUid" : score_index.uid, "q": "jean", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, + {"indexUid" : index.uid, "q": "the bat", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, + {"indexUid" : score_index.uid, "q": "the bat", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, + {"indexUid" : score_index.uid, "q": "badman returns", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman returns", "attributesToRetrieve": ["title"], "attributesToHighlight": ["title"]}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { "title": "Gläss", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 0, "weightedRankingScore": 1.0 }, @@ -3043,7 +2748,7 @@ async fn federation_formatting() { { "id": 852, "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -3051,7 +2756,7 @@ async fn federation_formatting() { { "title": "Batman", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 1.0 }, @@ -3062,7 +2767,7 @@ async fn federation_formatting() { { "title": "Batman Returns", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 10, "weightedRankingScore": 1.0 }, @@ -3073,7 +2778,7 @@ async fn federation_formatting() { { "title": "Captain Marvel", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 0.9848484848484848 }, @@ -3084,7 +2789,7 @@ async fn federation_formatting() { { "title": "Escape Room", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 3, "weightedRankingScore": 0.9848484848484848 }, @@ -3095,7 +2800,7 @@ async fn federation_formatting() { { "id": 951, "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 4, "weightedRankingScore": 0.9848484848484848 } @@ -3103,7 +2808,7 @@ async fn federation_formatting() { { "title": "Batman the dark knight returns: Part 1", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 0.9848484848484848 }, @@ -3114,7 +2819,7 @@ async fn federation_formatting() { { "title": "Batman the dark knight returns: Part 2", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 0.9848484848484848 }, @@ -3125,7 +2830,7 @@ async fn federation_formatting() { { "id": 654, "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 2, "weightedRankingScore": 0.7803030303030303 } @@ -3133,7 +2838,7 @@ async fn federation_formatting() { { "title": "Badman", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 8, "weightedRankingScore": 0.5 }, @@ -3144,7 +2849,7 @@ async fn federation_formatting() { { "title": "How to Train Your Dragon: The Hidden World", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 6, "weightedRankingScore": 0.4166666666666667 }, @@ -3153,7 +2858,7 @@ async fn federation_formatting() { } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 12 @@ -3164,33 +2869,33 @@ async fn federation_formatting() { { let (response, code) = server .multi_search(json!({"federation": {"limit": 1}, "queries": [ - {"indexUid" : "test", "q": "glass", "attributesToRetrieve": ["title"]}, - {"indexUid" : "test", "q": "captain", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "pésti", "attributesToRetrieve": ["id"]}, - {"indexUid" : "test", "q": "Escape", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "jean", "attributesToRetrieve": ["id"]}, - {"indexUid": "score", "q": "jean", "attributesToRetrieve": ["title"]}, - {"indexUid": "test", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "badman returns", "attributesToRetrieve": ["title"]}, - {"indexUid" : "score", "q": "batman", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "batman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "glass", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "captain", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "pésti", "attributesToRetrieve": ["id"]}, + {"indexUid" : index.uid, "q": "Escape", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "jean", "attributesToRetrieve": ["id"]}, + {"indexUid" : score_index.uid, "q": "jean", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "badman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman returns", "attributesToRetrieve": ["title"]}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { "title": "Gläss", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 0, "weightedRankingScore": 1.0 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 1, "offset": 0, "estimatedTotalHits": 12 @@ -3201,27 +2906,27 @@ async fn federation_formatting() { { let (response, code) = server .multi_search(json!({"federation": {"offset": 2}, "queries": [ - {"indexUid" : "test", "q": "glass", "attributesToRetrieve": ["title"]}, - {"indexUid" : "test", "q": "captain", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "pésti", "attributesToRetrieve": ["id"]}, - {"indexUid" : "test", "q": "Escape", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "jean", "attributesToRetrieve": ["id"]}, - {"indexUid": "score", "q": "jean", "attributesToRetrieve": ["title"]}, - {"indexUid": "test", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "badman returns", "attributesToRetrieve": ["title"]}, - {"indexUid" : "score", "q": "batman", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "batman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "glass", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "captain", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "pésti", "attributesToRetrieve": ["id"]}, + {"indexUid" : index.uid, "q": "Escape", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "jean", "attributesToRetrieve": ["id"]}, + {"indexUid" : score_index.uid, "q": "jean", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "badman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman returns", "attributesToRetrieve": ["title"]}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { "title": "Batman", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 1.0 } @@ -3229,7 +2934,7 @@ async fn federation_formatting() { { "title": "Batman Returns", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 10, "weightedRankingScore": 1.0 } @@ -3237,7 +2942,7 @@ async fn federation_formatting() { { "title": "Captain Marvel", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 1, "weightedRankingScore": 0.9848484848484848 } @@ -3245,7 +2950,7 @@ async fn federation_formatting() { { "title": "Escape Room", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 3, "weightedRankingScore": 0.9848484848484848 } @@ -3253,7 +2958,7 @@ async fn federation_formatting() { { "id": 951, "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 4, "weightedRankingScore": 0.9848484848484848 } @@ -3261,7 +2966,7 @@ async fn federation_formatting() { { "title": "Batman the dark knight returns: Part 1", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 0.9848484848484848 } @@ -3269,7 +2974,7 @@ async fn federation_formatting() { { "title": "Batman the dark knight returns: Part 2", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 9, "weightedRankingScore": 0.9848484848484848 } @@ -3277,7 +2982,7 @@ async fn federation_formatting() { { "id": 654, "_federation": { - "indexUid": "nested", + "indexUid": "SHARED_NESTED_DOCUMENTS", "queriesPosition": 2, "weightedRankingScore": 0.7803030303030303 } @@ -3285,7 +2990,7 @@ async fn federation_formatting() { { "title": "Badman", "_federation": { - "indexUid": "score", + "indexUid": "SHARED_SCORE_DOCUMENTS", "queriesPosition": 8, "weightedRankingScore": 0.5 } @@ -3293,13 +2998,13 @@ async fn federation_formatting() { { "title": "How to Train Your Dragon: The Hidden World", "_federation": { - "indexUid": "test", + "indexUid": "SHARED_DOCUMENTS", "queriesPosition": 6, "weightedRankingScore": 0.4166666666666667 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 2, "estimatedTotalHits": 12 @@ -3310,24 +3015,24 @@ async fn federation_formatting() { { let (response, code) = server .multi_search(json!({"federation": {"offset": 12}, "queries": [ - {"indexUid" : "test", "q": "glass", "attributesToRetrieve": ["title"]}, - {"indexUid" : "test", "q": "captain", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "pésti", "attributesToRetrieve": ["id"]}, - {"indexUid" : "test", "q": "Escape", "attributesToRetrieve": ["title"]}, - {"indexUid": "nested", "q": "jean", "attributesToRetrieve": ["id"]}, - {"indexUid": "score", "q": "jean", "attributesToRetrieve": ["title"]}, - {"indexUid": "test", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "the bat", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "badman returns", "attributesToRetrieve": ["title"]}, - {"indexUid" : "score", "q": "batman", "attributesToRetrieve": ["title"]}, - {"indexUid": "score", "q": "batman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "glass", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "captain", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "pésti", "attributesToRetrieve": ["id"]}, + {"indexUid" : index.uid, "q": "Escape", "attributesToRetrieve": ["title"]}, + {"indexUid" : nested_index.uid, "q": "jean", "attributesToRetrieve": ["id"]}, + {"indexUid" : score_index.uid, "q": "jean", "attributesToRetrieve": ["title"]}, + {"indexUid" : index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "the bat", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "badman returns", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman", "attributesToRetrieve": ["title"]}, + {"indexUid" : score_index.uid, "q": "batman returns", "attributesToRetrieve": ["title"]}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 12, "estimatedTotalHits": 12 @@ -3338,9 +3043,8 @@ async fn federation_formatting() { #[actix_rt::test] async fn federation_invalid_weight() { - let server = Server::new().await; - - let index = server.index("fruits"); + let server = Server::new_shared(); + let index = server.unique_index(); let documents = FRUITS_DOCUMENTS.clone(); let (value, _) = index.add_documents(documents, None).await; @@ -3355,12 +3059,12 @@ async fn federation_invalid_weight() { let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "fruits", "q": "apple red", "filter": "BOOST = true", "showRankingScore": true, "federationOptions": {"weight": 3.0}}, - {"indexUid": "fruits", "q": "apple red", "showRankingScore": true, "federationOptions": {"weight": -12}}, + {"indexUid" : index.uid, "q": "apple red", "filter": "BOOST = true", "showRankingScore": true, "federationOptions": {"weight": 3.0}}, + {"indexUid": index.uid, "q": "apple red", "showRankingScore": true, "federationOptions": {"weight": -12}}, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(response, @r###" { "message": "Invalid value at `.queries[1].federationOptions.weight`: the value of `weight` is invalid, expected a positive float (>= 0.0).", "code": "invalid_multi_search_weight", @@ -3372,9 +3076,9 @@ async fn federation_invalid_weight() { #[actix_rt::test] async fn federation_null_weight() { - let server = Server::new().await; + let server = Server::new_shared(); - let index = server.index("fruits"); + let index = server.unique_index_with_prefix("fruits"); let documents = FRUITS_DOCUMENTS.clone(); let (value, _) = index.add_documents(documents, None).await; @@ -3389,12 +3093,12 @@ async fn federation_null_weight() { let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "fruits", "q": "apple red", "filter": "BOOST = true", "showRankingScore": true, "federationOptions": {"weight": 3.0}}, - {"indexUid": "fruits", "q": "apple red", "showRankingScore": true, "federationOptions": {"weight": 0.0} }, + {"indexUid" : index.uid, "q": "apple red", "filter": "BOOST = true", "showRankingScore": true, "federationOptions": {"weight": 3.0}}, + {"indexUid": index.uid, "q": "apple red", "showRankingScore": true, "federationOptions": {"weight": 0.0} }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { @@ -3402,7 +3106,7 @@ async fn federation_null_weight() { "id": "red-delicious-boosted", "BOOST": true, "_federation": { - "indexUid": "fruits", + "indexUid": "fruits-[uuid]", "queriesPosition": 0, "weightedRankingScore": 2.7281746031746033 }, @@ -3413,7 +3117,7 @@ async fn federation_null_weight() { "id": "green-apple-boosted", "BOOST": true, "_federation": { - "indexUid": "fruits", + "indexUid": "fruits-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.318181818181818 }, @@ -3423,14 +3127,14 @@ async fn federation_null_weight() { "name": "Red apple gala", "id": "red-apple-gala", "_federation": { - "indexUid": "fruits", + "indexUid": "fruits-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.0 }, "_rankingScore": 0.953042328042328 } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 3 @@ -3440,9 +3144,9 @@ async fn federation_null_weight() { #[actix_rt::test] async fn federation_federated_contains_pagination() { - let server = Server::new().await; + let server = Server::new_shared(); - let index = server.index("fruits"); + let index = server.unique_index_with_prefix("fruits"); let documents = FRUITS_DOCUMENTS.clone(); let (value, _) = index.add_documents(documents, None).await; @@ -3451,12 +3155,12 @@ async fn federation_federated_contains_pagination() { // fail when a federated query contains "limit" let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "fruits", "q": "apple red"}, - {"indexUid": "fruits", "q": "apple red", "limit": 5}, + {"indexUid" : index.uid, "q": "apple red"}, + {"indexUid": index.uid, "q": "apple red", "limit": 5}, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(response, @r###" { "message": "Inside `.queries[1]`: Using pagination options is not allowed in federated queries.\n - Hint: remove `limit` from query #1 or remove `federation` from the request\n - Hint: pass `federation.limit` and `federation.offset` for pagination in federated search", "code": "invalid_multi_search_query_pagination", @@ -3467,12 +3171,12 @@ async fn federation_federated_contains_pagination() { // fail when a federated query contains "offset" let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "fruits", "q": "apple red"}, - {"indexUid": "fruits", "q": "apple red", "offset": 5}, + {"indexUid" : index.uid, "q": "apple red"}, + {"indexUid": index.uid, "q": "apple red", "offset": 5}, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(response, @r###" { "message": "Inside `.queries[1]`: Using pagination options is not allowed in federated queries.\n - Hint: remove `offset` from query #1 or remove `federation` from the request\n - Hint: pass `federation.limit` and `federation.offset` for pagination in federated search", "code": "invalid_multi_search_query_pagination", @@ -3483,12 +3187,12 @@ async fn federation_federated_contains_pagination() { // fail when a federated query contains "page" let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "fruits", "q": "apple red"}, - {"indexUid": "fruits", "q": "apple red", "page": 2}, + {"indexUid" : index.uid, "q": "apple red"}, + {"indexUid": index.uid, "q": "apple red", "page": 2}, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(response, @r###" { "message": "Inside `.queries[1]`: Using pagination options is not allowed in federated queries.\n - Hint: remove `page` from query #1 or remove `federation` from the request\n - Hint: pass `federation.limit` and `federation.offset` for pagination in federated search", "code": "invalid_multi_search_query_pagination", @@ -3499,12 +3203,12 @@ async fn federation_federated_contains_pagination() { // fail when a federated query contains "hitsPerPage" let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "fruits", "q": "apple red"}, - {"indexUid": "fruits", "q": "apple red", "hitsPerPage": 5}, + {"indexUid" : index.uid, "q": "apple red"}, + {"indexUid": index.uid, "q": "apple red", "hitsPerPage": 5}, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(response, @r###" { "message": "Inside `.queries[1]`: Using pagination options is not allowed in federated queries.\n - Hint: remove `hitsPerPage` from query #1 or remove `federation` from the request\n - Hint: pass `federation.limit` and `federation.offset` for pagination in federated search", "code": "invalid_multi_search_query_pagination", @@ -3516,9 +3220,9 @@ async fn federation_federated_contains_pagination() { #[actix_rt::test] async fn federation_federated_contains_facets() { - let server = Server::new().await; + let server = Server::new_shared(); - let index = server.index("fruits"); + let index = server.unique_index_with_prefix("fruits"); let (value, _) = index .update_settings( @@ -3535,19 +3239,19 @@ async fn federation_federated_contains_facets() { // empty facets are actually OK let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "fruits", "q": "apple red"}, - {"indexUid": "fruits", "q": "apple red", "facets": []}, + {"indexUid" : index.uid, "q": "apple red"}, + {"indexUid": index.uid, "q": "apple red", "facets": []}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { "name": "Red apple gala", "id": "red-apple-gala", "_federation": { - "indexUid": "fruits", + "indexUid": "fruits-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.953042328042328 } @@ -3557,7 +3261,7 @@ async fn federation_federated_contains_facets() { "id": "red-delicious-boosted", "BOOST": true, "_federation": { - "indexUid": "fruits", + "indexUid": "fruits-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9093915343915344 } @@ -3567,13 +3271,13 @@ async fn federation_federated_contains_facets() { "id": "green-apple-boosted", "BOOST": true, "_federation": { - "indexUid": "fruits", + "indexUid": "fruits-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.4393939393939394 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 3 @@ -3583,14 +3287,14 @@ async fn federation_federated_contains_facets() { // fails let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "fruits", "q": "apple red"}, - {"indexUid": "fruits", "q": "apple red", "facets": ["BOOSTED"]}, + {"indexUid": index.uid, "q": "apple red"}, + {"indexUid": index.uid, "q": "apple red", "facets": ["BOOSTED"]}, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response), @r###" { - "message": "Inside `.queries[1]`: Using facet options is not allowed in federated queries.\n - Hint: remove `facets` from query #1 or remove `federation` from the request\n - Hint: pass `federation.facetsByIndex.fruits: [\"BOOSTED\"]` for facets in federated search", + "message": "Inside `.queries[1]`: Using facet options is not allowed in federated queries.\n - Hint: remove `facets` from query #1 or remove `federation` from the request\n - Hint: pass `federation.facetsByIndex.fruits-[uuid]: [\"BOOSTED\"]` for facets in federated search", "code": "invalid_multi_search_query_facets", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_query_facets" @@ -3600,54 +3304,55 @@ async fn federation_federated_contains_facets() { #[actix_rt::test] async fn federation_non_faceted_for_an_index() { - let server = Server::new().await; + let server = Server::new_shared(); - let index = server.index("fruits"); + let fruits_index = server.unique_index_with_prefix("fruits"); - let (value, _) = index + let (value, _) = fruits_index .update_settings( json!({"searchableAttributes": ["name"], "filterableAttributes": ["BOOST", "id", "name"]}), ) .await; - index.wait_task(value.uid()).await.succeeded(); + fruits_index.wait_task(value.uid()).await.succeeded(); - let index = server.index("fruits-no-name"); + let fruits_no_name_index = server.unique_index_with_prefix("fruits-no-name"); - let (value, _) = index + let (value, _) = fruits_no_name_index .update_settings( json!({"searchableAttributes": ["name"], "filterableAttributes": ["BOOST", "id"]}), ) .await; - index.wait_task(value.uid()).await.succeeded(); + fruits_no_name_index.wait_task(value.uid()).await.succeeded(); - let index = server.index("fruits-no-facets"); + let fruits_no_facets_index = server.unique_index_with_prefix("fruits-no-facets"); - let (value, _) = index.update_settings(json!({"searchableAttributes": ["name"]})).await; + let (value, _) = + fruits_no_facets_index.update_settings(json!({"searchableAttributes": ["name"]})).await; - index.wait_task(value.uid()).await.succeeded(); + fruits_no_facets_index.wait_task(value.uid()).await.succeeded(); let documents = FRUITS_DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); + let (value, _) = fruits_no_facets_index.add_documents(documents, None).await; + fruits_no_facets_index.wait_task(value.uid()).await.succeeded(); // fails let (response, code) = server .multi_search(json!({"federation": { "facetsByIndex": { - "fruits": ["BOOST", "id", "name"], - "fruits-no-name": ["BOOST", "id", "name"], + fruits_index.uid.clone(): ["BOOST", "id", "name"], + fruits_no_name_index.uid.clone(): ["BOOST", "id", "name"], } }, "queries": [ - {"indexUid" : "fruits", "q": "apple red"}, - {"indexUid": "fruits-no-name", "q": "apple red"}, + {"indexUid" : fruits_index.uid.clone(), "q": "apple red"}, + {"indexUid": fruits_no_name_index.uid.clone(), "q": "apple red"}, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response), @r###" { - "message": "Inside `.federation.facetsByIndex.fruits-no-name`: Invalid facet distribution: Attribute `name` is not filterable. Available filterable attributes patterns are: `BOOST, id`.\n - Note: index `fruits-no-name` used in `.queries[1]`", + "message": "Inside `.federation.facetsByIndex.fruits-no-name-[uuid]`: Invalid facet distribution: Attribute `name` is not filterable. Available filterable attributes patterns are: `BOOST, id`.\n - Note: index `fruits-no-name-[uuid]` used in `.queries[1]`", "code": "invalid_multi_search_facets", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_facets" @@ -3658,18 +3363,18 @@ async fn federation_non_faceted_for_an_index() { let (response, code) = server .multi_search(json!({"federation": { "facetsByIndex": { - "fruits": ["BOOST", "id", "name"], - "fruits-no-name": ["BOOST", "id", "name"], + fruits_index.uid.clone(): ["BOOST", "id", "name"], + fruits_no_name_index.uid.clone(): ["BOOST", "id", "name"], } }, "queries": [ - {"indexUid" : "fruits", "q": "apple red"}, - {"indexUid": "fruits", "q": "apple red"}, + {"indexUid" : fruits_index.uid.clone(), "q": "apple red"}, + {"indexUid": fruits_index.uid.clone(), "q": "apple red"}, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response), @r###" { - "message": "Inside `.federation.facetsByIndex.fruits-no-name`: Invalid facet distribution: Attribute `name` is not filterable. Available filterable attributes patterns are: `BOOST, id`.\n - Note: index `fruits-no-name` is not used in queries", + "message": "Inside `.federation.facetsByIndex.fruits-no-name-[uuid]`: Invalid facet distribution: Attribute `name` is not filterable. Available filterable attributes patterns are: `BOOST, id`.\n - Note: index `fruits-no-name-[uuid]` is not used in queries", "code": "invalid_multi_search_facets", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_facets" @@ -3680,19 +3385,19 @@ async fn federation_non_faceted_for_an_index() { let (response, code) = server .multi_search(json!({"federation": { "facetsByIndex": { - "fruits": ["BOOST", "id", "name"], - "fruits-no-name": ["BOOST", "id"], - "fruits-no-facets": ["BOOST", "id"], + fruits_index.uid.clone(): ["BOOST", "id", "name"], + fruits_no_name_index.uid.clone(): ["BOOST", "id"], + fruits_no_facets_index.uid.clone(): ["BOOST", "id"], } }, "queries": [ - {"indexUid" : "fruits", "q": "apple red"}, - {"indexUid": "fruits", "q": "apple red"}, + {"indexUid" : fruits_index.uid.clone(), "q": "apple red"}, + {"indexUid": fruits_index.uid.clone(), "q": "apple red"}, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r#" + snapshot!(json_string!(response), @r#" { - "message": "Inside `.federation.facetsByIndex.fruits-no-facets`: Invalid facet distribution: Attributes `BOOST, id` are not filterable. This index does not have configured filterable attributes.\n - Note: index `fruits-no-facets` is not used in queries", + "message": "Inside `.federation.facetsByIndex.fruits-no-facets-[uuid]`: Invalid facet distribution: Attributes `BOOST, id` are not filterable. This index does not have configured filterable attributes.\n - Note: index `fruits-no-facets-[uuid]` is not used in queries", "code": "invalid_multi_search_facets", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_facets" @@ -3704,15 +3409,15 @@ async fn federation_non_faceted_for_an_index() { .multi_search(json!({"federation": { "facetsByIndex": { "zorglub": ["BOOST", "id", "name"], - "fruits": ["BOOST", "id", "name"], + fruits_index.uid.clone(): ["BOOST", "id", "name"], } }, "queries": [ - {"indexUid" : "fruits", "q": "apple red"}, - {"indexUid": "fruits", "q": "apple red"}, + {"indexUid" : fruits_index.uid.clone(), "q": "apple red"}, + {"indexUid": fruits_index.uid.clone(), "q": "apple red"}, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(response, @r###" { "message": "Inside `.federation.facetsByIndex.zorglub`: Index `zorglub` not found.\n - Note: index `zorglub` is not used in queries", "code": "index_not_found", @@ -3724,9 +3429,9 @@ async fn federation_non_faceted_for_an_index() { #[actix_rt::test] async fn federation_non_federated_contains_federation_option() { - let server = Server::new().await; + let server = Server::new_shared(); - let index = server.index("fruits"); + let index = server.unique_index(); let documents = FRUITS_DOCUMENTS.clone(); let (value, _) = index.add_documents(documents, None).await; @@ -3735,12 +3440,12 @@ async fn federation_non_federated_contains_federation_option() { // fail when a non-federated query contains "federationOptions" let (response, code) = server .multi_search(json!({"queries": [ - {"indexUid" : "fruits", "q": "apple red"}, - {"indexUid": "fruits", "q": "apple red", "federationOptions": {}}, + {"indexUid" : index.uid.clone(), "q": "apple red"}, + {"indexUid": index.uid.clone(), "q": "apple red", "federationOptions": {}}, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(response, @r###" { "message": "Inside `.queries[1]`: Using `federationOptions` is not allowed in a non-federated search.\n - Hint: remove `federationOptions` from query #1 or add `federation` to the request.", "code": "invalid_multi_search_federation_options", @@ -3752,9 +3457,9 @@ async fn federation_non_federated_contains_federation_option() { #[actix_rt::test] async fn federation_vector_single_index() { - let server = Server::new().await; + let server = Server::new_shared(); - let index = server.index("vectors"); + let index = server.unique_index(); let (value, _) = index .update_settings(json!({"embedders": { @@ -3778,19 +3483,19 @@ async fn federation_vector_single_index() { // same embedder let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "vectors", "vector": [1.0, 0.0, 0.5], "hybrid": {"semanticRatio": 1.0, "embedder": "animal"}}, - {"indexUid": "vectors", "vector": [0.5, 0.5, 0.5], "hybrid": {"semanticRatio": 1.0, "embedder": "animal"}}, + {"indexUid" : index.uid.clone(), "vector": [1.0, 0.0, 0.5], "hybrid": {"semanticRatio": 1.0, "embedder": "animal"}}, + {"indexUid": index.uid.clone(), "vector": [0.5, 0.5, 0.5], "hybrid": {"semanticRatio": 1.0, "embedder": "animal"}}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { "id": "B", "description": "the kitten scratched the beagle", "_federation": { - "indexUid": "vectors", + "indexUid": "[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.9870882034301758 } @@ -3799,7 +3504,7 @@ async fn federation_vector_single_index() { "id": "D", "description": "the little boy pets the puppy", "_federation": { - "indexUid": "vectors", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9728479385375975 } @@ -3808,7 +3513,7 @@ async fn federation_vector_single_index() { "id": "C", "description": "the dog had to stay alone today", "_federation": { - "indexUid": "vectors", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9701486229896544 } @@ -3817,13 +3522,13 @@ async fn federation_vector_single_index() { "id": "A", "description": "the dog barks at the cat", "_federation": { - "indexUid": "vectors", + "indexUid": "[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.9191691875457764 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 4, @@ -3834,20 +3539,20 @@ async fn federation_vector_single_index() { // distinct embedder let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "vectors", "vector": [1.0, 0.0, 0.5], "hybrid": {"semanticRatio": 1.0, "embedder": "animal"}}, + {"indexUid" : index.uid.clone(), "vector": [1.0, 0.0, 0.5], "hybrid": {"semanticRatio": 1.0, "embedder": "animal"}}, // joyful and energetic first - {"indexUid": "vectors", "vector": [0.8, 0.6], "hybrid": {"semanticRatio": 1.0, "embedder": "sentiment"}}, + {"indexUid": index.uid.clone(), "vector": [0.8, 0.6], "hybrid": {"semanticRatio": 1.0, "embedder": "sentiment"}}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { "id": "D", "description": "the little boy pets the puppy", "_federation": { - "indexUid": "vectors", + "indexUid": "[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.979868710041046 } @@ -3856,7 +3561,7 @@ async fn federation_vector_single_index() { "id": "C", "description": "the dog had to stay alone today", "_federation": { - "indexUid": "vectors", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9701486229896544 } @@ -3865,7 +3570,7 @@ async fn federation_vector_single_index() { "id": "B", "description": "the kitten scratched the beagle", "_federation": { - "indexUid": "vectors", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.8601469993591309 } @@ -3874,13 +3579,13 @@ async fn federation_vector_single_index() { "id": "A", "description": "the dog barks at the cat", "_federation": { - "indexUid": "vectors", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.8432406187057495 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 4, @@ -3891,21 +3596,21 @@ async fn federation_vector_single_index() { // hybrid search, distinct embedder let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "vectors", "vector": [1.0, 0.0, 0.5], "hybrid": {"semanticRatio": 1.0, "embedder": "animal"}, "showRankingScore": true}, + {"indexUid" : index.uid, "vector": [1.0, 0.0, 0.5], "hybrid": {"semanticRatio": 1.0, "embedder": "animal"}, "showRankingScore": true}, // joyful and energetic first - {"indexUid": "vectors", "vector": [0.8, 0.6], "q": "beagle", "hybrid": {"semanticRatio": 1.0, "embedder": "sentiment"},"showRankingScore": true}, - {"indexUid": "vectors", "q": "dog", "showRankingScore": true}, + {"indexUid": index.uid, "vector": [0.8, 0.6], "q": "beagle", "hybrid": {"semanticRatio": 1.0, "embedder": "sentiment"},"showRankingScore": true}, + {"indexUid": index.uid, "q": "dog", "showRankingScore": true}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { "id": "D", "description": "the little boy pets the puppy", "_federation": { - "indexUid": "vectors", + "indexUid": "[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.979868710041046 }, @@ -3915,7 +3620,7 @@ async fn federation_vector_single_index() { "id": "C", "description": "the dog had to stay alone today", "_federation": { - "indexUid": "vectors", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9701486229896544 }, @@ -3925,7 +3630,7 @@ async fn federation_vector_single_index() { "id": "A", "description": "the dog barks at the cat", "_federation": { - "indexUid": "vectors", + "indexUid": "[uuid]", "queriesPosition": 2, "weightedRankingScore": 0.9242424242424242 }, @@ -3935,14 +3640,14 @@ async fn federation_vector_single_index() { "id": "B", "description": "the kitten scratched the beagle", "_federation": { - "indexUid": "vectors", + "indexUid": "[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.8601469993591309 }, "_rankingScore": "[score]" } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 4, @@ -3953,11 +3658,11 @@ async fn federation_vector_single_index() { #[actix_rt::test] async fn federation_vector_two_indexes() { - let server = Server::new().await; + let server = Server::new_shared(); - let index = server.index("vectors-animal"); + let vectors_animal_index = server.unique_index_with_prefix("vectors-animal"); - let (value, _) = index + let (value, _) = vectors_animal_index .update_settings(json!({"embedders": { "animal": { "source": "userProvided", @@ -3965,16 +3670,16 @@ async fn federation_vector_two_indexes() { }, }})) .await; - index.wait_task(value.uid()).await.succeeded(); + vectors_animal_index.wait_task(value.uid()).await.succeeded(); let documents = VECTOR_DOCUMENTS.clone(); - let (value, code) = index.add_documents(documents, None).await; + let (value, code) = vectors_animal_index.add_documents(documents, None).await; snapshot!(code, @"202 Accepted"); - index.wait_task(value.uid()).await.succeeded(); + vectors_animal_index.wait_task(value.uid()).await.succeeded(); - let index = server.index("vectors-sentiment"); + let vectors_sentiment_index = server.unique_index_with_prefix("vectors-sentiment"); - let (value, _) = index + let (value, _) = vectors_sentiment_index .update_settings(json!({"embedders": { "sentiment": { "source": "userProvided", @@ -3982,23 +3687,23 @@ async fn federation_vector_two_indexes() { } }})) .await; - index.wait_task(value.uid()).await.succeeded(); + vectors_sentiment_index.wait_task(value.uid()).await.succeeded(); let documents = VECTOR_DOCUMENTS.clone(); - let (value, code) = index.add_documents(documents, None).await; + let (value, code) = vectors_sentiment_index.add_documents(documents, None).await; snapshot!(code, @"202 Accepted"); - index.wait_task(value.uid()).await.succeeded(); + vectors_sentiment_index.wait_task(value.uid()).await.succeeded(); let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "vectors-animal", "vector": [1.0, 0.0, 0.5], "hybrid": {"semanticRatio": 1.0, "embedder": "animal"}, "retrieveVectors": true}, + {"indexUid" : vectors_animal_index.uid, "vector": [1.0, 0.0, 0.5], "hybrid": {"semanticRatio": 1.0, "embedder": "animal"}, "retrieveVectors": true}, // joyful and energetic first - {"indexUid": "vectors-sentiment", "vector": [0.8, 0.6], "hybrid": {"semanticRatio": 1.0, "embedder": "sentiment"}, "retrieveVectors": true}, - {"indexUid": "vectors-sentiment", "q": "dog", "retrieveVectors": true}, + {"indexUid": vectors_sentiment_index.uid, "vector": [0.8, 0.6], "hybrid": {"semanticRatio": 1.0, "embedder": "sentiment"}, "retrieveVectors": true}, + {"indexUid": vectors_sentiment_index.uid, "q": "dog", "retrieveVectors": true}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { @@ -4021,7 +3726,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-sentiment", + "indexUid": "vectors-sentiment-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.979868710041046 } @@ -4046,7 +3751,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-animal", + "indexUid": "vectors-animal-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9728479385375975 } @@ -4071,7 +3776,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-animal", + "indexUid": "vectors-animal-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9701486229896544 } @@ -4096,7 +3801,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-sentiment", + "indexUid": "vectors-sentiment-[uuid]", "queriesPosition": 2, "weightedRankingScore": 0.9242424242424242 } @@ -4121,7 +3826,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-sentiment", + "indexUid": "vectors-sentiment-[uuid]", "queriesPosition": 2, "weightedRankingScore": 0.9242424242424242 } @@ -4146,7 +3851,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-animal", + "indexUid": "vectors-animal-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.8601469993591309 } @@ -4171,7 +3876,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-animal", + "indexUid": "vectors-animal-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.8432406187057495 } @@ -4196,13 +3901,13 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-sentiment", + "indexUid": "vectors-sentiment-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.6690993905067444 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 8, @@ -4213,12 +3918,12 @@ async fn federation_vector_two_indexes() { // hybrid search, distinct embedder let (response, code) = server .multi_search(json!({"federation": {}, "queries": [ - {"indexUid" : "vectors-animal", "vector": [1.0, 0.0, 0.5], "hybrid": {"semanticRatio": 1.0, "embedder": "animal"}, "showRankingScore": true, "retrieveVectors": true}, - {"indexUid": "vectors-sentiment", "vector": [-1, 0.6], "q": "beagle", "hybrid": {"semanticRatio": 1.0, "embedder": "sentiment"}, "showRankingScore": true, "retrieveVectors": true,}, + {"indexUid" : vectors_animal_index.uid, "vector": [1.0, 0.0, 0.5], "hybrid": {"semanticRatio": 1.0, "embedder": "animal"}, "showRankingScore": true, "retrieveVectors": true}, + {"indexUid": vectors_sentiment_index.uid, "vector": [-1, 0.6], "q": "beagle", "hybrid": {"semanticRatio": 1.0, "embedder": "sentiment"}, "showRankingScore": true, "retrieveVectors": true,}, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]", ".**._rankingScore" => "[score]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]", ".**._rankingScore" => "[score]" }), @r###" { "hits": [ { @@ -4241,7 +3946,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-animal", + "indexUid": "vectors-animal-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9728479385375975 }, @@ -4267,7 +3972,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-animal", + "indexUid": "vectors-animal-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9701486229896544 }, @@ -4293,7 +3998,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-sentiment", + "indexUid": "vectors-sentiment-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.9522157907485962 }, @@ -4319,7 +4024,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-sentiment", + "indexUid": "vectors-sentiment-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.8719604015350342 }, @@ -4345,7 +4050,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-animal", + "indexUid": "vectors-animal-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.8601469993591309 }, @@ -4371,7 +4076,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-animal", + "indexUid": "vectors-animal-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.8432406187057495 }, @@ -4397,7 +4102,7 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-sentiment", + "indexUid": "vectors-sentiment-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.8297949433326721 }, @@ -4423,14 +4128,14 @@ async fn federation_vector_two_indexes() { } }, "_federation": { - "indexUid": "vectors-sentiment", + "indexUid": "vectors-sentiment-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.18887794017791748 }, "_rankingScore": "[score]" } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 8, @@ -4441,37 +4146,17 @@ async fn federation_vector_two_indexes() { #[actix_rt::test] async fn federation_facets_different_indexes_same_facet() { - let server = Server::new().await; + let server = Server::new_shared(); + let movies_index = shared_movies_index().await; + let batman_index = shared_batman_index().await; - let index = server.index("movies"); - - let documents = DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); - - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["title"], - "filterableAttributes": ["title", "color"], - "rankingRules": [ - "sort", - "words", - "typo", - "proximity", - "attribute", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); - - let index = server.index("batman"); + let batman_2_index = server.unique_index_with_prefix("batman_2"); let documents = SCORE_DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); + let (value, _) = batman_2_index.add_documents(documents, None).await; + batman_2_index.wait_task(value.uid()).await.succeeded(); - let (value, _) = index + let (value, _) = batman_2_index .update_settings(json!({ "sortableAttributes": ["title"], "filterableAttributes": ["title"], @@ -4485,52 +4170,30 @@ async fn federation_facets_different_indexes_same_facet() { ] })) .await; - index.wait_task(value.uid()).await.succeeded(); + batman_2_index.wait_task(value.uid()).await.succeeded(); - let index = server.index("batman-2"); - - let documents = SCORE_DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); - - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["title"], - "filterableAttributes": ["title"], - "rankingRules": [ - "sort", - "words", - "typo", - "proximity", - "attribute", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); - - // return titles ordered accross indexes + // return titles ordered across indexes let (response, code) = server .multi_search(json!({"federation": { "facetsByIndex": { - "movies": ["title", "color"], - "batman": ["title"], - "batman-2": ["title"], + movies_index.uid.clone(): ["title", "color"], + batman_index.uid.clone(): ["title"], + batman_2_index.uid.clone(): ["title"], } }, "queries": [ - {"indexUid" : "movies", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, - {"indexUid" : "batman", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, - {"indexUid" : "batman-2", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : movies_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : batman_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : batman_2_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { "title": "Badman", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -4538,7 +4201,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Badman", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -4546,7 +4209,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -4554,7 +4217,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -4562,7 +4225,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman Returns", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -4570,7 +4233,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman Returns", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -4578,7 +4241,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman the dark knight returns: Part 1", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -4586,7 +4249,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman the dark knight returns: Part 1", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -4594,7 +4257,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman the dark knight returns: Part 2", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -4602,7 +4265,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman the dark knight returns: Part 2", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -4610,7 +4273,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Captain Marvel", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -4618,7 +4281,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Escape Room", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -4626,7 +4289,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Gläss", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -4634,7 +4297,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "How to Train Your Dragon: The Hidden World", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -4642,18 +4305,18 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Shazam!", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 15, "facetsByIndex": { - "batman": { + "batman-[uuid]": { "distribution": { "title": { "Badman": 1, @@ -4665,7 +4328,7 @@ async fn federation_facets_different_indexes_same_facet() { }, "stats": {} }, - "batman-2": { + "batman_2-[uuid]": { "distribution": { "title": { "Badman": 1, @@ -4677,7 +4340,7 @@ async fn federation_facets_different_indexes_same_facet() { }, "stats": {} }, - "movies": { + "movies-[uuid]": { "distribution": { "color": { "blue": 3, @@ -4702,25 +4365,25 @@ async fn federation_facets_different_indexes_same_facet() { let (response, code) = server .multi_search(json!({"federation": { "facetsByIndex": { - "movies": ["title"], - "batman": ["title"], - "batman-2": ["title"] + movies_index.uid.clone(): ["title"], + batman_index.uid.clone(): ["title"], + batman_2_index.uid.clone(): ["title"] }, "mergeFacets": {} }, "queries": [ - {"indexUid" : "movies", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, - {"indexUid" : "batman", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, - {"indexUid" : "batman-2", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : movies_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : batman_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : batman_2_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { "title": "Badman", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -4728,7 +4391,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Badman", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -4736,7 +4399,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -4744,7 +4407,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -4752,7 +4415,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman Returns", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -4760,7 +4423,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman Returns", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -4768,7 +4431,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman the dark knight returns: Part 1", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -4776,7 +4439,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman the dark knight returns: Part 1", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -4784,7 +4447,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman the dark knight returns: Part 2", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -4792,7 +4455,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman the dark knight returns: Part 2", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -4800,7 +4463,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Captain Marvel", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -4808,7 +4471,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Escape Room", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -4816,7 +4479,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Gläss", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -4824,7 +4487,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "How to Train Your Dragon: The Hidden World", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -4832,13 +4495,13 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Shazam!", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 15, @@ -4864,25 +4527,25 @@ async fn federation_facets_different_indexes_same_facet() { let (response, code) = server .multi_search(json!({"federation": { "facetsByIndex": { - "movies": [], - "batman": ["title"], - "batman-2": ["title"] + movies_index.uid.clone(): [], + batman_index.uid.clone(): ["title"], + batman_2_index.uid.clone(): ["title"] } }, "queries": [ - {"indexUid" : "batman", "q": "badman returns", "sort": ["title:desc"], "attributesToRetrieve": ["title"] }, - {"indexUid" : "batman-2", "q": "badman returns", "sort": ["title:desc"], "attributesToRetrieve": ["title"] }, - {"indexUid" : "movies", "q": "captain", "sort": ["title:desc"], "attributesToRetrieve": ["title"] }, - {"indexUid" : "batman", "q": "the bat", "sort": ["title:desc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : batman_index.uid.clone(), "q": "badman returns", "sort": ["title:desc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : batman_2_index.uid.clone(), "q": "badman returns", "sort": ["title:desc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : movies_index.uid.clone(), "q": "captain", "sort": ["title:desc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : batman_index.uid.clone(), "q": "the bat", "sort": ["title:desc"], "attributesToRetrieve": ["title"] }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { "title": "Captain Marvel", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 2, "weightedRankingScore": 0.9848484848484848 } @@ -4890,7 +4553,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman the dark knight returns: Part 2", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 3, "weightedRankingScore": 0.9528218694885362 } @@ -4898,7 +4561,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman the dark knight returns: Part 2", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.7028218694885362 } @@ -4906,7 +4569,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman the dark knight returns: Part 1", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 3, "weightedRankingScore": 0.9528218694885362 } @@ -4914,7 +4577,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman the dark knight returns: Part 1", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.7028218694885362 } @@ -4922,7 +4585,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman Returns", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.8317901234567902 } @@ -4930,7 +4593,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman Returns", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.8317901234567902 } @@ -4938,7 +4601,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.23106060606060605 } @@ -4946,7 +4609,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Batman", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.23106060606060605 } @@ -4954,7 +4617,7 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Badman", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.5 } @@ -4962,18 +4625,18 @@ async fn federation_facets_different_indexes_same_facet() { { "title": "Badman", "_federation": { - "indexUid": "batman-2", + "indexUid": "batman_2-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.5 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 11, "facetsByIndex": { - "batman": { + "batman-[uuid]": { "distribution": { "title": { "Badman": 1, @@ -4985,7 +4648,7 @@ async fn federation_facets_different_indexes_same_facet() { }, "stats": {} }, - "batman-2": { + "batman_2-[uuid]": { "distribution": { "title": { "Badman": 1, @@ -4997,7 +4660,7 @@ async fn federation_facets_different_indexes_same_facet() { }, "stats": {} }, - "movies": { + "movies-[uuid]": { "distribution": {}, "stats": {} } @@ -5008,15 +4671,15 @@ async fn federation_facets_different_indexes_same_facet() { #[actix_rt::test] async fn federation_facets_same_indexes() { - let server = Server::new().await; + let server = Server::new_shared(); - let index = server.index("doggos"); + let doggos_index = server.unique_index_with_prefix("doggos"); let documents = NESTED_DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); + let (value, _) = doggos_index.add_documents(documents, None).await; + doggos_index.wait_task(value.uid()).await.succeeded(); - let (value, _) = index + let (value, _) = doggos_index .update_settings(json!({ "filterableAttributes": ["father", "mother", "doggos.age"], "rankingRules": [ @@ -5029,15 +4692,15 @@ async fn federation_facets_same_indexes() { ] })) .await; - index.wait_task(value.uid()).await.succeeded(); + doggos_index.wait_task(value.uid()).await.succeeded(); - let index = server.index("doggos-2"); + let doggos2_index = server.unique_index_with_prefix("doggos_2"); let documents = NESTED_DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); + let (value, _) = doggos2_index.add_documents(documents, None).await; + doggos2_index.wait_task(value.uid()).await.succeeded(); - let (value, _) = index + let (value, _) = doggos2_index .update_settings(json!({ "filterableAttributes": ["father", "mother", "doggos.age"], "rankingRules": [ @@ -5050,26 +4713,26 @@ async fn federation_facets_same_indexes() { ] })) .await; - index.wait_task(value.uid()).await.succeeded(); + doggos2_index.wait_task(value.uid()).await.succeeded(); let (response, code) = server .multi_search(json!({"federation": { "facetsByIndex": { - "doggos": ["father", "mother", "doggos.age"] + doggos_index.uid.clone(): ["father", "mother", "doggos.age"] } }, "queries": [ - {"indexUid" : "doggos", "q": "je", "attributesToRetrieve": ["id"] }, - {"indexUid" : "doggos", "q": "michel", "attributesToRetrieve": ["id"] }, + {"indexUid" : doggos_index.uid.clone(), "q": "je", "attributesToRetrieve": ["id"] }, + {"indexUid" : doggos_index.uid.clone(), "q": "michel", "attributesToRetrieve": ["id"] }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { "id": 852, "_federation": { - "indexUid": "doggos", + "indexUid": "doggos-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9621212121212122 } @@ -5077,7 +4740,7 @@ async fn federation_facets_same_indexes() { { "id": 951, "_federation": { - "indexUid": "doggos", + "indexUid": "doggos-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9621212121212122 } @@ -5085,18 +4748,18 @@ async fn federation_facets_same_indexes() { { "id": 750, "_federation": { - "indexUid": "doggos", + "indexUid": "doggos-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.9621212121212122 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 3, "facetsByIndex": { - "doggos": { + "doggos-[uuid]": { "distribution": { "doggos.age": { "2": 1, @@ -5128,22 +4791,22 @@ async fn federation_facets_same_indexes() { let (response, code) = server .multi_search(json!({"federation": { "facetsByIndex": { - "doggos": ["father", "mother", "doggos.age"], - "doggos-2": ["father", "mother", "doggos.age"] + doggos_index.uid.clone(): ["father", "mother", "doggos.age"], + doggos2_index.uid.clone(): ["father", "mother", "doggos.age"] } }, "queries": [ - {"indexUid" : "doggos", "q": "je", "attributesToRetrieve": ["id"] }, - {"indexUid" : "doggos-2", "q": "michel", "attributesToRetrieve": ["id"] }, + {"indexUid" : doggos_index.uid.clone(), "q": "je", "attributesToRetrieve": ["id"] }, + {"indexUid" : doggos2_index.uid.clone(), "q": "michel", "attributesToRetrieve": ["id"] }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { "id": 852, "_federation": { - "indexUid": "doggos", + "indexUid": "doggos-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9621212121212122 } @@ -5151,7 +4814,7 @@ async fn federation_facets_same_indexes() { { "id": 951, "_federation": { - "indexUid": "doggos", + "indexUid": "doggos-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9621212121212122 } @@ -5159,7 +4822,7 @@ async fn federation_facets_same_indexes() { { "id": 852, "_federation": { - "indexUid": "doggos-2", + "indexUid": "doggos_2-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.9621212121212122 } @@ -5167,18 +4830,18 @@ async fn federation_facets_same_indexes() { { "id": 750, "_federation": { - "indexUid": "doggos-2", + "indexUid": "doggos_2-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.9621212121212122 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 4, "facetsByIndex": { - "doggos": { + "doggos-[uuid]": { "distribution": { "doggos.age": { "2": 1, @@ -5202,7 +4865,7 @@ async fn federation_facets_same_indexes() { } } }, - "doggos-2": { + "doggos_2-[uuid]": { "distribution": { "doggos.age": { "2": 1, @@ -5230,23 +4893,23 @@ async fn federation_facets_same_indexes() { let (response, code) = server .multi_search(json!({"federation": { "facetsByIndex": { - "doggos": ["father", "mother", "doggos.age"], - "doggos-2": ["father", "mother", "doggos.age"] + doggos_index.uid.clone(): ["father", "mother", "doggos.age"], + doggos2_index.uid.clone(): ["father", "mother", "doggos.age"] }, "mergeFacets": {}, }, "queries": [ - {"indexUid" : "doggos", "q": "je", "attributesToRetrieve": ["id"] }, - {"indexUid" : "doggos-2", "q": "michel", "attributesToRetrieve": ["id"] }, + {"indexUid" : doggos_index.uid.clone(), "q": "je", "attributesToRetrieve": ["id"] }, + {"indexUid" : doggos2_index.uid.clone(), "q": "michel", "attributesToRetrieve": ["id"] }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { "id": 852, "_federation": { - "indexUid": "doggos", + "indexUid": "doggos-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9621212121212122 } @@ -5254,7 +4917,7 @@ async fn federation_facets_same_indexes() { { "id": 951, "_federation": { - "indexUid": "doggos", + "indexUid": "doggos-[uuid]", "queriesPosition": 0, "weightedRankingScore": 0.9621212121212122 } @@ -5262,7 +4925,7 @@ async fn federation_facets_same_indexes() { { "id": 852, "_federation": { - "indexUid": "doggos-2", + "indexUid": "doggos_2-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.9621212121212122 } @@ -5270,13 +4933,13 @@ async fn federation_facets_same_indexes() { { "id": 750, "_federation": { - "indexUid": "doggos-2", + "indexUid": "doggos_2-[uuid]", "queriesPosition": 1, "weightedRankingScore": 0.9621212121212122 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 4, @@ -5309,37 +4972,17 @@ async fn federation_facets_same_indexes() { #[actix_rt::test] async fn federation_inconsistent_merge_order() { - let server = Server::new().await; + let server = Server::new_shared(); - let index = server.index("movies"); + let movies_index = shared_movies_index().await; + + let movies2_index = server.unique_index_with_prefix("movies_2"); let documents = DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); + let (value, _) = movies2_index.add_documents(documents, None).await; + movies2_index.wait_task(value.uid()).await.succeeded(); - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["title"], - "filterableAttributes": ["title", "color"], - "rankingRules": [ - "sort", - "words", - "typo", - "proximity", - "attribute", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); - - let index = server.index("movies-2"); - - let documents = DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); - - let (value, _) = index + let (value, _) = movies2_index .update_settings(json!({ "sortableAttributes": ["title"], "filterableAttributes": ["title", "color"], @@ -5356,52 +4999,32 @@ async fn federation_inconsistent_merge_order() { } })) .await; - index.wait_task(value.uid()).await.succeeded(); + movies2_index.wait_task(value.uid()).await.succeeded(); - let index = server.index("batman"); - - let documents = SCORE_DOCUMENTS.clone(); - let (value, _) = index.add_documents(documents, None).await; - index.wait_task(value.uid()).await.succeeded(); - - let (value, _) = index - .update_settings(json!({ - "sortableAttributes": ["title"], - "filterableAttributes": ["title"], - "rankingRules": [ - "sort", - "words", - "typo", - "proximity", - "attribute", - "exactness" - ] - })) - .await; - index.wait_task(value.uid()).await.succeeded(); + let batman_index = shared_batman_index().await; // without merging, it works let (response, code) = server .multi_search(json!({"federation": { "facetsByIndex": { - "movies": ["title", "color"], - "batman": ["title"], - "movies-2": ["title", "color"], + movies_index.uid.clone(): ["title", "color"], + batman_index.uid.clone(): ["title"], + movies2_index.uid.clone(): ["title", "color"], } }, "queries": [ - {"indexUid" : "movies", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, - {"indexUid" : "batman", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, - {"indexUid" : "movies-2", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : movies_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : batman_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : movies2_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { "title": "Badman", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -5409,7 +5032,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Batman", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -5417,7 +5040,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Batman Returns", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -5425,7 +5048,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Batman the dark knight returns: Part 1", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -5433,7 +5056,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Batman the dark knight returns: Part 2", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -5441,7 +5064,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Captain Marvel", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -5449,7 +5072,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Captain Marvel", "_federation": { - "indexUid": "movies-2", + "indexUid": "movies_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -5457,7 +5080,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Escape Room", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -5465,7 +5088,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Escape Room", "_federation": { - "indexUid": "movies-2", + "indexUid": "movies_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -5473,7 +5096,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Gläss", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -5481,7 +5104,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Gläss", "_federation": { - "indexUid": "movies-2", + "indexUid": "movies_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -5489,7 +5112,7 @@ async fn federation_inconsistent_merge_order() { { "title": "How to Train Your Dragon: The Hidden World", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -5497,7 +5120,7 @@ async fn federation_inconsistent_merge_order() { { "title": "How to Train Your Dragon: The Hidden World", "_federation": { - "indexUid": "movies-2", + "indexUid": "movies_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -5505,7 +5128,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Shazam!", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -5513,18 +5136,18 @@ async fn federation_inconsistent_merge_order() { { "title": "Shazam!", "_federation": { - "indexUid": "movies-2", + "indexUid": "movies_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 15, "facetsByIndex": { - "batman": { + "batman-[uuid]": { "distribution": { "title": { "Badman": 1, @@ -5536,7 +5159,7 @@ async fn federation_inconsistent_merge_order() { }, "stats": {} }, - "movies": { + "movies-[uuid]": { "distribution": { "color": { "blue": 3, @@ -5554,7 +5177,7 @@ async fn federation_inconsistent_merge_order() { }, "stats": {} }, - "movies-2": { + "movies_2-[uuid]": { "distribution": { "color": { "red": 3, @@ -5580,21 +5203,21 @@ async fn federation_inconsistent_merge_order() { let (response, code) = server .multi_search(json!({"federation": { "facetsByIndex": { - "movies": ["title", "color"], - "batman": ["title"], - "movies-2": ["title", "color"], + movies_index.uid.clone(): ["title", "color"], + batman_index.uid.clone(): ["title"], + movies2_index.uid.clone(): ["title", "color"], }, "mergeFacets": {} }, "queries": [ - {"indexUid" : "movies", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, - {"indexUid" : "batman", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, - {"indexUid" : "movies-2", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : movies_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : batman_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : movies2_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, ]})) .await; snapshot!(code, @"400 Bad Request"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response), @r###" { - "message": "Inside `.federation.facetsByIndex.movies-2`: Inconsistent order for values in facet `color`: index `movies` orders alphabetically, but index `movies-2` orders by count.\n - Hint: Remove `federation.mergeFacets` or change `faceting.sortFacetValuesBy` to be consistent in settings.\n - Note: index `movies-2` used in `.queries[2]`", + "message": "Inside `.federation.facetsByIndex.movies_2-[uuid]`: Inconsistent order for values in facet `color`: index `movies-[uuid]` orders alphabetically, but index `movies_2-[uuid]` orders by count.\n - Hint: Remove `federation.mergeFacets` or change `faceting.sortFacetValuesBy` to be consistent in settings.\n - Note: index `movies_2-[uuid]` used in `.queries[2]`", "code": "invalid_multi_search_facet_order", "type": "invalid_request", "link": "https://docs.meilisearch.com/errors#invalid_multi_search_facet_order" @@ -5605,27 +5228,27 @@ async fn federation_inconsistent_merge_order() { let (response, code) = server .multi_search(json!({"federation": { "facetsByIndex": { - "movies": ["title", "color"], - "batman": ["title"], - "movies-2": ["title"], + movies_index.uid.clone(): ["title", "color"], + batman_index.uid.clone(): ["title"], + movies2_index.uid.clone(): ["title"], }, "mergeFacets": { "maxValuesPerFacet": 3, } }, "queries": [ - {"indexUid" : "movies", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, - {"indexUid" : "batman", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, - {"indexUid" : "movies-2", "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : movies_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : batman_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, + {"indexUid" : movies2_index.uid.clone(), "q": "", "sort": ["title:asc"], "attributesToRetrieve": ["title"] }, ]})) .await; snapshot!(code, @"200 OK"); - insta::assert_json_snapshot!(response, { ".processingTimeMs" => "[time]" }, @r###" + snapshot!(json_string!(response, { ".processingTimeMs" => "[duration]" }), @r###" { "hits": [ { "title": "Badman", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -5633,7 +5256,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Batman", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -5641,7 +5264,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Batman Returns", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -5649,7 +5272,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Batman the dark knight returns: Part 1", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -5657,7 +5280,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Batman the dark knight returns: Part 2", "_federation": { - "indexUid": "batman", + "indexUid": "batman-[uuid]", "queriesPosition": 1, "weightedRankingScore": 1.0 } @@ -5665,7 +5288,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Captain Marvel", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -5673,7 +5296,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Captain Marvel", "_federation": { - "indexUid": "movies-2", + "indexUid": "movies_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -5681,7 +5304,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Escape Room", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -5689,7 +5312,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Escape Room", "_federation": { - "indexUid": "movies-2", + "indexUid": "movies_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -5697,7 +5320,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Gläss", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -5705,7 +5328,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Gläss", "_federation": { - "indexUid": "movies-2", + "indexUid": "movies_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -5713,7 +5336,7 @@ async fn federation_inconsistent_merge_order() { { "title": "How to Train Your Dragon: The Hidden World", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -5721,7 +5344,7 @@ async fn federation_inconsistent_merge_order() { { "title": "How to Train Your Dragon: The Hidden World", "_federation": { - "indexUid": "movies-2", + "indexUid": "movies_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } @@ -5729,7 +5352,7 @@ async fn federation_inconsistent_merge_order() { { "title": "Shazam!", "_federation": { - "indexUid": "movies", + "indexUid": "movies-[uuid]", "queriesPosition": 0, "weightedRankingScore": 1.0 } @@ -5737,13 +5360,13 @@ async fn federation_inconsistent_merge_order() { { "title": "Shazam!", "_federation": { - "indexUid": "movies-2", + "indexUid": "movies_2-[uuid]", "queriesPosition": 2, "weightedRankingScore": 1.0 } } ], - "processingTimeMs": "[time]", + "processingTimeMs": "[duration]", "limit": 20, "offset": 0, "estimatedTotalHits": 15,