diff --git a/src/documents.rs b/src/documents.rs index 5dfc2a3a..2048937e 100644 --- a/src/documents.rs +++ b/src/documents.rs @@ -11,11 +11,89 @@ pub struct DocumentsResults { #[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>, } +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, + ) -> &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::("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( + &self, + document_id: &str, + ) -> Result { + self.index.get_document_with::(document_id, self).await + } +} + #[derive(Debug, Clone, Serialize)] pub struct DocumentsQuery<'a> { #[serde(skip_serializing)] @@ -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::() + /// .await + /// .unwrap(); /// - /// documents_query.with_offset(1).execute::().await.unwrap(); + /// # index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap(); /// # }); /// ``` pub async fn execute( diff --git a/src/indexes.rs b/src/indexes.rs index 8570e3e0..afc99614 100644 --- a/src/indexes.rs +++ b/src/indexes.rs @@ -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 - /// } - /// - /// #[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::("Interstellar", Some(["name", "description"].to_vec())).await.unwrap(); + /// let interstellar = movies.get_document::("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."), /// }); @@ -317,16 +309,65 @@ impl Index { pub async fn get_document( &self, document_id: &str, - fields: Option>, ) -> Result { 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::("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( + &self, + document_id: &str, + document_query: &DocumentQuery<'_>, + ) -> Result { + 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. @@ -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); @@ -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::(&query).await.unwrap(); + /// let movies = movie_index.get_documents_with::(&query).await.unwrap(); /// /// assert!(movies.results.len() == 1); /// # movie_index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();