@@ -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