From c8b7822d0d9febca76ed8a7e4a4801cacbc19382 Mon Sep 17 00:00:00 2001 From: Kerollmops Date: Sat, 19 Apr 2025 12:22:37 +0200 Subject: [PATCH] Allow users to delete documents --- crates/milli/src/update/new/document.rs | 41 ++++++++++++------- .../update/new/indexer/document_operation.rs | 14 ++++++- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/crates/milli/src/update/new/document.rs b/crates/milli/src/update/new/document.rs index e6178d1df..0de14ba22 100644 --- a/crates/milli/src/update/new/document.rs +++ b/crates/milli/src/update/new/document.rs @@ -412,7 +412,7 @@ impl<'doc> Versions<'doc> { engine: &rhai::Engine, edit_function: &rhai::AST, doc_alloc: &'doc bumpalo::Bump, - ) -> Result> { + ) -> Result>> { let Some(data) = versions.next() else { return Ok(None) }; let mut doc = doc.unwrap_or_default(); @@ -431,12 +431,19 @@ impl<'doc> Versions<'doc> { let _ = engine.eval_ast_with_scope::(&mut scope, edit_function).unwrap(); data = RawMap::with_hasher_in(FxBuildHasher, doc_alloc); - for (key, value) in scope.get_value::("doc").unwrap() { - let mut vec = bumpalo::collections::Vec::new_in(doc_alloc); - serde_json::to_writer(&mut vec, &value).unwrap(); - let key = doc_alloc.alloc_str(key.as_str()); - let raw_value = serde_json::from_slice(vec.into_bump_slice()).unwrap(); - data.insert(key, raw_value); + match scope.get_value::>("doc").unwrap() { + Some(map) => { + for (key, value) in map { + let mut vec = bumpalo::collections::Vec::new_in(doc_alloc); + serde_json::to_writer(&mut vec, &value).unwrap(); + let key = doc_alloc.alloc_str(key.as_str()); + let raw_value = serde_json::from_slice(vec.into_bump_slice()).unwrap(); + data.insert(key, raw_value); + } + } + // In case the deletes the document and it's not the last change + // we simply set the document to an empty one and await the next change. + None => (), } } @@ -449,15 +456,19 @@ impl<'doc> Versions<'doc> { let _ = engine.eval_ast_with_scope::(&mut scope, edit_function).unwrap(); data = RawMap::with_hasher_in(FxBuildHasher, doc_alloc); - for (key, value) in scope.get_value::("doc").unwrap() { - let mut vec = bumpalo::collections::Vec::new_in(doc_alloc); - serde_json::to_writer(&mut vec, &value).unwrap(); - let key = doc_alloc.alloc_str(key.as_str()); - let raw_value = serde_json::from_slice(vec.into_bump_slice()).unwrap(); - data.insert(key, raw_value); + match scope.get_value::>("doc").unwrap() { + Some(map) => { + for (key, value) in map { + let mut vec = bumpalo::collections::Vec::new_in(doc_alloc); + serde_json::to_writer(&mut vec, &value).unwrap(); + let key = doc_alloc.alloc_str(key.as_str()); + let raw_value = serde_json::from_slice(vec.into_bump_slice()).unwrap(); + data.insert(key, raw_value); + } + Ok(Some(Some(Self::single(data)))) + } + None => Ok(Some(None)), } - - Ok(Some(Self::single(data))) } pub fn single(version: RawMap<'doc, FxBuildHasher>) -> Self { diff --git a/crates/milli/src/update/new/indexer/document_operation.rs b/crates/milli/src/update/new/indexer/document_operation.rs index e3ac7b35d..96488c37c 100644 --- a/crates/milli/src/update/new/indexer/document_operation.rs +++ b/crates/milli/src/update/new/indexer/document_operation.rs @@ -510,6 +510,7 @@ impl<'pl> PayloadOperations<'pl> { } /// Returns only the most recent version of a document based on the updates from the payloads. + #[allow(clippy::too_many_arguments)] fn merge<'doc>( &self, rtxn: &heed::RoTxn, @@ -587,7 +588,18 @@ impl<'pl> PayloadOperations<'pl> { .get(rtxn, &self.docid)? .map(|obkv| obkv_to_rhaimap(obkv, fidmap)) .transpose()?; - Versions::multiple_with_edits(doc, versions, engine, ast, doc_alloc)? + match Versions::multiple_with_edits(doc, versions, engine, ast, doc_alloc)? + { + Some(Some(versions)) => Some(versions), + Some(None) if self.is_new => return Ok(None), + Some(None) => { + return Ok(Some(DocumentChange::Deletion(Deletion::create( + self.docid, + external_doc, + )))); + } + None => None, + } } None => Versions::multiple(versions)?, };