DynamicMapping annotation should be applicable to any object field.

Original Pull Request #1779
Closes #1767
This commit is contained in:
Peter-Josef Meisch 2021-04-17 14:53:12 +02:00
parent 532bb85d77
commit 73d52cd686
No known key found for this signature in database
GPG Key ID: DE108246970C7708
3 changed files with 76 additions and 19 deletions

View File

@ -216,6 +216,7 @@ public class MappingBuilder {
Field fieldAnnotation = property.findAnnotation(Field.class); Field fieldAnnotation = property.findAnnotation(Field.class);
boolean isCompletionProperty = property.isCompletionProperty(); boolean isCompletionProperty = property.isCompletionProperty();
boolean isNestedOrObjectProperty = isNestedOrObjectProperty(property); boolean isNestedOrObjectProperty = isNestedOrObjectProperty(property);
DynamicMapping dynamicMapping = property.findAnnotation(DynamicMapping.class);
if (!isCompletionProperty && property.isEntity() && hasRelevantAnnotation(property)) { if (!isCompletionProperty && property.isEntity() && hasRelevantAnnotation(property)) {
@ -230,7 +231,7 @@ public class MappingBuilder {
: null; : null;
mapEntity(builder, persistentEntity, false, property.getFieldName(), true, fieldAnnotation.type(), mapEntity(builder, persistentEntity, false, property.getFieldName(), true, fieldAnnotation.type(),
fieldAnnotation, property.findAnnotation(DynamicMapping.class)); fieldAnnotation, dynamicMapping);
return; return;
} }
} }
@ -245,9 +246,9 @@ public class MappingBuilder {
if (isRootObject && fieldAnnotation != null && property.isIdProperty()) { if (isRootObject && fieldAnnotation != null && property.isIdProperty()) {
applyDefaultIdFieldMapping(builder, property); applyDefaultIdFieldMapping(builder, property);
} else if (multiField != null) { } else if (multiField != null) {
addMultiFieldMapping(builder, property, multiField, isNestedOrObjectProperty); addMultiFieldMapping(builder, property, multiField, isNestedOrObjectProperty, dynamicMapping);
} else if (fieldAnnotation != null) { } else if (fieldAnnotation != null) {
addSingleFieldMapping(builder, property, fieldAnnotation, isNestedOrObjectProperty); addSingleFieldMapping(builder, property, fieldAnnotation, isNestedOrObjectProperty, dynamicMapping);
} }
} }
@ -328,7 +329,7 @@ public class MappingBuilder {
* @throws IOException * @throws IOException
*/ */
private void addSingleFieldMapping(XContentBuilder builder, ElasticsearchPersistentProperty property, private void addSingleFieldMapping(XContentBuilder builder, ElasticsearchPersistentProperty property,
Field annotation, boolean nestedOrObjectField) throws IOException { Field annotation, boolean nestedOrObjectField, @Nullable DynamicMapping dynamicMapping) throws IOException {
// build the property json, if empty skip it as this is no valid mapping // build the property json, if empty skip it as this is no valid mapping
XContentBuilder propertyBuilder = jsonBuilder().startObject(); XContentBuilder propertyBuilder = jsonBuilder().startObject();
@ -340,6 +341,11 @@ public class MappingBuilder {
} }
builder.startObject(property.getFieldName()); builder.startObject(property.getFieldName());
if (nestedOrObjectField && dynamicMapping != null) {
builder.field(TYPE_DYNAMIC, dynamicMapping.value().name().toLowerCase());
}
addFieldMappingParameters(builder, annotation, nestedOrObjectField); addFieldMappingParameters(builder, annotation, nestedOrObjectField);
builder.endObject(); builder.endObject();
} }
@ -380,10 +386,15 @@ public class MappingBuilder {
* @throws IOException * @throws IOException
*/ */
private void addMultiFieldMapping(XContentBuilder builder, ElasticsearchPersistentProperty property, private void addMultiFieldMapping(XContentBuilder builder, ElasticsearchPersistentProperty property,
MultiField annotation, boolean nestedOrObjectField) throws IOException { MultiField annotation, boolean nestedOrObjectField, @Nullable DynamicMapping dynamicMapping) throws IOException {
// main field // main field
builder.startObject(property.getFieldName()); builder.startObject(property.getFieldName());
if (nestedOrObjectField && dynamicMapping != null) {
builder.field(TYPE_DYNAMIC, dynamicMapping.value().name().toLowerCase());
}
addFieldMappingParameters(builder, annotation.mainField(), nestedOrObjectField); addFieldMappingParameters(builder, annotation.mainField(), nestedOrObjectField);
// inner fields // inner fields

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2013-2020 the original author or authors. * Copyright 2013-2021 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,6 +30,7 @@ import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import java.lang.Integer; import java.lang.Integer;
import java.lang.Object;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -263,11 +264,21 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
/** /**
* @author Xiao Yu * @author Xiao Yu
*/ */
@Setter @Test // #1767
@Getter @DisplayName("should write dynamic mapping entries")
@NoArgsConstructor void shouldWriteDynamicMappingEntries() {
@AllArgsConstructor
@Builder IndexOperations indexOps = operations.indexOps(DynamicMappingEntity.class);
indexOps.create();
indexOps.putMapping();
indexOps.delete();
}
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Document(indexName = "ignore-above-index") @Document(indexName = "ignore-above-index")
static class IgnoreAboveEntity { static class IgnoreAboveEntity {
@ -647,4 +658,25 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
@Field(type = FieldType.Text, @Field(type = FieldType.Text,
termVector = TermVector.with_positions_offsets_payloads) private String with_positions_offsets_payloads; termVector = TermVector.with_positions_offsets_payloads) private String with_positions_offsets_payloads;
} }
@Document(indexName = "dynamic-mapping")
@DynamicMapping(DynamicMappingValue.False)
static class DynamicMappingEntity {
@Nullable @DynamicMapping(DynamicMappingValue.Strict) @Field(type = FieldType.Object) private Author author;
@Nullable @DynamicMapping(DynamicMappingValue.False) @Field(
type = FieldType.Object) private Map<String, Object> objectMap;
@Nullable @DynamicMapping(DynamicMappingValue.False) @Field(
type = FieldType.Nested) private List<Map<String, Object>> nestedObjectMap;
@Nullable
public Author getAuthor() {
return author;
}
public void setAuthor(Author author) {
this.author = author;
}
}
} }

View File

@ -37,6 +37,7 @@ import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -410,19 +411,28 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
assertEquals(expected, mapping, true); assertEquals(expected, mapping, true);
} }
@Test @Test // DATAES-148, #1767
void shouldWriteDynamicMappingSettings() throws JSONException { void shouldWriteDynamicMappingSettings() throws JSONException {
String expected = "{\n" + // String expected = "{\n" + //
" \"dynamic\": \"false\",\n" + // " \"dynamic\": \"false\",\n" + //
" \"properties\": {\n" + // " \"properties\": {\n" + //
" \"author\": {\n" + // " \"author\": {\n" + //
" \"dynamic\": \"strict\",\n" + // " \"type\": \"object\",\n" + //
" \"type\": \"object\",\n" + // " \"dynamic\": \"strict\",\n" + //
" \"properties\": {}\n" + // " \"properties\": {\n" + //
" }\n" + // " }\n" + //
" },\n" + //
" \"objectMap\": {\n" + //
" \"type\": \"object\",\n" + //
" \"dynamic\": \"false\"\n" + //
" },\n" + //
" \"nestedObjectMap\": {\n" + //
" \"type\": \"nested\",\n" + //
" \"dynamic\": \"false\"\n" + //
" }\n" + // " }\n" + //
"}\n"; " }\n" + //
"}"; //
String mapping = getMappingBuilder().buildPropertyMapping(ConfigureDynamicMappingEntity.class); String mapping = getMappingBuilder().buildPropertyMapping(ConfigureDynamicMappingEntity.class);
@ -898,6 +908,10 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
static class ConfigureDynamicMappingEntity { static class ConfigureDynamicMappingEntity {
@Nullable @DynamicMapping(DynamicMappingValue.Strict) @Field(type = FieldType.Object) private Author author; @Nullable @DynamicMapping(DynamicMappingValue.Strict) @Field(type = FieldType.Object) private Author author;
@Nullable @DynamicMapping(DynamicMappingValue.False) @Field(
type = FieldType.Object) private Map<String, Object> objectMap;
@Nullable @DynamicMapping(DynamicMappingValue.False) @Field(
type = FieldType.Nested) private List<Map<String, Object>> nestedObjectMap;
@Nullable @Nullable
public Author getAuthor() { public Author getAuthor() {