Skip to content

Commit

Permalink
Support serialization for DynamicTemplates.
Browse files Browse the repository at this point in the history
Signed-off-by: Youssef Aouichaoui <[email protected]>
  • Loading branch information
youssef3wi committed Aug 16, 2024
1 parent d079a59 commit eae9992
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -248,4 +248,11 @@
* @since 5.4
*/
String mappedTypeName() default "";

/**
* Maps your data beyond the dynamic field mapping rules.
*
* @since 5.4
*/
boolean dynamicTemplate() default false;
}
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,14 @@ protected void writeProperty(ElasticsearchPersistentProperty property, Object va

if (valueType.isMap()) {
Map<String, Object> mapDbObj = createMap((Map<?, ?>) value, property);
sink.set(property, mapDbObj);
if (property.isDynamicFieldMapping()) {
for (Entry<String, Object> entry : mapDbObj.entrySet()) {
sink.set(entry.getKey(), entry.getValue());
}
} else {
sink.set(property, mapDbObj);
}

return;
}

Expand Down Expand Up @@ -1499,7 +1506,11 @@ public void set(ElasticsearchPersistentProperty property, @Nullable Object value
}
}

target.put(property.getFieldName(), value);
set(property.getFieldName(), value);
}

public void set(String key, @Nullable Object value) {
target.put(key, value);
}

private Map<String, Object> getAsMap(Object result) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ public interface ElasticsearchPersistentProperty extends PersistentProperty<Elas
*/
boolean isIndexedIndexNameProperty();

/**
* Maps your data beyond the dynamic field mapping rules.
*
* @since 5.4
*/
boolean isDynamicFieldMapping();

/**
* calls {@link #getActualType()} but returns null when an exception is thrown
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public class SimpleElasticsearchPersistentProperty extends
@Nullable private PropertyValueConverter propertyValueConverter;
private final boolean storeNullValue;
private final boolean storeEmptyValue;
private final boolean isDynamicFieldMapping;

public SimpleElasticsearchPersistentProperty(Property property,
PersistentEntity<?, ElasticsearchPersistentProperty> owner, SimpleTypeHolder simpleTypeHolder) {
Expand All @@ -111,6 +112,7 @@ public SimpleElasticsearchPersistentProperty(Property property,

storeNullValue = isField && getRequiredAnnotation(Field.class).storeNullValue();
storeEmptyValue = isField ? getRequiredAnnotation(Field.class).storeEmptyValue() : true;
isDynamicFieldMapping = isField && getRequiredAnnotation(Field.class).dynamicTemplate();
}

@Override
Expand Down Expand Up @@ -390,4 +392,9 @@ public boolean isCompletionProperty() {
public boolean isIndexedIndexNameProperty() {
return isAnnotationPresent(IndexedIndexName.class);
}

@Override
public boolean isDynamicFieldMapping() {
return isDynamicFieldMapping;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@

package org.springframework.data.elasticsearch.core.index;

import static java.util.UUID.randomUUID;
import static org.assertj.core.api.Assertions.*;
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
import static org.springframework.data.elasticsearch.core.query.StringQuery.MATCH_ALL;

import java.time.Instant;
import java.time.LocalDate;
Expand All @@ -40,7 +42,9 @@
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.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.StringQuery;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
import org.springframework.lang.Nullable;
Expand Down Expand Up @@ -280,6 +284,24 @@ void shouldWriteMappingWithFieldAliases() {
operations.indexOps(FieldAliasEntity.class).createWithMapping();
}

@Test
void shouldMapDynamicFields() {
// Given
IndexOperations documentOperations = operations.indexOps(DynamicFieldDocument.class);
documentOperations.createWithMapping();

DynamicFieldDocument document = new DynamicFieldDocument();
document.dynamicFields = Map.of("a_str", randomUUID().toString(), "b_str", randomUUID().toString());
operations.save(document);

// When
SearchHits<DynamicFieldDocument> results = operations.search(new StringQuery(MATCH_ALL), DynamicFieldDocument.class);

// Then
assertThat(results.getTotalHits()).isEqualTo(1);
documentOperations.delete();
}

// region Entities
@Document(indexName = "#{@indexNameProvider.indexName()}")
static class Book {
Expand Down Expand Up @@ -933,5 +955,14 @@ private static class FieldAliasEntity {
@Field(type = Text) private String otherText;
}

@SuppressWarnings("unused")
@Document(indexName = "foo")
@DynamicTemplates(mappingPath = "/mappings/test-dynamic_templates_mappings_three.json")
private static class DynamicFieldDocument {
@Nullable
@Id String id;

@Field(name = "*_str", dynamicTemplate = true) private Map<String, String> dynamicFields = new HashMap<>();
}
// endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"dynamic_templates": [
{
"_str": {
"match": "*_str",
"mapping": {
"type": "keyword"
}
}
}
]
}

0 comments on commit eae9992

Please sign in to comment.