@@ -661,6 +661,96 @@ impl Index {
661661 self . add_or_replace ( documents, primary_key) . await
662662 }
663663
664+ /// Add a raw ndjson payload and update them if they already.
665+ ///
666+ /// It configures the correct content type for ndjson data.
667+ ///
668+ /// 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.
669+ /// Thus, any fields not present in the new document are kept and remained unchanged.
670+ ///
671+ /// To completely overwrite a document, check out the [`Index::add_documents_ndjson`] documents method.
672+ ///
673+ /// # Example
674+ ///
675+ /// ```
676+ /// # use serde::{Serialize, Deserialize};
677+ /// # use meilisearch_sdk::{client::*, indexes::*};
678+ /// # use std::thread::sleep;
679+ /// # use std::time::Duration;
680+ /// #
681+ /// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
682+ /// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
683+ /// # futures::executor::block_on(async move {
684+ /// # let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY));
685+ /// let movie_index = client.index("update_documents_ndjson");
686+ ///
687+ /// let task = movie_index.update_documents_ndjson(
688+ /// r#"{ "id": 1, "body": "doggo" }
689+ /// { "id": 2, "body": "catto" }"#.as_bytes(),
690+ /// Some("id"),
691+ /// ).await.unwrap();
692+ /// // Meilisearch may take some time to execute the request so we are going to wait till it's completed
693+ /// client.wait_for_task(task, None, None).await.unwrap();
694+ ///
695+ /// let movies = movie_index.get_documents::<serde_json::Value>().await.unwrap();
696+ /// assert!(movies.results.len() == 2);
697+ /// # movie_index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
698+ /// # });
699+ /// ```
700+ pub async fn update_documents_ndjson < T : futures_io:: AsyncRead + Send + Sync + ' static > (
701+ & self ,
702+ payload : T ,
703+ primary_key : Option < & str > ,
704+ ) -> Result < TaskInfo , Error > {
705+ self . add_or_update_unchecked_payload ( payload, "application/x-ndjson" , primary_key)
706+ . await
707+ }
708+
709+ /// Add a raw ndjson payload to meilisearch.
710+ ///
711+ /// It configures the correct content type for ndjson data.
712+ ///
713+ /// If you send an already existing document (same id) the **whole existing document** will be overwritten by the new document.
714+ /// Fields previously in the document not present in the new document are removed.
715+ ///
716+ /// For a partial update of the document see [`Index::update_documents_ndjson`].
717+ ///
718+ /// # Example
719+ ///
720+ /// ```
721+ /// # use serde::{Serialize, Deserialize};
722+ /// # use meilisearch_sdk::{client::*, indexes::*};
723+ /// # use std::thread::sleep;
724+ /// # use std::time::Duration;
725+ /// #
726+ /// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
727+ /// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
728+ /// # futures::executor::block_on(async move {
729+ /// # let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY));
730+ /// let movie_index = client.index("add_documents_ndjson");
731+ ///
732+ /// let task = movie_index.add_documents_ndjson(
733+ /// r#"{ "id": 1, "body": "doggo" }
734+ /// { "id": 2, "body": "catto" }"#.as_bytes(),
735+ /// Some("id"),
736+ /// ).await.unwrap();
737+ /// // Meilisearch may take some time to execute the request so we are going to wait till it's completed
738+ /// client.wait_for_task(task, None, None).await.unwrap();
739+ ///
740+ /// let movies = movie_index.get_documents::<serde_json::Value>().await.unwrap();
741+ /// assert!(movies.results.len() == 2);
742+ /// # movie_index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
743+ /// # });
744+ /// ```
745+ pub async fn add_documents_ndjson < T : futures_io:: AsyncRead + Send + Sync + ' static > (
746+ & self ,
747+ payload : T ,
748+ primary_key : Option < & str > ,
749+ ) -> Result < TaskInfo , Error > {
750+ self . add_or_replace_unchecked_payload ( payload, "application/x-ndjson" , primary_key)
751+ . await
752+ }
753+
664754 /// Add a list of documents and update them if they already.
665755 ///
666756 /// 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.
@@ -1861,6 +1951,60 @@ mod tests {
18611951 assert_eq ! ( res. offset, 2 ) ;
18621952 }
18631953
1954+ #[ meilisearch_test]
1955+ async fn test_add_documents_ndjson ( client : Client , index : Index ) -> Result < ( ) , Error > {
1956+ let ndjson = r#"{ "id": 1, "body": "doggo" }{ "id": 2, "body": "catto" }"# . as_bytes ( ) ;
1957+
1958+ let task = index
1959+ . add_documents_ndjson ( ndjson, Some ( "id" ) )
1960+ . await ?
1961+ . wait_for_completion ( & client, None , None )
1962+ . await ?;
1963+
1964+ let status = index. get_task ( task) . await ?;
1965+ // Meilisearch may take some time to execute the request so we are going to wait till it's completed
1966+ let elements = index. get_documents :: < serde_json:: Value > ( ) . await . unwrap ( ) ;
1967+ assert ! ( matches!( status, Task :: Succeeded { .. } ) ) ;
1968+ assert ! ( elements. results. len( ) == 2 ) ;
1969+
1970+ Ok ( ( ) )
1971+ }
1972+
1973+ #[ meilisearch_test]
1974+ async fn test_update_documents_ndjson ( client : Client , index : Index ) -> Result < ( ) , Error > {
1975+ let old_ndjson = r#"{ "id": 1, "body": "doggo" }{ "id": 2, "body": "catto" }"# . as_bytes ( ) ;
1976+ let updated_ndjson =
1977+ r#"{ "id": 1, "second_body": "second_doggo" }{ "id": 2, "second_body": "second_catto" }"# . as_bytes ( ) ;
1978+ // Add first njdson document
1979+ let task = index
1980+ . add_documents_ndjson ( old_ndjson, Some ( "id" ) )
1981+ . await ?
1982+ . wait_for_completion ( & client, None , None )
1983+ . await ?;
1984+ let _ = index. get_task ( task) . await ?;
1985+
1986+ let task = index
1987+ . update_documents_ndjson ( updated_ndjson, Some ( "id" ) )
1988+ . await ?
1989+ . wait_for_completion ( & client, None , None )
1990+ . await ?;
1991+
1992+ let status = index. get_task ( task) . await ?;
1993+ let elements = index. get_documents :: < serde_json:: Value > ( ) . await . unwrap ( ) ;
1994+
1995+ assert ! ( matches!( status, Task :: Succeeded { .. } ) ) ;
1996+ assert ! ( elements. results. len( ) == 2 ) ;
1997+
1998+ let expected_result = vec ! [
1999+ json!( { "body" : "doggo" , "id" : 1 , "second_body" : "second_doggo" } ) ,
2000+ json!( { "body" : "catto" , "id" : 2 , "second_body" : "second_catto" } ) ,
2001+ ] ;
2002+
2003+ assert_eq ! ( elements. results, expected_result) ;
2004+
2005+ Ok ( ( ) )
2006+ }
2007+
18642008 #[ meilisearch_test]
18652009 async fn test_get_one_task ( client : Client , index : Index ) -> Result < ( ) , Error > {
18662010 let task = index
0 commit comments