Skip to content

Commit

Permalink
Merge #620
Browse files Browse the repository at this point in the history
620: Add support for language settings and search parameter r=ManyTheFish a=necocen

# Pull Request

## Related issue
Fixes #611 

## What does this PR do?
- Added `locales` parameter and `with_locales` method to `SearchQuery` struct
- Added localized attributes related methods to `Index` and `Settings`
- Added tests
- Added code samples
    - search_parameter_reference_locales_1
    - get_localized_attribute_settings_1
    - update_localized_attribute_settings_1
    - reset_localized_attribute_settings_1

## PR checklist
Please check if your PR fulfills the following requirements:
- [x] Does this PR fix an existing issue, or have you listed the changes applied in the PR description (and why they are needed)?
- [x] Have you read the contributing guidelines?
- [x] Have you made sure that the title is accurate and descriptive of the changes?

Thank you so much for contributing to Meilisearch!


Co-authored-by: necocen <necocen@gmail.com>
  • Loading branch information
meili-bors[bot] and necocen authored Dec 3, 2024
2 parents 38309ef + f74e472 commit a641093
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 0 deletions.
31 changes: 31 additions & 0 deletions .code-samples.meilisearch.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1739,3 +1739,34 @@ search_parameter_reference_ranking_score_threshold_1: |-
.execute()
.await
.unwrap();
search_parameter_reference_locales_1: |-
let res = client
.index("books")
.search()
.with_query("進撃の巨人")
.with_locales(&["jpn"])
.execute()
.await
.unwrap();
get_localized_attribute_settings_1: |-
let localized_attributes: Option<Vec<LocalizedAttributes>> = client
.index("books")
.get_localized_attributes()
.await
.unwrap();
update_localized_attribute_settings_1: |-
let localized_attributes = vec![LocalizedAttributes {
locales: vec!["jpn".to_string()],
attribute_patterns: vec!["*_ja".to_string()],
}];
let task: TaskInfo = client
.index("books")
.set_localized_attributes(&localizced_attributes)
.await
.unwrap();
reset_localized_attribute_settings_1: |-
let task: TaskInfo = client
.index("books")
.reset_localized_attributes()
.await
.unwrap();
21 changes: 21 additions & 0 deletions src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,10 @@ pub struct SearchQuery<'a, Http: HttpClient> {
#[serde(skip_serializing_if = "Option::is_none")]
pub ranking_score_threshold: Option<f64>,

/// Defines the language of the search query.
#[serde(skip_serializing_if = "Option::is_none")]
pub locales: Option<&'a [&'a str]>,

#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) index_uid: Option<&'a str>,
}
Expand Down Expand Up @@ -377,6 +381,7 @@ impl<'a, Http: HttpClient> SearchQuery<'a, Http> {
index_uid: None,
distinct: None,
ranking_score_threshold: None,
locales: None,
}
}
pub fn with_query<'b>(&'b mut self, query: &'a str) -> &'b mut SearchQuery<'a, Http> {
Expand Down Expand Up @@ -580,6 +585,10 @@ impl<'a, Http: HttpClient> SearchQuery<'a, Http> {
self.ranking_score_threshold = Some(ranking_score_threshold);
self
}
pub fn with_locales<'b>(&'b mut self, locales: &'a [&'a str]) -> &'b mut SearchQuery<'a, Http> {
self.locales = Some(locales);
self
}
pub fn build(&mut self) -> SearchQuery<'a, Http> {
self.clone()
}
Expand Down Expand Up @@ -1161,6 +1170,18 @@ mod tests {
Ok(())
}

#[meilisearch_test]
async fn test_query_locales(client: Client, index: Index) -> Result<(), Error> {
setup_test_index(&client, &index).await?;

let mut query = SearchQuery::new(&index);
query.with_query("Harry Styles");
query.with_locales(&["eng"]);
let results: SearchResults<Document> = index.execute_query(&query).await.unwrap();
assert_eq!(results.hits.len(), 7);
Ok(())
}

#[meilisearch_test]
async fn test_phrase_search(client: Client, index: Index) -> Result<(), Error> {
setup_test_index(&client, &index).await?;
Expand Down
172 changes: 172 additions & 0 deletions src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ pub struct FacetingSettings {
pub max_values_per_facet: usize,
}

#[derive(Serialize, Deserialize, Default, Debug, Clone, Eq, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct LocalizedAttributes {
pub locales: Vec<String>,
pub attribute_patterns: Vec<String>,
}

/// Struct reprensenting a set of settings.
///
/// You can build this struct using the builder syntax.
Expand Down Expand Up @@ -112,6 +119,9 @@ pub struct Settings {
/// Remove tokens from Meilisearch's default [list of word separators](https://www.meilisearch.com/docs/learn/engine/datatypes#string).
#[serde(skip_serializing_if = "Option::is_none")]
pub non_separator_tokens: Option<Vec<String>>,
/// LocalizedAttributes settings.
#[serde(skip_serializing_if = "Option::is_none")]
pub localized_attributes: Option<Vec<LocalizedAttributes>>,
}

#[allow(missing_docs)]
Expand Down Expand Up @@ -336,6 +346,17 @@ impl Settings {
..self
}
}

#[must_use]
pub fn with_localized_attributes(
self,
localized_attributes: impl IntoIterator<Item = LocalizedAttributes>,
) -> Settings {
Settings {
localized_attributes: Some(localized_attributes.into_iter().collect()),
..self
}
}
}

