2023-06-22 14:42:52 +02:00
|
|
|
use meili_snap::{json_string, snapshot};
|
2023-06-07 18:49:17 +02:00
|
|
|
use once_cell::sync::Lazy;
|
|
|
|
|
|
|
|
use crate::common::index::Index;
|
2023-09-11 16:50:53 +02:00
|
|
|
use crate::common::{Server, Value};
|
|
|
|
use crate::json;
|
2023-06-07 18:49:17 +02:00
|
|
|
|
|
|
|
async fn index_with_documents<'a>(server: &'a Server, documents: &Value) -> Index<'a> {
|
|
|
|
let index = server.index("test");
|
|
|
|
|
|
|
|
index.add_documents(documents.clone(), None).await;
|
|
|
|
index.wait_task(0).await;
|
|
|
|
index
|
|
|
|
}
|
|
|
|
|
|
|
|
static SIMPLE_SEARCH_DOCUMENTS: Lazy<Value> = Lazy::new(|| {
|
|
|
|
json!([
|
|
|
|
{
|
|
|
|
"title": "Shazam!",
|
|
|
|
"desc": "a Captain Marvel ersatz",
|
|
|
|
"id": "1",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"title": "Captain Planet",
|
|
|
|
"desc": "He's not part of the Marvel Cinematic Universe",
|
|
|
|
"id": "2",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"title": "Captain Marvel",
|
|
|
|
"desc": "a Shazam ersatz",
|
|
|
|
"id": "3",
|
|
|
|
}])
|
|
|
|
});
|
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn simple_search_on_title() {
|
|
|
|
let server = Server::new().await;
|
|
|
|
let index = index_with_documents(&server, &SIMPLE_SEARCH_DOCUMENTS).await;
|
|
|
|
|
|
|
|
// simple search should return 2 documents (ids: 2 and 3).
|
|
|
|
index
|
|
|
|
.search(
|
2023-06-20 10:00:35 +02:00
|
|
|
json!({"q": "Captain Marvel", "attributesToSearchOn": ["title"]}),
|
2023-06-07 18:49:17 +02:00
|
|
|
|response, code| {
|
2023-06-22 14:42:52 +02:00
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(response["hits"].as_array().unwrap().len(), @"2");
|
2023-06-07 18:49:17 +02:00
|
|
|
},
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
2023-07-12 10:36:55 +02:00
|
|
|
#[actix_rt::test]
|
|
|
|
async fn search_no_searchable_attribute_set() {
|
|
|
|
let server = Server::new().await;
|
|
|
|
let index = index_with_documents(&server, &SIMPLE_SEARCH_DOCUMENTS).await;
|
|
|
|
|
|
|
|
index
|
|
|
|
.search(
|
|
|
|
json!({"q": "Captain Marvel", "attributesToSearchOn": ["unknown"]}),
|
|
|
|
|response, code| {
|
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(response["hits"].as_array().unwrap().len(), @"0");
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
|
|
|
|
index.update_settings_searchable_attributes(json!(["*"])).await;
|
|
|
|
index.wait_task(1).await;
|
|
|
|
|
|
|
|
index
|
|
|
|
.search(
|
|
|
|
json!({"q": "Captain Marvel", "attributesToSearchOn": ["unknown"]}),
|
|
|
|
|response, code| {
|
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(response["hits"].as_array().unwrap().len(), @"0");
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
|
2023-07-12 16:06:15 +02:00
|
|
|
index.update_settings_searchable_attributes(json!(["*"])).await;
|
2023-07-12 10:36:55 +02:00
|
|
|
index.wait_task(2).await;
|
|
|
|
|
|
|
|
index
|
|
|
|
.search(
|
2023-07-12 16:06:15 +02:00
|
|
|
json!({"q": "Captain Marvel", "attributesToSearchOn": ["unknown", "title"]}),
|
2023-07-12 10:36:55 +02:00
|
|
|
|response, code| {
|
|
|
|
snapshot!(code, @"200 OK");
|
2023-07-12 16:06:15 +02:00
|
|
|
snapshot!(response["hits"].as_array().unwrap().len(), @"2");
|
2023-07-12 10:36:55 +02:00
|
|
|
},
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn search_on_all_attributes() {
|
|
|
|
let server = Server::new().await;
|
|
|
|
let index = index_with_documents(&server, &SIMPLE_SEARCH_DOCUMENTS).await;
|
|
|
|
|
|
|
|
index
|
|
|
|
.search(json!({"q": "Captain Marvel", "attributesToSearchOn": ["*"]}), |response, code| {
|
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(response["hits"].as_array().unwrap().len(), @"3");
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn search_on_all_attributes_restricted_set() {
|
|
|
|
let server = Server::new().await;
|
|
|
|
let index = index_with_documents(&server, &SIMPLE_SEARCH_DOCUMENTS).await;
|
|
|
|
index.update_settings_searchable_attributes(json!(["title"])).await;
|
|
|
|
index.wait_task(1).await;
|
|
|
|
|
|
|
|
index
|
|
|
|
.search(json!({"q": "Captain Marvel", "attributesToSearchOn": ["*"]}), |response, code| {
|
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(response["hits"].as_array().unwrap().len(), @"2");
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
2023-06-07 18:49:17 +02:00
|
|
|
#[actix_rt::test]
|
|
|
|
async fn simple_prefix_search_on_title() {
|
|
|
|
let server = Server::new().await;
|
|
|
|
let index = index_with_documents(&server, &SIMPLE_SEARCH_DOCUMENTS).await;
|
|
|
|
|
|
|
|
// simple search should return 2 documents (ids: 2 and 3).
|
|
|
|
index
|
2023-06-20 10:00:35 +02:00
|
|
|
.search(json!({"q": "Captain Mar", "attributesToSearchOn": ["title"]}), |response, code| {
|
2023-06-22 14:42:52 +02:00
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(response["hits"].as_array().unwrap().len(), @"2");
|
2023-06-20 10:00:35 +02:00
|
|
|
})
|
2023-06-07 18:49:17 +02:00
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn simple_search_on_title_matching_strategy_all() {
|
|
|
|
let server = Server::new().await;
|
|
|
|
let index = index_with_documents(&server, &SIMPLE_SEARCH_DOCUMENTS).await;
|
|
|
|
// simple search matching strategy all should only return 1 document (ids: 2).
|
|
|
|
index
|
2023-06-20 10:00:35 +02:00
|
|
|
.search(json!({"q": "Captain Marvel", "attributesToSearchOn": ["title"], "matchingStrategy": "all"}), |response, code| {
|
2023-06-22 14:42:52 +02:00
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(response["hits"].as_array().unwrap().len(), @"1");
|
2023-06-07 18:49:17 +02:00
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn simple_search_on_no_field() {
|
|
|
|
let server = Server::new().await;
|
|
|
|
let index = index_with_documents(&server, &SIMPLE_SEARCH_DOCUMENTS).await;
|
|
|
|
// simple search on no field shouldn't return any document.
|
|
|
|
index
|
2023-06-20 10:00:35 +02:00
|
|
|
.search(json!({"q": "Captain Marvel", "attributesToSearchOn": []}), |response, code| {
|
2023-06-22 14:42:52 +02:00
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(response["hits"].as_array().unwrap().len(), @"0");
|
2023-06-20 10:00:35 +02:00
|
|
|
})
|
2023-06-07 18:49:17 +02:00
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn word_ranking_rule_order() {
|
|
|
|
let server = Server::new().await;
|
|
|
|
let index = index_with_documents(&server, &SIMPLE_SEARCH_DOCUMENTS).await;
|
|
|
|
|
|
|
|
// Document 3 should appear before document 2.
|
|
|
|
index
|
|
|
|
.search(
|
2023-06-20 10:00:35 +02:00
|
|
|
json!({"q": "Captain Marvel", "attributesToSearchOn": ["title"], "attributesToRetrieve": ["id"]}),
|
2023-06-07 18:49:17 +02:00
|
|
|
|response, code| {
|
2023-06-22 14:42:52 +02:00
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(json_string!(response["hits"]),
|
|
|
|
@r###"
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"id": "3"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "2"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
"###
|
2023-06-07 18:49:17 +02:00
|
|
|
);
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn word_ranking_rule_order_exact_words() {
|
|
|
|
let server = Server::new().await;
|
|
|
|
let index = index_with_documents(&server, &SIMPLE_SEARCH_DOCUMENTS).await;
|
|
|
|
index.update_settings_typo_tolerance(json!({"disableOnWords": ["Captain", "Marvel"]})).await;
|
|
|
|
index.wait_task(1).await;
|
|
|
|
|
|
|
|
// simple search should return 2 documents (ids: 2 and 3).
|
|
|
|
index
|
|
|
|
.search(
|
2023-06-20 10:00:35 +02:00
|
|
|
json!({"q": "Captain Marvel", "attributesToSearchOn": ["title"], "attributesToRetrieve": ["id"]}),
|
2023-06-07 18:49:17 +02:00
|
|
|
|response, code| {
|
2023-06-22 14:42:52 +02:00
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(json_string!(response["hits"]),
|
|
|
|
@r###"
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"id": "3"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "2"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
"###
|
2023-06-07 18:49:17 +02:00
|
|
|
);
|
|
|
|
},
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn typo_ranking_rule_order() {
|
|
|
|
let server = Server::new().await;
|
|
|
|
let index = index_with_documents(
|
|
|
|
&server,
|
|
|
|
&json!([
|
|
|
|
{
|
|
|
|
"title": "Capitain Marivel",
|
|
|
|
"desc": "Captain Marvel",
|
|
|
|
"id": "1",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"title": "Captain Marivel",
|
|
|
|
"desc": "a Shazam ersatz",
|
|
|
|
"id": "2",
|
|
|
|
}]),
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
|
|
|
|
// Document 2 should appear before document 1.
|
|
|
|
index
|
2023-06-20 10:00:35 +02:00
|
|
|
.search(json!({"q": "Captain Marvel", "attributesToSearchOn": ["title"], "attributesToRetrieve": ["id"]}), |response, code| {
|
2023-06-22 14:42:52 +02:00
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(json_string!(response["hits"]),
|
|
|
|
@r###"
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"id": "2"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "1"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
"###
|
2023-06-07 18:49:17 +02:00
|
|
|
);
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn attributes_ranking_rule_order() {
|
|
|
|
let server = Server::new().await;
|
|
|
|
let index = index_with_documents(
|
|
|
|
&server,
|
|
|
|
&json!([
|
|
|
|
{
|
|
|
|
"title": "Captain Marvel",
|
|
|
|
"desc": "a Shazam ersatz",
|
|
|
|
"footer": "The story of Captain Marvel",
|
|
|
|
"id": "1",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"title": "The Avengers",
|
|
|
|
"desc": "Captain Marvel is far from the earth",
|
|
|
|
"footer": "A super hero team",
|
|
|
|
"id": "2",
|
|
|
|
}]),
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
|
|
|
|
// Document 2 should appear before document 1.
|
|
|
|
index
|
2023-06-20 10:00:35 +02:00
|
|
|
.search(json!({"q": "Captain Marvel", "attributesToSearchOn": ["desc", "footer"], "attributesToRetrieve": ["id"]}), |response, code| {
|
2023-06-22 14:42:52 +02:00
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(json_string!(response["hits"]),
|
|
|
|
@r###"
|
|
|
|
[
|
|
|
|
{
|
2024-05-16 01:06:33 +02:00
|
|
|
"id": "1"
|
2023-06-22 14:42:52 +02:00
|
|
|
},
|
|
|
|
{
|
2024-05-16 01:06:33 +02:00
|
|
|
"id": "2"
|
2023-06-22 14:42:52 +02:00
|
|
|
}
|
|
|
|
]
|
|
|
|
"###
|
2023-06-07 18:49:17 +02:00
|
|
|
);
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn exactness_ranking_rule_order() {
|
|
|
|
let server = Server::new().await;
|
|
|
|
let index = index_with_documents(
|
|
|
|
&server,
|
|
|
|
&json!([
|
|
|
|
{
|
|
|
|
"title": "Captain Marvel",
|
|
|
|
"desc": "Captain Marivel",
|
|
|
|
"id": "1",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"title": "Captain Marvel",
|
2023-07-12 16:47:30 +02:00
|
|
|
"desc": "Captain the Marvel",
|
2023-06-07 18:49:17 +02:00
|
|
|
"id": "2",
|
|
|
|
}]),
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
|
|
|
|
// Document 2 should appear before document 1.
|
|
|
|
index
|
2023-06-20 10:00:35 +02:00
|
|
|
.search(json!({"q": "Captain Marvel", "attributesToRetrieve": ["id"], "attributesToSearchOn": ["desc"]}), |response, code| {
|
2023-06-22 14:42:52 +02:00
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(json_string!(response["hits"]),
|
|
|
|
@r###"
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"id": "2"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "1"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
"###
|
2023-06-07 18:49:17 +02:00
|
|
|
);
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}
|
2023-11-27 11:03:16 +01:00
|
|
|
|
|
|
|
#[actix_rt::test]
|
|
|
|
async fn search_on_exact_field() {
|
|
|
|
let server = Server::new().await;
|
|
|
|
let index = index_with_documents(
|
|
|
|
&server,
|
|
|
|
&json!([
|
|
|
|
{
|
|
|
|
"title": "Captain Marvel",
|
|
|
|
"exact": "Captain Marivel",
|
|
|
|
"id": "1",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"title": "Captain Marivel",
|
|
|
|
"exact": "Captain the Marvel",
|
|
|
|
"id": "2",
|
|
|
|
}]),
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
|
|
|
|
let (response, code) =
|
|
|
|
index.update_settings_typo_tolerance(json!({ "disableOnAttributes": ["exact"] })).await;
|
|
|
|
assert_eq!(202, code, "{:?}", response);
|
|
|
|
index.wait_task(1).await;
|
|
|
|
// Searching on an exact attribute should only return the document matching without typo.
|
|
|
|
index
|
|
|
|
.search(json!({"q": "Marvel", "attributesToSearchOn": ["exact"]}), |response, code| {
|
|
|
|
snapshot!(code, @"200 OK");
|
|
|
|
snapshot!(response["hits"].as_array().unwrap().len(), @"1");
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}
|