Skip to content

Commit

Permalink
Added the same settings operations found in meilisearch/meilisearch-p…
Browse files Browse the repository at this point in the history
  • Loading branch information
CommanderStorm committed Mar 11, 2024
1 parent e21d8a9 commit 8ffb555
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,7 @@ mod tests {
.expect("could not enable the vector store");
assert_eq!(features.vector_store, true);
let embedder_setting = crate::Embedder::HuggingFace(crate::HuggingFaceEmbedderSettings {
model: "BAAI/bge-base-en-v1.5".into(),
model: Some("BAAI/bge-base-en-v1.5".into()),
revision: None,
document_template: Some("{{ doc.value }}".into()),
});
Expand Down
137 changes: 132 additions & 5 deletions src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ pub enum Embedder {
#[serde(rename_all = "camelCase")]
pub struct HuggingFaceEmbedderSettings {
/// the BERT embedding model you want to use from HuggingFace
/// Example: `bge-base-en-v1.5`
pub model: String,
/// Defaults to `BAAI/bge-base-en-v1.5`
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub revision: Option<String>,
/// if present, document_template must be a [Liquid template](https://shopify.github.io/liquid/).
Expand All @@ -75,9 +76,12 @@ pub struct OpenapiEmbedderSettings {
/// Use [tier 2 keys](https://platform.openai.com/docs/guides/rate-limits/usage-tiers?context=tier-two) or above for optimal performance.
pub api_key: String,
/// The openapi model name
/// Example: `text-embedding-ada-002`
pub model: String,
pub dimensions: usize,
/// Default: `text-embedding-ada-002`
#[serde(skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
/// Defaults to the default for said model name
#[serde(skip_serializing_if = "Option::is_none")]
pub dimensions: Option<usize>,
/// if present, document_template must be a [Liquid template](https://shopify.github.io/liquid/).
/// Use `{{ doc.attribute }}` to access document field values.
/// Meilisearch also exposes a `{{ fields }}` array containing one object per document field, which you may access with `{{ field.name }}` and `{{ field.value }}`.
Expand Down Expand Up @@ -820,6 +824,49 @@ impl Index {
.await
}

/// Get [embedders](https://www.meilisearch.com/docs/learn/experimental/vector_search) of the [Index].
///
/// ```
/// # use std::collections::HashMap;
/// # use std::string::String;
/// use meilisearch_sdk::{client::*, CustomEmbedderSettings, Embedder, ExperimentalFeatures, indexes::*, 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");
/// #
/// # futures::executor::block_on(async move {
/// let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY));
/// # client.create_index("get_embedders", None).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// let index = client.index("get_embedders");
///
/// # let mut features = ExperimentalFeatures::new(&client);
/// # features.set_vector_store(true);
/// # let res = features.update().await.unwrap();
/// #
/// # let t=index.set_settings(&Settings{
/// # embedders:Some(HashMap::from([(String::from("default"),Embedder::UserProvided(CustomEmbedderSettings{dimensions:1}))])),
/// # ..Settings::default()
/// # }).await.unwrap();
/// # t.wait_for_completion(&client, None, None).await.unwrap();
/// let embedders = index.get_embedders().await.unwrap();
/// # index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// # });
/// ```
#[cfg(feature = "experimental-vector-search")]
pub async fn get_embedders(&self) -> Result<HashMap<String, Embedder>, Error> {
request::<(), (), Option<HashMap<String, Embedder>>>(
&format!(
"{}/indexes/{}/settings/embedders",
self.client.host, self.uid
),
self.client.get_api_key(),
Method::Get { query: () },
200,
)
.await
.map(|r| r.unwrap_or_default())
}

/// 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 @@ -1847,6 +1894,39 @@ impl Index {
)
.await
}

/// Reset [embedders](https://www.meilisearch.com/docs/learn/experimental/vector_search) 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");
/// #
/// # futures::executor::block_on(async move {
/// # let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY));
/// # client.create_index("reset_embedders", None).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// let mut index = client.index("reset_embedders");
///
/// let task = index.reset_embedders().await.unwrap();
/// # index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// # });
/// ```
#[cfg(feature = "experimental-vector-search")]
pub async fn reset_embedders(&self) -> Result<TaskInfo, Error> {
request::<(), (), TaskInfo>(
&format!(
"{}/indexes/{}/settings/embedders",
self.client.host, self.uid
),
self.client.get_api_key(),
Method::Delete { query: () },
202,
)
.await
}
}

#[cfg(test)]
Expand Down Expand Up @@ -1882,6 +1962,14 @@ mod tests {
assert_eq!(faceting, res);
}

#[cfg(feature = "experimental-vector-search")]
#[meilisearch_test]
async fn test_get_embeddings(index: Index) {
let res = index.get_embedders().await.unwrap();

assert_eq!(HashMap::new(), res);
}

#[meilisearch_test]
async fn test_set_faceting(client: Client, index: Index) {
let faceting = FacetingSettings {
Expand All @@ -1908,6 +1996,23 @@ mod tests {
assert_eq!(faceting, res);
}

#[cfg(feature = "experimental-vector-search")]
#[meilisearch_test]
async fn test_reset_embedders(client: Client, index: Index) {
let features = crate::ExperimentalFeatures::new(&client)
.set_vector_store(true)
.update()
.await
.expect("could not enable the vector store");
assert_eq!(features.vector_store, true);
let task_info = index.reset_embedders().await.unwrap();
client.wait_for_task(task_info, None, None).await.unwrap();

let res = index.get_embedders().await.unwrap();

assert_eq!(HashMap::new(), res);
}

#[meilisearch_test]
async fn test_get_dictionary(index: Index) {
let dictionary: Vec<String> = vec![];
Expand Down Expand Up @@ -2084,6 +2189,28 @@ mod tests {
assert_eq!(expected, res);
}

#[cfg(feature = "experimental-vector-search")]
#[meilisearch_test]
async fn test_set_embedding_settings(client: Client, index: Index) {
let features = crate::ExperimentalFeatures::new(&client)
.set_vector_store(true)
.update()
.await
.expect("could not enable the vector store");
assert_eq!(features.vector_store, true);

let custom_embedder = Embedder::UserProvided(CustomEmbedderSettings { dimensions: 2 });
let embeddings = HashMap::from([("default".into(), custom_embedder)]);
let settings = Settings::new().with_embedders(embeddings.clone());

let task_info = index.set_settings(&settings).await.unwrap();
client.wait_for_task(task_info, None, None).await.unwrap();

let res = index.get_embedders().await.unwrap();

assert_eq!(embeddings, res);
}

#[meilisearch_test]
async fn test_reset_proximity_precision(index: Index) {
let expected = "byWord".to_string();
Expand Down

0 comments on commit 8ffb555

Please sign in to comment.