124: enable distinct r=MarinPostma a=MarinPostma



Co-authored-by: mpostma <postma.marin@protonmail.com>
Co-authored-by: Marin Postma <postma.marin@protonmail.com>
This commit is contained in:
bors[bot] 2021-04-20 13:52:00 +00:00 committed by GitHub
commit 63d443deb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 777 additions and 751 deletions

File diff suppressed because it is too large Load Diff

View File

@ -84,6 +84,7 @@ version = "0.18.1"
actix-rt = "2.1.0"
assert-json-diff = { branch = "master", git = "https://github.com/qdequele/assert-json-diff" }
mockall = "0.9.1"
paste = "1.0.5"
serde_url_params = "0.2.0"
tempdir = "0.3.7"
urlencoding = "1.1.1"

View File

@ -59,6 +59,9 @@ impl Index {
})
.transpose()?
.unwrap_or_else(BTreeSet::new);
let distinct_attribute = self
.distinct_attribute(&txn)?
.map(String::from);
Ok(Settings {
displayed_attributes: Some(Some(displayed_attributes)),
@ -66,6 +69,7 @@ impl Index {
attributes_for_faceting: Some(Some(faceted_attributes)),
ranking_rules: Some(Some(criteria)),
stop_words: Some(Some(stop_words)),
distinct_attribute: Some(distinct_attribute),
})
}

View File

@ -43,13 +43,18 @@ pub struct Settings {
skip_serializing_if = "Option::is_none"
)]
pub ranking_rules: Option<Option<Vec<String>>>,
#[serde(
default,
deserialize_with = "deserialize_some",
skip_serializing_if = "Option::is_none"
)]
pub stop_words: Option<Option<BTreeSet<String>>>,
#[serde(
default,
deserialize_with = "deserialize_some",
skip_serializing_if = "Option::is_none"
)]
pub distinct_attribute: Option<Option<String>>,
}
impl Settings {
@ -60,6 +65,7 @@ impl Settings {
attributes_for_faceting: Some(None),
ranking_rules: Some(None),
stop_words: Some(None),
distinct_attribute: Some(None),
}
}
}
@ -145,7 +151,6 @@ impl Index {
let mut wtxn = self.write_txn()?;
let mut builder = update_builder.settings(&mut wtxn, self);
// We transpose the settings JSON struct into a real setting update.
if let Some(ref names) = settings.searchable_attributes {
match names {
Some(names) => builder.set_searchable_fields(names.clone()),
@ -153,7 +158,6 @@ impl Index {
}
}
// We transpose the settings JSON struct into a real setting update.
if let Some(ref names) = settings.displayed_attributes {
match names {
Some(names) => builder.set_displayed_fields(names.clone()),
@ -161,13 +165,11 @@ impl Index {
}
}
// We transpose the settings JSON struct into a real setting update.
if let Some(ref facet_types) = settings.attributes_for_faceting {
let facet_types = facet_types.clone().unwrap_or_else(HashMap::new);
builder.set_faceted_fields(facet_types);
}
// We transpose the settings JSON struct into a real setting update.
if let Some(ref criteria) = settings.ranking_rules {
match criteria {
Some(criteria) => builder.set_criteria(criteria.clone()),
@ -175,7 +177,6 @@ impl Index {
}
}
// We transpose the settings JSON struct into a real setting update.
if let Some(ref stop_words) = settings.stop_words {
match stop_words {
Some(stop_words) => builder.set_stop_words(stop_words.clone()),
@ -183,6 +184,13 @@ impl Index {
}
}
if let Some(ref distinct_attribute) = settings.distinct_attribute {
match distinct_attribute {
Some(attr) => builder.set_distinct_attribute(attr.clone()),
None => builder.reset_distinct_attribute(),
}
}
let result = builder
.execute(|indexing_step, update_id| info!("update {}: {:?}", update_id, indexing_step));

View File

@ -97,11 +97,11 @@ make_setting_route!(
stop_words
);
//make_setting_route!(
//"/indexes/{index_uid}/settings/distinct-attribute",
//String,
//distinct_attribute
//);
make_setting_route!(
"/indexes/{index_uid}/settings/distinct-attribute",
String,
distinct_attribute
);
//make_setting_route!(
//"/indexes/{index_uid}/settings/ranking-rules",
@ -129,6 +129,7 @@ create_services!(
attributes_for_faceting,
displayed_attributes,
searchable_attributes,
distinct_attribute,
stop_words
);

View File

@ -1,16 +1,34 @@
use std::time::Duration;
use actix_web::http::StatusCode;
use paste::paste;
use serde_json::{json, Value};
use tokio::time::sleep;
use super::service::Service;
macro_rules! make_settings_test_routes {
($($name:ident),+) => {
$(paste! {
pub async fn [<update_$name>](&self, value: Value) -> (Value, StatusCode) {
let url = format!("/indexes/{}/settings/{}", self.uid, stringify!($name).replace("_", "-"));
self.service.post(url, value).await
}
pub async fn [<get_$name>](&self) -> (Value, StatusCode) {
let url = format!("/indexes/{}/settings/{}", self.uid, stringify!($name).replace("_", "-"));
self.service.get(url).await
}
})*
};
}
pub struct Index<'a> {
pub uid: String,
pub service: &'a Service,
}
#[allow(dead_code)]
impl Index<'_> {
pub async fn get(&self) -> (Value, StatusCode) {
let url = format!("/indexes/{}", self.uid);
@ -166,8 +184,13 @@ impl Index<'_> {
let url = format!("/indexes/{}/stats", self.uid);
self.service.get(url).await
}
make_settings_test_routes!(
distinct_attribute
);
}
pub struct GetDocumentOptions;
#[derive(Debug, Default)]

View File

@ -0,0 +1,44 @@
use crate::common::Server;
use serde_json::json;
#[actix_rt::test]
async fn set_and_reset_distinct_attribute() {
let server = Server::new().await;
let index = server.index("test");
let (_response, _code) = index.update_settings(json!({ "distinctAttribute": "test"})).await;
index.wait_update_id(0).await;
let (response, _) = index.settings().await;
assert_eq!(response["distinctAttribute"], "test");
index.update_settings(json!({ "distinctAttribute": null })).await;
index.wait_update_id(1).await;
let (response, _) = index.settings().await;
assert_eq!(response["distinctAttribute"], json!(null));
}
#[actix_rt::test]
async fn set_and_reset_distinct_attribute_with_dedicated_route() {
let server = Server::new().await;
let index = server.index("test");
let (_response, _code) = index.update_distinct_attribute(json!("test")).await;
index.wait_update_id(0).await;
let (response, _) = index.get_distinct_attribute().await;
assert_eq!(response, "test");
index.update_distinct_attribute(json!(null)).await;
index.wait_update_id(1).await;
let (response, _) = index.get_distinct_attribute().await;
assert_eq!(response, json!(null));
}

View File

@ -16,10 +16,11 @@ async fn get_settings() {
let (response, code) = index.settings().await;
assert_eq!(code, 200);
let settings = response.as_object().unwrap();
assert_eq!(settings.keys().len(), 5);
assert_eq!(settings.keys().len(), 6);
assert_eq!(settings["displayedAttributes"], json!(["*"]));
assert_eq!(settings["searchableAttributes"], json!(["*"]));
assert_eq!(settings["attributesForFaceting"], json!({}));
assert_eq!(settings["distinctAttribute"], json!(null));
assert_eq!(
settings["rankingRules"],
json!([

View File

@ -1 +1,2 @@
mod get_settings;
mod distinct;