Skip to content

Commit 476ee7f

Browse files
Merge #508
508: add functions for csv documents r=curquiza a=carlosb1 # Pull Request ## Related issue Fixes partially #191 ## What does this PR do? Added the first two functions (with their tests) for issue #191. It includes two functions for sending csv payloads - `add_documents_csv` - `update_documents_csv` ## 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: carlosb1 <[email protected]>
2 parents 835b86f + 214256d commit 476ee7f

File tree

1 file changed

+142
-0
lines changed

1 file changed

+142
-0
lines changed

src/indexes.rs

+142
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,96 @@ impl Index {
753753
.await
754754
}
755755

756+
/// Add a raw csv payload and update them if they already.
757+
///
758+
/// It configures the correct content type for csv data.
759+
///
760+
/// If you send an already existing document (same id) the old document will be only partially updated according to the fields of the new document.
761+
/// Thus, any fields not present in the new document are kept and remained unchanged.
762+
///
763+
/// To completely overwrite a document, check out the [`Index::add_documents_csv`] documents method.
764+
///
765+
/// # Example
766+
///
767+
/// ```
768+
/// # use serde::{Serialize, Deserialize};
769+
/// # use meilisearch_sdk::{client::*, indexes::*};
770+
/// # use std::thread::sleep;
771+
/// # use std::time::Duration;
772+
/// #
773+
/// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
774+
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
775+
/// # futures::executor::block_on(async move {
776+
/// # let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY));
777+
/// let movie_index = client.index("update_documents_csv");
778+
///
779+
/// let task = movie_index.update_documents_csv(
780+
/// "id,body\n1,\"doggo\"\n2,\"catto\"".as_bytes(),
781+
/// Some("id"),
782+
/// ).await.unwrap();
783+
/// // Meilisearch may take some time to execute the request so we are going to wait till it's completed
784+
/// client.wait_for_task(task, None, None).await.unwrap();
785+
///
786+
/// let movies = movie_index.get_documents::<serde_json::Value>().await.unwrap();
787+
/// assert!(movies.results.len() == 2);
788+
/// # movie_index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
789+
/// # });
790+
/// ```
791+
#[cfg(not(target_arch = "wasm32"))]
792+
pub async fn update_documents_csv<T: futures_io::AsyncRead + Send + Sync + 'static>(
793+
&self,
794+
payload: T,
795+
primary_key: Option<&str>,
796+
) -> Result<TaskInfo, Error> {
797+
self.add_or_update_unchecked_payload(payload, "text/csv", primary_key)
798+
.await
799+
}
800+
801+
/// Add a raw csv payload to meilisearch.
802+
///
803+
/// It configures the correct content type for csv data.
804+
///
805+
/// If you send an already existing document (same id) the **whole existing document** will be overwritten by the new document.
806+
/// Fields previously in the document not present in the new document are removed.
807+
///
808+
/// For a partial update of the document see [`Index::update_documents_csv`].
809+
///
810+
/// # Example
811+
///
812+
/// ```
813+
/// # use serde::{Serialize, Deserialize};
814+
/// # use meilisearch_sdk::{client::*, indexes::*};
815+
/// # use std::thread::sleep;
816+
/// # use std::time::Duration;
817+
/// #
818+
/// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
819+
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
820+
/// # futures::executor::block_on(async move {
821+
/// # let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY));
822+
/// let movie_index = client.index("add_documents_csv");
823+
///
824+
/// let task = movie_index.add_documents_csv(
825+
/// "id,body\n1,\"doggo\"\n2,\"catto\"".as_bytes(),
826+
/// Some("id"),
827+
/// ).await.unwrap();
828+
/// // Meilisearch may take some time to execute the request so we are going to wait till it's completed
829+
/// client.wait_for_task(task, None, None).await.unwrap();
830+
///
831+
/// let movies = movie_index.get_documents::<serde_json::Value>().await.unwrap();
832+
/// assert!(movies.results.len() == 2);
833+
/// # movie_index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
834+
/// # });
835+
/// ```
836+
#[cfg(not(target_arch = "wasm32"))]
837+
pub async fn add_documents_csv<T: futures_io::AsyncRead + Send + Sync + 'static>(
838+
&self,
839+
payload: T,
840+
primary_key: Option<&str>,
841+
) -> Result<TaskInfo, Error> {
842+
self.add_or_replace_unchecked_payload(payload, "text/csv", primary_key)
843+
.await
844+
}
845+
756846
/// Add a list of documents and update them if they already.
757847
///
758848
/// If you send an already existing document (same id) the old document will be only partially updated according to the fields of the new document.
@@ -2007,6 +2097,58 @@ mod tests {
20072097
Ok(())
20082098
}
20092099

2100+
#[meilisearch_test]
2101+
async fn test_add_documents_csv(client: Client, index: Index) -> Result<(), Error> {
2102+
let csv_input = "id,body\n1,\"doggo\"\n2,\"catto\"".as_bytes();
2103+
2104+
let task = index
2105+
.add_documents_csv(csv_input, Some("id"))
2106+
.await?
2107+
.wait_for_completion(&client, None, None)
2108+
.await?;
2109+
2110+
let status = index.get_task(task).await?;
2111+
let elements = index.get_documents::<serde_json::Value>().await.unwrap();
2112+
assert!(matches!(status, Task::Succeeded { .. }));
2113+
assert!(elements.results.len() == 2);
2114+
2115+
Ok(())
2116+
}
2117+
2118+
#[meilisearch_test]
2119+
async fn test_update_documents_csv(client: Client, index: Index) -> Result<(), Error> {
2120+
let old_csv = "id,body\n1,\"doggo\"\n2,\"catto\"".as_bytes();
2121+
let updated_csv = "id,body\n1,\"new_doggo\"\n2,\"new_catto\"".as_bytes();
2122+
// Add first njdson document
2123+
let task = index
2124+
.add_documents_csv(old_csv, Some("id"))
2125+
.await?
2126+
.wait_for_completion(&client, None, None)
2127+
.await?;
2128+
let _ = index.get_task(task).await?;
2129+
2130+
// Update via njdson document
2131+
let task = index
2132+
.update_documents_csv(updated_csv, Some("id"))
2133+
.await?
2134+
.wait_for_completion(&client, None, None)
2135+
.await?;
2136+
2137+
let status = index.get_task(task).await?;
2138+
let elements = index.get_documents::<serde_json::Value>().await.unwrap();
2139+
2140+
assert!(matches!(status, Task::Succeeded { .. }));
2141+
assert!(elements.results.len() == 2);
2142+
2143+
let expected_result = vec![
2144+
json!( {"body": "new_doggo", "id": "1"}),
2145+
json!( {"body": "new_catto", "id": "2"}),
2146+
];
2147+
2148+
assert_eq!(elements.results, expected_result);
2149+
2150+
Ok(())
2151+
}
20102152
#[meilisearch_test]
20112153
async fn test_get_one_task(client: Client, index: Index) -> Result<(), Error> {
20122154
let task = index

0 commit comments

Comments
 (0)