@@ -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\n 1,\" doggo\" \n 2,\" 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\n 1,\" doggo\" \n 2,\" catto\" " . as_bytes ( ) ;
2121+ let updated_csv = "id,body\n 1,\" new_doggo\" \n 2,\" 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