Skip to content

Update document query for v0.28.0 #326

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 84 additions & 2 deletions src/documents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,89 @@ pub struct DocumentsResults<T> {

#[derive(Debug, Clone, Serialize)]
pub struct DocumentQuery<'a> {
#[serde(skip_serializing)]
pub index: &'a Index,

/// The fields that should appear in the documents. By default all of the fields are present.
#[serde(skip_serializing_if = "Option::is_none")]
pub fields: Option<Vec<&'a str>>,
}

impl<'a> DocumentQuery<'a> {
pub fn new(index: &Index) -> DocumentQuery {
DocumentQuery {
index,
fields: None,
}
}

/// Specify the fields to return in the document.
///
/// # Example
///
/// ```
/// # use meilisearch_sdk::{client::*, indexes::*, documents::*};
/// #
/// # let MEILISEARCH_HOST = option_env!("MEILISEARCH_HOST").unwrap_or("http://localhost:7700");
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
/// #
/// # let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
/// let index = client.index("document_query_with_fields");
/// let mut document_query = DocumentQuery::new(&index);
///
/// document_query.with_fields(["title"]);
/// ```
pub fn with_fields(
&mut self,
fields: impl IntoIterator<Item = &'a str>,
) -> &mut DocumentQuery<'a> {
self.fields = Some(fields.into_iter().collect());
self
}

/// Execute the get document query.
///
/// # Example
///
/// ```
/// # use meilisearch_sdk::{client::*, indexes::*, documents::*};
/// # use serde::{Deserialize, Serialize};
/// #
/// # let MEILISEARCH_HOST = option_env!("MEILISEARCH_HOST").unwrap_or("http://localhost:7700");
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
/// #
/// # let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
///
/// # futures::executor::block_on(async move {
/// #[derive(Debug, Serialize, Deserialize, PartialEq)]
/// struct MyObject {
/// id: String,
/// kind: String,
/// }
/// #[derive(Debug, Serialize, Deserialize, PartialEq)]
/// struct MyObjectReduced {
/// id: String,
/// }
///
/// # let index = client.index("document_query_execute");
/// # index.add_or_replace(&[MyObject{id:"1".to_string(), kind:String::from("a kind")},MyObject{id:"2".to_string(), kind:String::from("some kind")}], None).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
///
/// let document = DocumentQuery::new(&index).with_fields(["id"]).execute::<MyObjectReduced>("1").await.unwrap();
///
/// assert_eq!(
/// document,
/// MyObjectReduced { id: "1".to_string() }
/// );
/// # index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// # });
pub async fn execute<T: DeserializeOwned + 'static>(
&self,
document_id: &str,
) -> Result<T, Error> {
self.index.get_document_with::<T>(document_id, self).await
}
}