impl<Http: HttpClient> Index<Http> {
Expand Down Expand Up @@ -900,6 +921,39 @@ impl<Http: HttpClient> Index<Http> {
.await
}

/// Get [localized attributes](https://www.meilisearch.com/docs/reference/api/settings#localized-attributes-object) settings of the [Index].
///
/// ```
/// # use meilisearch_sdk::{client::*, indexes::*, settings::LocalizedAttributes};
/// #
/// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
/// #
/// # tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap().block_on(async {
/// let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY)).unwrap();
/// # client.create_index("get_localized_attributes", None).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// let index = client.index("get_localized_attributes");
///
/// let localized_attributes = index.get_localized_attributes().await.unwrap();
/// # index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// # });
/// ```
pub async fn get_localized_attributes(
&self,
) -> Result<Option<Vec<LocalizedAttributes>>, Error> {
self.client
.http_client
.request::<(), (), Option<Vec<LocalizedAttributes>>>(
&format!(
"{}/indexes/{}/settings/localized-attributes",
self.client.host, self.uid
),
Method::Get { query: () },
200,
)
.await
}

/// Update [settings](../settings/struct.Settings) of the [Index].
///
/// Updates in the settings are partial. This means that any parameters corresponding to a `None` value will be left unchanged.
Expand Down Expand Up @@ -1611,6 +1665,50 @@ impl<Http: HttpClient> Index<Http> {
.await
}

/// Update [localized attributes](https://www.meilisearch.com/docs/reference/api/settings#localized-attributes-object) settings of the [Index].
///
/// # Example
///
/// ```
/// # use meilisearch_sdk::{client::*, indexes::*, settings::Settings, settings::{LocalizedAttributes}};
/// #
/// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
/// #
/// # tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap().block_on(async {
/// let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY)).unwrap();
/// # client.create_index("set_localized_attributes", None).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// let mut index = client.index("set_localized_attributes");
///
/// let localized_attributes = vec![LocalizedAttributes {
/// locales: vec!["jpn".to_string()],
/// attribute_patterns: vec!["*_ja".to_string()],
/// }];
///
/// let task = index.set_localized_attributes(&localized_attributes).await.unwrap();
/// # index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// # });
/// ```
pub async fn set_localized_attributes(
&self,
localized_attributes: &Vec<LocalizedAttributes>,
) -> Result<TaskInfo, Error> {
self.client
.http_client
.request::<(), &Vec<LocalizedAttributes>, TaskInfo>(
&format!(
"{}/indexes/{}/settings/localized-attributes",
self.client.host, self.uid
),
Method::Put {
query: (),
body: localized_attributes,
},
202,
)
.await
}

/// Reset [Settings] of the [Index].
///
/// All settings will be reset to their [default value](https://www.meilisearch.com/docs/reference/api/settings#reset-settings).
Expand Down Expand Up @@ -2172,6 +2270,39 @@ impl<Http: HttpClient> Index<Http> {
)
.await
}

/// Reset [localized attributes](https://www.meilisearch.com/docs/reference/api/settings#localized-attributes-object) settings of the [Index].
///
/// # Example
///
/// ```
/// # use meilisearch_sdk::{client::*, indexes::*, settings::Settings};
/// #
/// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
/// #
/// # tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap().block_on(async {
/// let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY)).unwrap();
/// # client.create_index("reset_localized_attributes", None).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// let index = client.index("reset_localized_attributes");
///
/// let task = index.reset_localized_attributes().await.unwrap();
/// # index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// # });
/// ```
pub async fn reset_localized_attributes(&self) -> Result<TaskInfo, Error> {
self.client
.http_client
.request::<(), (), TaskInfo>(
&format!(
"{}/indexes/{}/settings/localized-attributes",
self.client.host, self.uid
),
Method::Delete { query: () },
202,
)
.await
}
}

#[cfg(test)]
Expand Down Expand Up @@ -2522,4 +2653,45 @@ mod tests {
let res = index.get_dictionary().await.unwrap();
assert_eq!(separator, res);
}

#[meilisearch_test]
async fn test_get_localized_attributes(index: Index) {
let res = index.get_localized_attributes().await.unwrap();
assert_eq!(None, res);
}

#[meilisearch_test]
async fn test_set_localized_attributes(client: Client, index: Index) {
let localized_attributes = vec![LocalizedAttributes {
locales: vec!["jpn".to_string()],
attribute_patterns: vec!["*_ja".to_string()],
}];
let task_info = index
.set_localized_attributes(&localized_attributes)
.await
.unwrap();
client.wait_for_task(task_info, None, None).await.unwrap();

let res = index.get_localized_attributes().await.unwrap();
assert_eq!(Some(localized_attributes), res);
}

#[meilisearch_test]
async fn test_reset_localized_attributes(client: Client, index: Index) {
let localized_attributes = vec![LocalizedAttributes {
locales: vec!["jpn".to_string()],
attribute_patterns: vec!["*_ja".to_string()],
}];
let task_info = index
.set_localized_attributes(&localized_attributes)
.await
.unwrap();
client.wait_for_task(task_info, None, None).await.unwrap();

let reset_task = index.reset_localized_attributes().await.unwrap();
client.wait_for_task(reset_task, None, None).await.unwrap();

let res = index.get_localized_attributes().await.unwrap();
assert_eq!(None, res);
}
}

0 comments on commit a641093

Please sign in to comment.