From f052ae234a36df89d995d2868c02d06e0f7b40e4 Mon Sep 17 00:00:00 2001 From: Youssef Aouichaoui Date: Tue, 20 Aug 2024 16:54:28 +0200 Subject: [PATCH] Support deserialization for DynamicTemplates. Signed-off-by: Youssef Aouichaoui --- .../MappingElasticsearchConverter.java | 40 +++++++++++++++++++ .../index/MappingBuilderIntegrationTests.java | 5 ++- 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index ff231bd08..841b36407 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -15,6 +15,9 @@ */ package org.springframework.data.elasticsearch.core.convert; +import static org.springframework.util.PatternMatchUtils.simpleMatch; +import static org.springframework.util.StringUtils.hasText; + import java.time.temporal.TemporalAccessor; import java.util.*; import java.util.Map.Entry; @@ -38,8 +41,10 @@ import org.springframework.core.env.EnvironmentCapable; import org.springframework.core.env.StandardEnvironment; import org.springframework.data.convert.CustomConversions; +import org.springframework.data.elasticsearch.annotations.DynamicTemplates; import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.ScriptedField; +import org.springframework.data.elasticsearch.core.ResourceUtil; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.SearchDocument; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; @@ -53,6 +58,7 @@ import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.elasticsearch.core.query.SourceFilter; +import org.springframework.data.elasticsearch.support.DefaultStringObjectMap; import org.springframework.data.mapping.InstanceCreatorMetadata; import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.Parameter; @@ -388,6 +394,40 @@ private R readEntity(ElasticsearchPersistentEntity entity, Map().fromJson(jsonString).get("dynamic_templates"); + if (templates instanceof List array) { + for (Object node : array) { + if (node instanceof Map entry) { + Entry templateEntry = entry.entrySet().stream().findFirst().orElse(null); + if (templateEntry != null) { + ElasticsearchPersistentProperty property = targetEntity + .getPersistentPropertyWithFieldName((String) templateEntry.getKey()); + if (property != null && property.isDynamicFieldMapping()) { + targetEntity.getPropertyAccessor(result).getProperty(property); + targetEntity.getPropertyAccessor(result).setProperty(property, + document.entrySet().stream().filter(fieldKey -> { + if (templateEntry.getValue() instanceof Map templateValue) { + if (templateValue.containsKey("match")) { + return simpleMatch((String) templateValue.get("match"), fieldKey.getKey()); + } + } + + return false; + }).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); + } + } + } + } + } + } + } + } } if (source instanceof SearchDocument searchDocument) { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java index eba9a8ede..9d68b7905 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderIntegrationTests.java @@ -42,6 +42,7 @@ import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.MappingContextBaseTests; +import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.StringQuery; @@ -299,6 +300,8 @@ void shouldMapDynamicFields() { // Then assertThat(results.getTotalHits()).isEqualTo(1); + assertThat(results.getSearchHits()).first().extracting(SearchHit::getContent).extracting(doc -> doc.dynamicFields) + .isEqualTo(document.dynamicFields); documentOperations.delete(); } @@ -962,7 +965,7 @@ private static class DynamicFieldDocument { @Nullable @Id String id; - @Field(name = "*_str", dynamicTemplate = true) private Map dynamicFields = new HashMap<>(); + @Field(name = "_str", dynamicTemplate = true) private Map dynamicFields = new HashMap<>(); } // endregion }