From 926dce707eb1b8ae10da04132c9e5e3e716342a5 Mon Sep 17 00:00:00 2001 From: Mubelotix Date: Fri, 1 Aug 2025 11:14:37 +0200 Subject: [PATCH] Remove JsonDocument Co-Authored-By: Louis Dureuil --- .../meilisearch/src/routes/indexes/render.rs | 10 +- crates/milli/src/prompt/document.rs | 105 ------------------ crates/milli/src/prompt/mod.rs | 10 +- 3 files changed, 11 insertions(+), 114 deletions(-) diff --git a/crates/meilisearch/src/routes/indexes/render.rs b/crates/meilisearch/src/routes/indexes/render.rs index 6ac0a939c..f9c0919e5 100644 --- a/crates/meilisearch/src/routes/indexes/render.rs +++ b/crates/meilisearch/src/routes/indexes/render.rs @@ -182,7 +182,7 @@ enum RenderError<'a> { BothInlineDocAndDocId, TemplateParsing(json_template::Error), TemplateRendering(json_template::Error), - CouldNotHandleInput, + InputConversion(liquid::Error), } impl From for RenderError<'_> { @@ -321,8 +321,8 @@ impl From> for ResponseError { format!("Error rendering template: {}", err.rendering_error("input")), Code::TemplateRenderingError, ), - CouldNotHandleInput => ResponseError::from_msg( - String::from("Could not handle the input provided."), + InputConversion(err) => ResponseError::from_msg( + format!("Error converting input to a liquid object: {err}"), Code::InvalidRenderInput, ), ExpectedDotAfterValue(span) => ResponseError::from_msg( @@ -516,8 +516,8 @@ async fn render(index: Index, query: RenderQuery) -> Result { /// Implementation for any type that implements the Document trait use crate::update::new::document::Document as DocumentTrait; -pub struct JsonDocument { - object: liquid::Object, - cached: BTreeMap>, -} - -impl JsonDocument { - pub fn new(value: &serde_json::Value) -> Result { - let to_string = serde_json::to_string(&value).map_err(|_| ())?; - let back_to_value: BTreeMap> = - serde_json::from_str(&to_string).map_err(|_| ())?; - let object = liquid::to_object(&value).map_err(|_| ())?; - Ok(Self { object, cached: back_to_value }) - } -} - -impl std::fmt::Debug for JsonDocument { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.object.fmt(f) - } -} - -impl<'a> DocumentTrait<'a> for &'a JsonDocument { - fn iter_top_level_fields( - &self, - ) -> impl Iterator> { - self.cached.iter().filter_map(|(k, v)| { - if k == RESERVED_VECTORS_FIELD_NAME || k == RESERVED_GEO_FIELD_NAME { - None - } else { - Some(Ok((k.as_str(), v.as_ref()))) - } - }) - } - - fn top_level_fields_count(&self) -> usize { - self.cached.len() - - self.cached.contains_key(RESERVED_VECTORS_FIELD_NAME) as usize - - self.cached.contains_key(RESERVED_GEO_FIELD_NAME) as usize - } - - fn top_level_field(&self, k: &str) -> crate::Result> { - if k == RESERVED_VECTORS_FIELD_NAME || k == RESERVED_GEO_FIELD_NAME { - return Ok(None); - } - Ok(self.cached.get(k).map(|r| r.as_ref())) - } - - fn vectors_field(&self) -> crate::Result> { - Ok(self.cached.get(RESERVED_VECTORS_FIELD_NAME).map(|r| r.as_ref())) - } - - fn geo_field(&self) -> crate::Result> { - Ok(self.cached.get(RESERVED_GEO_FIELD_NAME).map(|r| r.as_ref())) - } -} - -impl ObjectView for JsonDocument { - fn as_value(&self) -> &dyn ValueView { - self.object.as_value() - } - fn size(&self) -> i64 { - self.object.size() - } - fn keys<'k>(&'k self) -> Box> + 'k> { - Box::new(self.object.keys().map(|s| s.into())) - } - fn values<'k>(&'k self) -> Box + 'k> { - Box::new(self.object.values().map(|v| v.as_view())) - } - fn iter<'k>(&'k self) -> Box, &'k dyn ValueView)> + 'k> { - Box::new(self.object.iter().map(|(k, v)| (k.into(), v.as_view()))) - } - fn contains_key(&self, index: &str) -> bool { - self.object.contains_key(index) - } - fn get<'s>(&'s self, index: &str) -> Option<&'s dyn ValueView> { - self.object.get(index).map(|v| v.as_view()) - } -} - -impl ValueView for JsonDocument { - fn as_debug(&self) -> &dyn fmt::Debug { - self.object.as_debug() - } - fn render(&self) -> DisplayCow<'_> { - self.object.render() - } - fn source(&self) -> DisplayCow<'_> { - self.object.source() - } - fn type_name(&self) -> &'static str { - self.object.type_name() - } - fn query_state(&self, state: State) -> bool { - self.object.query_state(state) - } - fn to_kstr(&self) -> KStringCow<'_> { - self.object.to_kstr() - } - fn to_value(&self) -> LiquidValue { - self.object.to_value() - } -} - #[derive(Debug)] pub struct ParseableDocument<'a, 'doc, D: DocumentTrait<'a> + Debug> { document: D, diff --git a/crates/milli/src/prompt/mod.rs b/crates/milli/src/prompt/mod.rs index 910d01251..b5e616832 100644 --- a/crates/milli/src/prompt/mod.rs +++ b/crates/milli/src/prompt/mod.rs @@ -18,7 +18,6 @@ use liquid::ValueView; pub use self::context::Context; use crate::fields_ids_map::metadata::FieldIdMapWithMetadata; -use crate::prompt::document::JsonDocument; use crate::update::del_add::DelAdd; use crate::update::new::document::DocumentFromDb; use crate::{GlobalFieldsIdsMap, Index, MetadataBuilder}; @@ -173,10 +172,13 @@ pub fn get_inline_document_fields( index: &Index, rtxn: &RoTxn<'_>, inline_doc: &serde_json::Value, -) -> Result, crate::Error> { +) -> Result, crate::Error> { let fid_map_with_meta = index.fields_ids_map_with_metadata(rtxn)?; - let Ok(inline_doc) = JsonDocument::new(inline_doc) else { - return Ok(Err(())); + let inline_doc = match liquid::to_object(&inline_doc) { + Ok(inline_doc) => inline_doc, + Err(e) => { + return Ok(Err(e)); + } }; let fields = OwnedFields::new(&inline_doc, &fid_map_with_meta);