Skip to content

Commit 60b168e

Browse files
committed
Added csv operation
Signed-off-by: carlosb1 <[email protected]>
1 parent 241e797 commit 60b168e

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

src/indexes.rs

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,100 @@ impl Index {
753753
.await
754754
}
755755

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

2068+
#[meilisearch_test]
2069+
async fn test_update_documents_csv(client: Client, index: Index) -> Result<(), Error> {
2070+
let old_csv = r#"1,body
2071+
1,"doggo"
2072+
2,"catto""#
2073+
.as_bytes();
2074+
let updated_csv = r#"1,body
2075+
1,"new_doggo"
2076+
2,"new_catto""#
2077+
.as_bytes();
2078+
// Add first njdson document
2079+
let task = index
2080+
.add_documents_ndjson(old_csv, Some("id"))
2081+
.await?
2082+
.wait_for_completion(&client, None, None)
2083+
.await?;
2084+
let _ = index.get_task(task).await?;
2085+
2086+
// Update via njdson document
2087+
let task = index
2088+
.update_documents_ndjson(updated_csv, Some("id"))
2089+
.await?
2090+
.wait_for_completion(&client, None, None)
2091+
.await?;
2092+
2093+
let status = index.get_task(task).await?;
2094+
let elements = index.get_documents::<serde_json::Value>().await.unwrap();
2095+
2096+
assert!(matches!(status, Task::Succeeded { .. }));
2097+
assert!(elements.results.len() == 2);
2098+
2099+
let expected_result = vec![
2100+
json!( {"body": "doggo", "id": 1, "second_body": "second_doggo"}),
2101+
json!( {"body": "catto", "id": 2, "second_body": "second_catto"}),
2102+
];
2103+
2104+
assert_eq!(elements.results, expected_result);
2105+
2106+
Ok(())
2107+
}
2108+
2109+
#[meilisearch_test]
2110+
async fn test_add_documents_csv(client: Client, index: Index) -> Result<(), Error> {
2111+
let csv_input = r#"1,body
2112+
1,"doggo"
2113+
2,"catto""#
2114+
.as_bytes();
2115+
2116+
let task = index
2117+
.add_documents_csv(csv_input, Some("id"))
2118+
.await?
2119+
.wait_for_completion(&client, None, None)
2120+
.await?;
2121+
2122+
let status = index.get_task(task).await?;
2123+
let elements = index.get_documents::<serde_json::Value>().await.unwrap();
2124+
assert!(matches!(status, Task::Succeeded { .. }));
2125+
assert!(elements.results.len() == 2);
2126+
2127+
Ok(())
2128+
}
2129+
19742130
#[meilisearch_test]
19752131
async fn test_update_documents_ndjson(client: Client, index: Index) -> Result<(), Error> {
19762132
let old_ndjson = r#"{ "id": 1, "body": "doggo" }{ "id": 2, "body": "catto" }"#.as_bytes();

0 commit comments

Comments
 (0)