Skip to content

DynamicMapping annotation should be applicable to any object field. #1779

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ private void buildPropertyMapping(XContentBuilder builder, boolean isRootObject,
Field fieldAnnotation = property.findAnnotation(Field.class);
boolean isCompletionProperty = property.isCompletionProperty();
boolean isNestedOrObjectProperty = isNestedOrObjectProperty(property);
DynamicMapping dynamicMapping = property.findAnnotation(DynamicMapping.class);

if (!isCompletionProperty && property.isEntity() && hasRelevantAnnotation(property)) {

Expand All @@ -259,7 +260,7 @@ private void buildPropertyMapping(XContentBuilder builder, boolean isRootObject,
: null;

mapEntity(builder, persistentEntity, false, property.getFieldName(), true, fieldAnnotation.type(),
fieldAnnotation, property.findAnnotation(DynamicMapping.class));
fieldAnnotation, dynamicMapping);
return;
}
}
Expand All @@ -274,9 +275,9 @@ private void buildPropertyMapping(XContentBuilder builder, boolean isRootObject,
if (isRootObject && fieldAnnotation != null && property.isIdProperty()) {
applyDefaultIdFieldMapping(builder, property);
} else if (multiField != null) {
addMultiFieldMapping(builder, property, multiField, isNestedOrObjectProperty);
addMultiFieldMapping(builder, property, multiField, isNestedOrObjectProperty, dynamicMapping);
} else if (fieldAnnotation != null) {
addSingleFieldMapping(builder, property, fieldAnnotation, isNestedOrObjectProperty);
addSingleFieldMapping(builder, property, fieldAnnotation, isNestedOrObjectProperty, dynamicMapping);
}
}