#[derive(Debug, Clone, Serialize)]
pub struct DocumentsQuery<'a> {
#[serde(skip_serializing)]
Expand Down Expand Up @@ -144,9 +222,13 @@ impl<'a> DocumentsQuery<'a> {
/// }
/// let index = client.index("documents_query_execute");
///
/// let mut documents_query = DocumentsQuery::new(&index);
/// let document = DocumentsQuery::new(&index)
/// .with_offset(1)
/// .execute::<MyObject>()
/// .await
/// .unwrap();
///
/// documents_query.with_offset(1).execute::<MyObject>().await.unwrap();
/// # index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// # });
/// ```
pub async fn execute<T: DeserializeOwned + 'static>(
Expand Down
78 changes: 62 additions & 16 deletions src/indexes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,29 +285,21 @@ impl Index {
/// # let MEILISEARCH_HOST = option_env!("MEILISEARCH_HOST").unwrap_or("http://localhost:7700");
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
/// #
/// #[derive(Serialize, Debug)]
/// #[derive(Serialize, Deserialize, Debug, PartialEq)]
/// struct Movie {
/// name: String,
/// description: String,
/// age: Option<usize>
/// }
///
/// #[derive(Deserialize, Debug, PartialEq)]
/// struct ReturnedMovie {
/// name: String,
/// description: String
/// }
///
///
/// # futures::executor::block_on(async move {
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
/// let movies = client.index("get_document");
/// # movies.add_or_replace(&[Movie{name:String::from("Interstellar"), description:String::from("Interstellar chronicles the adventures of a group of explorers who make use of a newly discovered wormhole to surpass the limitations on human space travel and conquer the vast distances involved in an interstellar voyage."), age: Some(1)}], Some("name")).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// # movies.add_or_replace(&[Movie{name:String::from("Interstellar"), description:String::from("Interstellar chronicles the adventures of a group of explorers who make use of a newly discovered wormhole to surpass the limitations on human space travel and conquer the vast distances involved in an interstellar voyage.")}], Some("name")).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
///
/// // retrieve a document (you have to put the document in the index before)
/// let interstellar = movies.get_document::<ReturnedMovie>("Interstellar", Some(["name", "description"].to_vec())).await.unwrap();
/// let interstellar = movies.get_document::<Movie>("Interstellar").await.unwrap();
///
/// assert_eq!(interstellar, ReturnedMovie {
/// assert_eq!(interstellar, Movie {
/// name: String::from("Interstellar"),
/// description: String::from("Interstellar chronicles the adventures of a group of explorers who make use of a newly discovered wormhole to surpass the limitations on human space travel and conquer the vast distances involved in an interstellar voyage."),
/// });
Expand All @@ -317,16 +309,65 @@ impl Index {
pub async fn get_document<T: 'static + DeserializeOwned>(
&self,
document_id: &str,
fields: Option<Vec<&str>>,
) -> Result<T, Error> {
let url = format!(
"{}/indexes/{}/documents/{}",
self.client.host, self.uid, document_id
);

let query = DocumentQuery { fields };
request::<(), T>(&url, &self.client.api_key, Method::Get(()), 200).await
}

/// Get one document with parameters.
///
/// # Example
///
/// ```
/// # use meilisearch_sdk::{client::*, indexes::*, documents::*};
/// # use serde::{Deserialize, Serialize};
/// #
/// # let MEILISEARCH_HOST = option_env!("MEILISEARCH_HOST").unwrap_or("http://localhost:7700");
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
/// #
/// # let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
///
/// # futures::executor::block_on(async move {
/// #[derive(Debug, Serialize, Deserialize, PartialEq)]
/// struct MyObject {
/// id: String,
/// kind: String,
/// }
/// #[derive(Debug, Serialize, Deserialize, PartialEq)]
/// struct MyObjectReduced {
/// id: String,
/// }
///
/// # let index = client.index("document_query_execute");
/// # index.add_or_replace(&[MyObject{id:"1".to_string(), kind:String::from("a kind")},MyObject{id:"2".to_string(), kind:String::from("some kind")}], None).await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
///
/// let mut document_query = DocumentQuery::new(&index);
/// document_query.with_fields(["id"]);
///
/// let document = index.get_document_with::<MyObjectReduced>("1", &document_query).await.unwrap();
///
/// assert_eq!(
/// document,
/// MyObjectReduced { id: "1".to_string() }
/// );
/// # index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
/// # });
pub async fn get_document_with<T: 'static + DeserializeOwned>(
&self,
document_id: &str,
document_query: &DocumentQuery<'_>,
) -> Result<T, Error> {
let url = format!(
"{}/indexes/{}/documents/{}",
self.client.host, self.uid, document_id
);

request::<&DocumentQuery, T>(&url, &self.client.api_key, Method::Get(&query), 200).await
request::<&DocumentQuery, T>(&url, &self.client.api_key, Method::Get(document_query), 200)
.await
}

/// Get [Document]s by batch.
Expand Down Expand Up @@ -388,6 +429,10 @@ impl Index {
/// description: String,
/// }
///
/// #[derive(Deserialize, Debug, PartialEq)]
/// struct ReturnedMovie {
/// name: String,
/// }
///
/// # futures::executor::block_on(async move {
/// let client = Client::new(MEILISEARCH_HOST, MEILISEARCH_API_KEY);
Expand All @@ -397,8 +442,9 @@ impl Index {
///
/// let mut query = DocumentsQuery::new(&movie_index);
/// query.with_limit(1);
/// query.with_fields(["name"]);
/// // retrieve movies (you have to put some movies in the index before)
/// let movies = movie_index.get_documents_with::<Movie>(&query).await.unwrap();
/// let movies = movie_index.get_documents_with::<ReturnedMovie>(&query).await.unwrap();
///
/// assert!(movies.results.len() == 1);
/// # movie_index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
Expand Down