Expand Down Expand Up @@ -377,7 +378,7 @@ private void applyDisabledPropertyMapping(XContentBuilder builder, Elasticsearch
* @throws IOException
*/
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
XContentBuilder propertyBuilder = jsonBuilder().startObject();
Expand All @@ -389,6 +390,11 @@ private void addSingleFieldMapping(XContentBuilder builder, ElasticsearchPersist
}

builder.startObject(property.getFieldName());

if (nestedOrObjectField && dynamicMapping != null) {
builder.field(TYPE_DYNAMIC, dynamicMapping.value().name().toLowerCase());
}

addFieldMappingParameters(builder, annotation, nestedOrObjectField);
builder.endObject();
}
Expand Down Expand Up @@ -429,10 +435,15 @@ private void addJoinFieldMapping(XContentBuilder builder, ElasticsearchPersisten
* @throws IOException
*/
private void addMultiFieldMapping(XContentBuilder builder, ElasticsearchPersistentProperty property,
MultiField annotation, boolean nestedOrObjectField) throws IOException {
MultiField annotation, boolean nestedOrObjectField, @Nullable DynamicMapping dynamicMapping) throws IOException {

// main field
builder.startObject(property.getFieldName());

if (nestedOrObjectField && dynamicMapping != null) {
builder.field(TYPE_DYNAMIC, dynamicMapping.value().name().toLowerCase());
}

addFieldMappingParameters(builder, annotation.mainField(), nestedOrObjectField);

// inner fields
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,16 @@ void shouldWriteMappingForDisabledProperty() {
indexOps.delete();
}

@Test // #1767
@DisplayName("should write dynamic mapping entries")
void shouldWriteDynamicMappingEntries() {

IndexOperations indexOps = operations.indexOps(DynamicMappingEntity.class);
indexOps.create();
indexOps.putMapping();
indexOps.delete();
}

@Document(indexName = "ignore-above-index")
static class IgnoreAboveEntity {
@Nullable @Id private String id;
Expand Down Expand Up @@ -1082,4 +1092,25 @@ public void setDense_vector(@Nullable float[] dense_vector) {
this.dense_vector = dense_vector;
}
}

@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;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.elasticsearch.search.suggest.completion.context.ContextMapping;
Expand Down Expand Up @@ -415,23 +416,42 @@ public void shouldSetFieldMappingProperties() throws JSONException {
assertEquals(expected, mapping, false);
}

@Test
@Test // DATAES-148, #1767
void shouldWriteDynamicMappingSettings() throws JSONException {

String expected = "{\n" + //
" \"dynamic\": \"false\",\n" + //
" \"properties\": {\n" + //
" \"author\": {\n" + //
" \"dynamic\": \"strict\",\n" + //
" \"type\": \"object\",\n" + //
" \"properties\": {}\n" + //
" \"dynamic\": \"false\",\n" + //
" \"properties\": {\n" + //
" \"_class\": {\n" + //
" \"type\": \"keyword\",\n" + //
" \"index\": false,\n" + //
" \"doc_values\": false\n" + //
" },\n" + //
" \"author\": {\n" + //
" \"type\": \"object\",\n" + //
" \"dynamic\": \"strict\",\n" + //
" \"properties\": {\n" + //
" \"_class\": {\n" + //
" \"type\": \"keyword\",\n" + //
" \"index\": false,\n" + //
" \"doc_values\": false\n" + //
" }\n" + //
" }\n" + //
" },\n" + //
" \"objectMap\": {\n" + //
" \"type\": \"object\",\n" + //
" \"dynamic\": \"false\"\n" + //
" },\n" + //
" \"nestedObjectMap\": {\n" + //
" \"type\": \"nested\",\n" + //
" \"dynamic\": \"false\"\n" + //
" }\n" + //
"}\n";
" }\n" + //
"}"; //

String mapping = getMappingBuilder().buildPropertyMapping(ConfigureDynamicMappingEntity.class);

assertEquals(expected, mapping, false);
assertEquals(expected, mapping, true);
}

@Test // DATAES-784
Expand Down Expand Up @@ -608,39 +628,38 @@ void shouldWriteTypeHintEntries() throws JSONException {
assertEquals(expected, mapping, false);
}

@Test // #1727
@DisplayName("should map according to the annotated properties")
void shouldMapAccordingToTheAnnotatedProperties() throws JSONException {

String expected = "{\n" +
" \"properties\": {\n" + //
" \"field1\": {\n" + //
" \"type\": \"date\",\n" + //
" \"format\": \"date_optional_time||epoch_millis\"\n" + //
" },\n" + //
" \"field2\": {\n" + //
" \"type\": \"date\",\n" + //
" \"format\": \"basic_date\"\n" + //
" },\n" + //
" \"field3\": {\n" + //
" \"type\": \"date\",\n" + //
" \"format\": \"basic_date||basic_time\"\n" + //
" },\n" + //
" \"field4\": {\n" + //
" \"type\": \"date\",\n" + //
" \"format\": \"date_optional_time||epoch_millis||dd.MM.uuuu\"\n" + //
" },\n" + //
" \"field5\": {\n" + //
" \"type\": \"date\",\n" + //
" \"format\": \"dd.MM.uuuu\"\n" + //
" }\n" + //
" }\n" + //
"}"; //

String mapping = getMappingBuilder().buildPropertyMapping(DateFormatsEntity.class);

assertEquals(expected, mapping, false);
}
@Test // #1727
@DisplayName("should map according to the annotated properties")
void shouldMapAccordingToTheAnnotatedProperties() throws JSONException {

String expected = "{\n" + " \"properties\": {\n" + //
" \"field1\": {\n" + //
" \"type\": \"date\",\n" + //
" \"format\": \"date_optional_time||epoch_millis\"\n" + //
" },\n" + //
" \"field2\": {\n" + //
" \"type\": \"date\",\n" + //
" \"format\": \"basic_date\"\n" + //
" },\n" + //
" \"field3\": {\n" + //
" \"type\": \"date\",\n" + //
" \"format\": \"basic_date||basic_time\"\n" + //
" },\n" + //
" \"field4\": {\n" + //
" \"type\": \"date\",\n" + //
" \"format\": \"date_optional_time||epoch_millis||dd.MM.uuuu\"\n" + //
" },\n" + //
" \"field5\": {\n" + //
" \"type\": \"date\",\n" + //
" \"format\": \"dd.MM.uuuu\"\n" + //
" }\n" + //
" }\n" + //
"}"; //

String mapping = getMappingBuilder().buildPropertyMapping(DateFormatsEntity.class);

assertEquals(expected, mapping, false);
}

@Document(indexName = "ignore-above-index")
static class IgnoreAboveEntity {
Expand All @@ -666,7 +685,6 @@ public void setMessage(@Nullable String message) {
}
}


static class FieldNameEntity {

@Document(indexName = "fieldname-index")
Expand Down Expand Up @@ -1199,6 +1217,10 @@ static class FieldMappingParameters {
static class ConfigureDynamicMappingEntity {

@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() {
Expand Down Expand Up @@ -1474,7 +1496,8 @@ static class DateFormatsEntity {
@Nullable @Id private String id;
@Nullable @Field(type = FieldType.Date) private LocalDateTime field1;
@Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date) private LocalDateTime field2;
@Nullable @Field(type = FieldType.Date, format = { DateFormat.basic_date, DateFormat.basic_time }) private LocalDateTime field3;
@Nullable @Field(type = FieldType.Date,
format = { DateFormat.basic_date, DateFormat.basic_time }) private LocalDateTime field3;
@Nullable @Field(type = FieldType.Date, pattern = "dd.MM.uuuu") private LocalDateTime field4;
@Nullable @Field(type = FieldType.Date, format = {}, pattern = "dd.MM.uuuu") private LocalDateTime field5;

Expand Down