Fix FieldType mapping.

Original PullRequest #2026
Closes #2024

(cherry picked from commit f7a6a97c4e2fcde86fa182f599e548a75ce73865)
This commit is contained in:
Peter-Josef Meisch 2021-12-13 21:32:26 +01:00
parent 083a38ed57
commit f3f9ca4002
No known key found for this signature in database
GPG Key ID: DE108246970C7708
7 changed files with 400 additions and 176 deletions

View File

@ -46,6 +46,16 @@ public @interface CompletionContext {
* @since 4.3 * @since 4.3
*/ */
enum ContextMappingType { enum ContextMappingType {
CATEGORY, GEO CATEGORY("category"), GEO("geo");
private final String mappedName;
ContextMappingType(String mappedName) {
this.mappedName = mappedName;
}
public String getMappedName() {
return mappedName;
}
} }
} }

View File

@ -17,7 +17,7 @@ package org.springframework.data.elasticsearch.annotations;
/** /**
* Values for the {@code dynamic} mapping parameter. * Values for the {@code dynamic} mapping parameter.
* *
* @author Sascha Woo * @author Sascha Woo
* @since 4.3 * @since 4.3
*/ */
@ -25,26 +25,36 @@ public enum Dynamic {
/** /**
* New fields are added to the mapping. * New fields are added to the mapping.
*/ */
TRUE, TRUE("true"),
/** /**
* New fields are added to the mapping as * New fields are added to the mapping as
* <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime.html">runtime fields</a>. These * <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/runtime.html">runtime fields</a>. These
* fields are not indexed, and are loaded from {@code _source} at query time. * fields are not indexed, and are loaded from {@code _source} at query time.
*/ */
RUNTIME, RUNTIME("runtime"),
/** /**
* New fields are ignored. These fields will not be indexed or searchable, but will still appear in the * New fields are ignored. These fields will not be indexed or searchable, but will still appear in the
* {@code _source} field of returned hits. These fields will not be added to the mapping, and new fields must be added * {@code _source} field of returned hits. These fields will not be added to the mapping, and new fields must be added
* explicitly. * explicitly.
*/ */
FALSE, FALSE("false"),
/** /**
* If new fields are detected, an exception is thrown and the document is rejected. New fields must be explicitly * If new fields are detected, an exception is thrown and the document is rejected. New fields must be explicitly
* added to the mapping. * added to the mapping.
*/ */
STRICT, STRICT("strict"),
/** /**
* Inherit the dynamic setting from their parent object or from the mapping type. * Inherit the dynamic setting from their parent object or from the mapping type.
*/ */
INHERIT INHERIT("nherit");
private final String mappedName;
Dynamic(String mappedName) {
this.mappedName = mappedName;
}
public String getMappedName() {
return mappedName;
}
} }

View File

@ -17,13 +17,23 @@ package org.springframework.data.elasticsearch.annotations;
/** /**
* values for the {@link DynamicMapping annotation} * values for the {@link DynamicMapping annotation}
* *
* @author Peter-Josef Meisch * @author Peter-Josef Meisch
* @author Sascha Woo * @author Sascha Woo
* @since 4.0 * @since 4.0
* @deprecated since 4.3, use {@link Document#dynamic()} or {@link Field#dynamic()} instead. * @deprecated since 4.3, use {@link Document#dynamic()} or {@link Field#dynamic()} instead.
*/ */
@Deprecated @Deprecated
public enum DynamicMappingValue { public enum DynamicMappingValue {
True, False, Strict True("true"), False("false"), Strict("strict");
private final String mappedName;
DynamicMappingValue(String mappedName) {
this.mappedName = mappedName;
}
public String getMappedName() {
return mappedName;
}
} }

View File

@ -26,40 +26,51 @@ package org.springframework.data.elasticsearch.annotations;
* @author Morgan Lutz * @author Morgan Lutz
*/ */
public enum FieldType { public enum FieldType {
Auto, // Auto("auto"), //
Text, // Text("text"), //
Keyword, // Keyword("keyword"), //
Long, // Long("long"), //
Integer, // Integer("integer"), //
Short, // Short("short"), //
Byte, // Byte("byte"), //
Double, // Double("double"), //
Float, // Float("float"), //
Half_Float, // Half_Float("half_float"), //
Scaled_Float, // Scaled_Float("scaled_float"), //
Date, // Date("date"), //
Date_Nanos, // Date_Nanos("date_nanos"), //
Boolean, // Boolean("boolean"), //
Binary, // Binary("binary"), //
Integer_Range, // Integer_Range("integer_range"), //
Float_Range, // Float_Range("float_range"), //
Long_Range, // Long_Range("long_range"), //
Double_Range, // Double_Range("double_range"), //
Date_Range, // Date_Range("date_range"), //
Ip_Range, // Ip_Range("ip_range"), //
Object, // Object("object"), //
Nested, // Nested("nested"), //
Ip, // Ip("ip"), //
TokenCount, // TokenCount("token_count"), //
Percolator, // Percolator("percolator"), //
Flattened, // Flattened("flattened"), //
Search_As_You_Type, // Search_As_You_Type("search_as_you_type"), //
/** @since 4.1 */ /** @since 4.1 */
Rank_Feature, // Rank_Feature("rank_feature"), //
/** @since 4.1 */ /** @since 4.1 */
Rank_Features, // Rank_Features("rank_features"), //
/** since 4.2 */ /** since 4.2 */
Wildcard, // Wildcard("wildcard"), //
/** @since 4.2 */ /** @since 4.2 */
Dense_Vector // Dense_Vector("dense_vector") //
;
private final String mappedName;
FieldType(String mappedName) {
this.mappedName = mappedName;
}
public String getMappedName() {
return mappedName;
}
} }

View File

@ -230,8 +230,7 @@ public class MappingBuilder {
boolean writeNestedProperties = !isRootObject && (isAnyPropertyAnnotatedWithField(entity) || nestedOrObjectField); boolean writeNestedProperties = !isRootObject && (isAnyPropertyAnnotatedWithField(entity) || nestedOrObjectField);
if (writeNestedProperties) { if (writeNestedProperties) {
String type = nestedOrObjectField ? fieldType.toString().toLowerCase() String type = nestedOrObjectField ? fieldType.getMappedName() : FieldType.Object.getMappedName();
: FieldType.Object.toString().toLowerCase();
ObjectNode nestedObjectNode = objectMapper.createObjectNode(); ObjectNode nestedObjectNode = objectMapper.createObjectNode();
nestedObjectNode.put(FIELD_PARAM_TYPE, type); nestedObjectNode.put(FIELD_PARAM_TYPE, type);
@ -247,9 +246,9 @@ public class MappingBuilder {
} }
if (entity != null && entity.dynamic() != Dynamic.INHERIT) { if (entity != null && entity.dynamic() != Dynamic.INHERIT) {
objectNode.put(TYPE_DYNAMIC, entity.dynamic().name().toLowerCase()); objectNode.put(TYPE_DYNAMIC, entity.dynamic().getMappedName());
} else if (dynamicMapping != null) { } else if (dynamicMapping != null) {
objectNode.put(TYPE_DYNAMIC, dynamicMapping.value().name().toLowerCase()); objectNode.put(TYPE_DYNAMIC, dynamicMapping.value().getMappedName());
} }
ObjectNode propertiesNode = objectNode.putObject(FIELD_PROPERTIES); ObjectNode propertiesNode = objectNode.putObject(FIELD_PROPERTIES);
@ -418,7 +417,7 @@ public class MappingBuilder {
ObjectNode contextNode = contextsNode.addObject(); ObjectNode contextNode = contextsNode.addObject();
contextNode.put(FIELD_CONTEXT_NAME, context.name()); contextNode.put(FIELD_CONTEXT_NAME, context.name());
contextNode.put(FIELD_CONTEXT_TYPE, context.type().name().toLowerCase()); contextNode.put(FIELD_CONTEXT_TYPE, context.type().getMappedName());
if (context.precision().length() > 0) { if (context.precision().length() > 0) {
contextNode.put(FIELD_CONTEXT_PRECISION, context.precision()); contextNode.put(FIELD_CONTEXT_PRECISION, context.precision());
@ -450,7 +449,7 @@ public class MappingBuilder {
} }
propertiesNode.set(property.getFieldName(), objectMapper.createObjectNode() // propertiesNode.set(property.getFieldName(), objectMapper.createObjectNode() //
.put(FIELD_PARAM_TYPE, field.type().name().toLowerCase()) // .put(FIELD_PARAM_TYPE, field.type().getMappedName()) //
.put(MAPPING_ENABLED, false) // .put(MAPPING_ENABLED, false) //
); );
@ -479,9 +478,9 @@ public class MappingBuilder {
if (nestedOrObjectField) { if (nestedOrObjectField) {
if (annotation.dynamic() != Dynamic.INHERIT) { if (annotation.dynamic() != Dynamic.INHERIT) {
fieldNode.put(TYPE_DYNAMIC, annotation.dynamic().name().toLowerCase()); fieldNode.put(TYPE_DYNAMIC, annotation.dynamic().getMappedName());
} else if (dynamicMapping != null) { } else if (dynamicMapping != null) {
fieldNode.put(TYPE_DYNAMIC, dynamicMapping.value().name().toLowerCase()); fieldNode.put(TYPE_DYNAMIC, dynamicMapping.value().getMappedName());
} }
} }
} }
@ -530,9 +529,9 @@ public class MappingBuilder {
if (nestedOrObjectField) { if (nestedOrObjectField) {
if (annotation.mainField().dynamic() != Dynamic.INHERIT) { if (annotation.mainField().dynamic() != Dynamic.INHERIT) {
mainFieldNode.put(TYPE_DYNAMIC, annotation.mainField().dynamic().name().toLowerCase()); mainFieldNode.put(TYPE_DYNAMIC, annotation.mainField().dynamic().getMappedName());
} else if (dynamicMapping != null) { } else if (dynamicMapping != null) {
mainFieldNode.put(TYPE_DYNAMIC, dynamicMapping.value().name().toLowerCase()); mainFieldNode.put(TYPE_DYNAMIC, dynamicMapping.value().getMappedName());
} }
} }

View File

@ -237,7 +237,7 @@ public final class MappingParameters {
} }
if (type != FieldType.Auto) { if (type != FieldType.Auto) {
objectNode.put(FIELD_PARAM_TYPE, type.toString().toLowerCase()); objectNode.put(FIELD_PARAM_TYPE, type.getMappedName());
if (type == FieldType.Date) { if (type == FieldType.Date) {
List<String> formats = new ArrayList<>(); List<String> formats = new ArrayList<>();

View File

@ -38,10 +38,14 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import org.assertj.core.data.Percentage; import org.assertj.core.data.Percentage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.*; import org.springframework.data.elasticsearch.annotations.*;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
@ -57,6 +61,7 @@ import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm;
import org.springframework.data.elasticsearch.core.suggest.Completion; import org.springframework.data.elasticsearch.core.suggest.Completion;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.utils.IndexNameProvider;
import org.springframework.data.geo.Box; import org.springframework.data.geo.Box;
import org.springframework.data.geo.Circle; import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Point; import org.springframework.data.geo.Point;
@ -79,10 +84,25 @@ import org.springframework.test.context.ContextConfiguration;
* @author Morgan Lutz * @author Morgan Lutz
*/ */
@SpringIntegrationTest @SpringIntegrationTest
@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class }) @ContextConfiguration(classes = { MappingBuilderIntegrationTests.Config.class })
public class MappingBuilderIntegrationTests extends MappingContextBaseTests { public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
@Configuration
@Import({ ElasticsearchRestTemplateConfiguration.class })
static class Config {
@Bean
IndexNameProvider indexNameProvider() {
return new IndexNameProvider("mapping-builder");
}
}
@Autowired private ElasticsearchOperations operations; @Autowired private ElasticsearchOperations operations;
@Autowired IndexNameProvider indexNameProvider;
@BeforeEach
public void before() {
indexNameProvider.increment();
}
@Test @Test
@Order(java.lang.Integer.MAX_VALUE) @Order(java.lang.Integer.MAX_VALUE)
@ -132,8 +152,7 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
@Test // DATAES-76 @Test // DATAES-76
public void shouldAddSampleInheritedEntityDocumentToIndex() { public void shouldAddSampleInheritedEntityDocumentToIndex() {
// given // given
IndexCoordinates index = IndexCoordinates.of("test-index-sample-inherited-mapping-builder"); IndexOperations indexOps = operations.indexOps(SampleInheritedEntity.class);
IndexOperations indexOps = operations.indexOps(index);
// when // when
indexOps.create(); indexOps.create();
@ -142,11 +161,10 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
String message = "msg"; String message = "msg";
String id = "abc"; String id = "abc";
operations.index(new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex(), operations.index(new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex(),
index); IndexCoordinates.of(indexNameProvider.indexName()));
operations.indexOps(SampleInheritedEntity.class).refresh();
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build();
SearchHits<SampleInheritedEntity> result = operations.search(searchQuery, SampleInheritedEntity.class, index); SearchHits<SampleInheritedEntity> result = operations.search(searchQuery, SampleInheritedEntity.class);
// then // then
assertThat(result).hasSize(1); assertThat(result).hasSize(1);
@ -163,7 +181,7 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
IndexOperations indexOpsUser = operations.indexOps(User.class); IndexOperations indexOpsUser = operations.indexOps(User.class);
indexOpsUser.create(); indexOpsUser.create();
indexOpsUser.putMapping(User.class); indexOpsUser.putMapping(User.class);
indexNameProvider.increment();
IndexOperations indexOpsGroup = operations.indexOps(Group.class); IndexOperations indexOpsGroup = operations.indexOps(Group.class);
indexOpsGroup.create(); indexOpsGroup.create();
indexOpsGroup.putMapping(Group.class); indexOpsGroup.putMapping(Group.class);
@ -336,11 +354,19 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
@Test // #2024
@DisplayName("should map all field type values")
void shouldMapAllFieldTypeValues() {
operations.indexOps(EntityWithAllTypes.class).createWithMapping();
}
// region entities // region entities
@Document(indexName = "ignore-above-index") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class IgnoreAboveEntity { static class IgnoreAboveEntity {
@Nullable @Id private String id; @Nullable
@Nullable @Field(type = FieldType.Keyword, ignoreAbove = 10) private String message; @Id private String id;
@Nullable
@Field(type = FieldType.Keyword, ignoreAbove = 10) private String message;
@Nullable @Nullable
public String getId() { public String getId() {
@ -365,57 +391,76 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
@Document(indexName = "fieldname-index") @Document(indexName = "fieldname-index")
static class IdEntity { static class IdEntity {
@Nullable @Id @Field("id-property") private String id; @Nullable
@Id
@Field("id-property") private String id;
} }
@Document(indexName = "fieldname-index") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class TextEntity { static class TextEntity {
@Nullable @Id @Field("id-property") private String id; @Nullable
@Id
@Field("id-property") private String id;
@Field(name = "text-property", type = FieldType.Text) // @Field(name = "text-property", type = FieldType.Text) //
@Nullable private String textProperty; @Nullable private String textProperty;
} }
@Document(indexName = "fieldname-index") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class MappingEntity { static class MappingEntity {
@Nullable @Id @Field("id-property") private String id; @Nullable
@Id
@Field("id-property") private String id;
@Field("mapping-property") @Mapping(mappingPath = "/mappings/test-field-analyzed-mappings.json") // @Field("mapping-property")
@Mapping(mappingPath = "/mappings/test-field-analyzed-mappings.json") //
@Nullable private byte[] mappingProperty; @Nullable private byte[] mappingProperty;
} }
@Document(indexName = "fieldname-index") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class GeoPointEntity { static class GeoPointEntity {
@Nullable @Id @Field("id-property") private String id; @Nullable
@Id
@Field("id-property") private String id;
@Nullable @Field("geopoint-property") private GeoPoint geoPoint; @Nullable
@Field("geopoint-property") private GeoPoint geoPoint;
} }
@Document(indexName = "fieldname-index") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class CircularEntity { static class CircularEntity {
@Nullable @Id @Field("id-property") private String id; @Nullable
@Id
@Field("id-property") private String id;
@Nullable @Field(name = "circular-property", type = FieldType.Object, ignoreFields = { "circular-property" }) // @Nullable
@Field(name = "circular-property", type = FieldType.Object, ignoreFields = { "circular-property" }) //
private CircularEntity circularProperty; private CircularEntity circularProperty;
} }
@Document(indexName = "fieldname-index") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class CompletionEntity { static class CompletionEntity {
@Nullable @Id @Field("id-property") private String id; @Nullable
@Id
@Field("id-property") private String id;
@Nullable @Field("completion-property") @CompletionField(maxInputLength = 100) // @Nullable
@Field("completion-property")
@CompletionField(maxInputLength = 100) //
private Completion suggest; private Completion suggest;
} }
@Document(indexName = "fieldname-index") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class MultiFieldEntity { static class MultiFieldEntity {
@Nullable @Id @Field("id-property") private String id; @Nullable
@Id
@Field("id-property") private String id;
@Nullable // @Nullable //
@MultiField(mainField = @Field(name = "main-field", type = FieldType.Text, analyzer = "whitespace"), @MultiField(mainField = @Field(name = "main-field", type = FieldType.Text, analyzer = "whitespace"),
@ -425,13 +470,17 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "test-index-book-mapping-builder") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class Book { static class Book {
@Nullable @Id private String id; @Nullable
@Id private String id;
@Nullable private String name; @Nullable private String name;
@Nullable @Field(type = FieldType.Object) private Author author; @Nullable
@Nullable @Field(type = FieldType.Nested) private Map<Integer, Collection<String>> buckets = new HashMap<>(); @Field(type = FieldType.Object) private Author author;
@Nullable @MultiField(mainField = @Field(type = FieldType.Text, analyzer = "whitespace"), @Nullable
@Field(type = FieldType.Nested) private Map<Integer, Collection<String>> buckets = new HashMap<>();
@Nullable
@MultiField(mainField = @Field(type = FieldType.Text, analyzer = "whitespace"),
otherFields = { @InnerField(suffix = "prefix", type = FieldType.Text, analyzer = "stop", otherFields = { @InnerField(suffix = "prefix", type = FieldType.Text, analyzer = "stop",
searchAnalyzer = "standard") }) private String description; searchAnalyzer = "standard") }) private String description;
@ -481,11 +530,12 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "test-index-simple-recursive-mapping-builder") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class SimpleRecursiveEntity { static class SimpleRecursiveEntity {
@Nullable @Id private String id; @Nullable
@Nullable @Field(type = FieldType.Object, @Id private String id;
ignoreFields = { "circularObject" }) private SimpleRecursiveEntity circularObject; @Nullable
@Field(type = FieldType.Object, ignoreFields = { "circularObject" }) private SimpleRecursiveEntity circularObject;
@Nullable @Nullable
public String getId() { public String getId() {
@ -506,12 +556,16 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "test-copy-to-mapping-builder") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class CopyToEntity { static class CopyToEntity {
@Nullable @Id private String id; @Nullable
@Nullable @Field(type = FieldType.Keyword, copyTo = "name") private String firstName; @Id private String id;
@Nullable @Field(type = FieldType.Keyword, copyTo = "name") private String lastName; @Nullable
@Nullable @Field(type = FieldType.Keyword) private String name; @Field(type = FieldType.Keyword, copyTo = "name") private String firstName;
@Nullable
@Field(type = FieldType.Keyword, copyTo = "name") private String lastName;
@Nullable
@Field(type = FieldType.Keyword) private String name;
@Nullable @Nullable
public String getId() { public String getId() {
@ -550,12 +604,15 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "test-index-normalizer-mapping-builder") @Document(indexName = "#{@indexNameProvider.indexName()}")
@Setting(settingPath = "/settings/test-normalizer.json") @Setting(settingPath = "/settings/test-normalizer.json")
static class NormalizerEntity { static class NormalizerEntity {
@Nullable @Id private String id; @Nullable
@Nullable @Field(type = FieldType.Keyword, normalizer = "lower_case_normalizer") private String name; @Id private String id;
@Nullable @MultiField(mainField = @Field(type = FieldType.Text), otherFields = { @InnerField(suffix = "lower_case", @Nullable
@Field(type = FieldType.Keyword, normalizer = "lower_case_normalizer") private String name;
@Nullable
@MultiField(mainField = @Field(type = FieldType.Text), otherFields = { @InnerField(suffix = "lower_case",
type = FieldType.Keyword, normalizer = "lower_case_normalizer") }) private String description; type = FieldType.Keyword, normalizer = "lower_case_normalizer") }) private String description;
@Nullable @Nullable
@ -610,10 +667,11 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "test-index-sample-inherited-mapping-builder") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class SampleInheritedEntity extends AbstractInheritedEntity { static class SampleInheritedEntity extends AbstractInheritedEntity {
@Nullable @Field(type = Text, index = false, store = true, analyzer = "standard") private String message; @Nullable
@Field(type = Text, index = false, store = true, analyzer = "standard") private String message;
@Nullable @Nullable
public String getMessage() { public String getMessage() {
@ -656,11 +714,13 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "test-index-stock-mapping-builder") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class StockPrice { static class StockPrice {
@Nullable @Id private String id; @Nullable
@Id private String id;
@Nullable private String symbol; @Nullable private String symbol;
@Nullable @Field(type = FieldType.Double) private BigDecimal price; @Nullable
@Field(type = FieldType.Double) private BigDecimal price;
@Nullable @Nullable
public String getId() { public String getId() {
@ -691,8 +751,10 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
static class AbstractInheritedEntity { static class AbstractInheritedEntity {
@Nullable @Id private String id; @Nullable
@Nullable @Field(type = FieldType.Date, format = DateFormat.date_time, index = false) private Date createdDate; @Id private String id;
@Nullable
@Field(type = FieldType.Date, format = DateFormat.date_time, index = false) private Date createdDate;
@Nullable @Nullable
public String getId() { public String getId() {
@ -713,21 +775,27 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "test-index-geo-mapping-builder") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class GeoEntity { static class GeoEntity {
@Nullable @Id private String id; @Nullable
@Id private String id;
// geo shape - Spring Data // geo shape - Spring Data
@Nullable private Box box; @Nullable private Box box;
@Nullable private Circle circle; @Nullable private Circle circle;
@Nullable private Polygon polygon; @Nullable private Polygon polygon;
// geo point - Custom implementation + Spring Data // geo point - Custom implementation + Spring Data
@Nullable @GeoPointField private Point pointA; @Nullable
@GeoPointField private Point pointA;
@Nullable private GeoPoint pointB; @Nullable private GeoPoint pointB;
@Nullable @GeoPointField private String pointC; @Nullable
@Nullable @GeoPointField private double[] pointD; @GeoPointField private String pointC;
@Nullable
@GeoPointField private double[] pointD;
// geo shape, until e have the classes for this, us a strng // geo shape, until e have the classes for this, us a strng
@Nullable @GeoShapeField private String shape1; @Nullable
@Nullable @GeoShapeField(coerce = true, ignoreMalformed = true, ignoreZValue = false, @GeoShapeField private String shape1;
@Nullable
@GeoShapeField(coerce = true, ignoreMalformed = true, ignoreZValue = false,
orientation = GeoShapeField.Orientation.clockwise) private String shape2; orientation = GeoShapeField.Orientation.clockwise) private String shape2;
@Nullable @Nullable
@ -821,17 +889,21 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "test-index-user-mapping-builder") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class User { static class User {
@Nullable @Id private String id; @Nullable
@Id private String id;
@Field(type = FieldType.Nested, ignoreFields = { "users" }) private Set<Group> groups = new HashSet<>(); @Field(type = FieldType.Nested, ignoreFields = { "users" }) private Set<Group> groups = new HashSet<>();
} }
@Document(indexName = "test-index-group-mapping-builder") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class Group { static class Group {
@Nullable @Id String id; @Nullable
@Id String id;
@Field(type = FieldType.Nested, ignoreFields = { "groups" }) private Set<User> users = new HashSet<>(); @Field(type = FieldType.Nested, ignoreFields = { "groups" }) private Set<User> users = new HashSet<>();
} }
@ -848,11 +920,14 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "completion") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class CompletionDocument { static class CompletionDocument {
@Nullable @Id private String id; @Nullable
@Nullable @CompletionField(contexts = { @CompletionContext(name = "location", @Id private String id;
type = CompletionContext.ContextMappingType.GEO, path = "proppath") }) private Completion suggest; @Nullable
@CompletionField(contexts = { @CompletionContext(name = "location", type = CompletionContext.ContextMappingType.GEO,
path = "proppath") }) private Completion suggest;
@Nullable @Nullable
public String getId() { public String getId() {
@ -873,9 +948,10 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "test-index-entity-with-seq-no-primary-term-mapping-builder") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class EntityWithSeqNoPrimaryTerm { static class EntityWithSeqNoPrimaryTerm {
@Nullable @Field(type = Object) private SeqNoPrimaryTerm seqNoPrimaryTerm; @Nullable
@Field(type = Object) private SeqNoPrimaryTerm seqNoPrimaryTerm;
@Nullable @Nullable
public SeqNoPrimaryTerm getSeqNoPrimaryTerm() { public SeqNoPrimaryTerm getSeqNoPrimaryTerm() {
@ -888,10 +964,14 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
static class RankFeatureEntity { static class RankFeatureEntity {
@Nullable @Id private String id; @Nullable
@Nullable @Field(type = FieldType.Rank_Feature) private Integer pageRank; @Id private String id;
@Nullable @Field(type = FieldType.Rank_Feature, positiveScoreImpact = false) private Integer urlLength; @Nullable
@Nullable @Field(type = FieldType.Rank_Features) private Map<String, Integer> topics; @Field(type = FieldType.Rank_Feature) private Integer pageRank;
@Nullable
@Field(type = FieldType.Rank_Feature, positiveScoreImpact = false) private Integer urlLength;
@Nullable
@Field(type = FieldType.Rank_Features) private Map<String, Integer> topics;
@Nullable @Nullable
public String getId() { public String getId() {
@ -930,18 +1010,25 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "termvectors-test") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class TermVectorFieldEntity { static class TermVectorFieldEntity {
@Nullable @Id private String id; @Nullable
@Nullable @Field(type = FieldType.Text, termVector = TermVector.no) private String no; @Id private String id;
@Nullable @Field(type = FieldType.Text, termVector = TermVector.yes) private String yes; @Nullable
@Nullable @Field(type = FieldType.Text, termVector = TermVector.with_positions) private String with_positions; @Field(type = FieldType.Text, termVector = TermVector.no) private String no;
@Nullable @Field(type = FieldType.Text, termVector = TermVector.with_offsets) private String with_offsets; @Nullable
@Nullable @Field(type = FieldType.Text, @Field(type = FieldType.Text, termVector = TermVector.yes) private String yes;
termVector = TermVector.with_positions_offsets) private String with_positions_offsets; @Nullable
@Nullable @Field(type = FieldType.Text, @Field(type = FieldType.Text, termVector = TermVector.with_positions) private String with_positions;
@Nullable
@Field(type = FieldType.Text, termVector = TermVector.with_offsets) private String with_offsets;
@Nullable
@Field(type = FieldType.Text, termVector = TermVector.with_positions_offsets) private String with_positions_offsets;
@Nullable
@Field(type = FieldType.Text,
termVector = TermVector.with_positions_payloads) private String with_positions_payloads; termVector = TermVector.with_positions_payloads) private String with_positions_payloads;
@Nullable @Field(type = FieldType.Text, @Nullable
@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;
@Nullable @Nullable
@ -1017,10 +1104,12 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "wildcard-test") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class WildcardEntity { static class WildcardEntity {
@Nullable @Field(type = Wildcard) private String wildcardWithoutParams; @Nullable
@Nullable @Field(type = Wildcard, nullValue = "WILD", ignoreAbove = 42) private String wildcardWithParams; @Field(type = Wildcard) private String wildcardWithoutParams;
@Nullable
@Field(type = Wildcard, nullValue = "WILD", ignoreAbove = 42) private String wildcardWithParams;
@Nullable @Nullable
public String getWildcardWithoutParams() { public String getWildcardWithoutParams() {
@ -1041,11 +1130,13 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "disabled-entity-mapping") @Document(indexName = "#{@indexNameProvider.indexName()}")
@Mapping(enabled = false) @Mapping(enabled = false)
static class DisabledMappingEntity { static class DisabledMappingEntity {
@Nullable @Id private String id; @Nullable
@Nullable @Field(type = Text) private String text; @Id private String id;
@Nullable
@Field(type = Text) private String text;
@Nullable @Nullable
public String getId() { public String getId() {
@ -1068,9 +1159,13 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
@Document(indexName = "disabled-property-mapping") @Document(indexName = "disabled-property-mapping")
static class DisabledMappingProperty { static class DisabledMappingProperty {
@Nullable @Id private String id; @Nullable
@Nullable @Field(type = Text) private String text; @Id private String id;
@Nullable @Mapping(enabled = false) @Field(type = Object) private Object object; @Nullable
@Field(type = Text) private String text;
@Nullable
@Mapping(enabled = false)
@Field(type = Object) private Object object;
@Nullable @Nullable
public String getId() { public String getId() {
@ -1100,10 +1195,12 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "densevector-test") @Document(indexName = "#{@indexNameProvider.indexName()}")
static class DenseVectorEntity { static class DenseVectorEntity {
@Nullable @Id private String id; @Nullable
@Nullable @Field(type = Dense_Vector, dims = 3) private float[] dense_vector; @Id private String id;
@Nullable
@Field(type = Dense_Vector, dims = 3) private float[] dense_vector;
@Nullable @Nullable
public String getId() { public String getId() {
@ -1124,15 +1221,19 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "dynamic-mapping-annotation") @Document(indexName = "#{@indexNameProvider.indexName()}")
@DynamicMapping(DynamicMappingValue.False) @DynamicMapping(DynamicMappingValue.False)
static class DynamicMappingAnnotationEntity { static class DynamicMappingAnnotationEntity {
@Nullable @DynamicMapping(DynamicMappingValue.Strict) @Field(type = FieldType.Object) private Author author; @Nullable
@Nullable @DynamicMapping(DynamicMappingValue.False) @Field( @DynamicMapping(DynamicMappingValue.Strict)
type = FieldType.Object) private Map<String, Object> objectMap; @Field(type = FieldType.Object) private Author author;
@Nullable @DynamicMapping(DynamicMappingValue.False) @Field( @Nullable
type = FieldType.Nested) private List<Map<String, Object>> nestedObjectMap; @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() {
@ -1144,57 +1245,140 @@ public class MappingBuilderIntegrationTests extends MappingContextBaseTests {
} }
} }
@Document(indexName = "dynamic-mapping", dynamic = Dynamic.FALSE) @Document(indexName = "#{@indexNameProvider.indexName()}")
static class DynamicMappingEntity { static class DynamicMappingEntity {
@Nullable @Field(type = FieldType.Object) // @Nullable
@Field(type = FieldType.Object) //
private Map<String, Object> objectInherit; private Map<String, Object> objectInherit;
@Nullable @Field(type = FieldType.Object, dynamic = Dynamic.FALSE) // @Nullable
@Field(type = FieldType.Object, dynamic = Dynamic.FALSE) //
private Map<String, Object> objectFalse; private Map<String, Object> objectFalse;
@Nullable @Field(type = FieldType.Object, dynamic = Dynamic.TRUE) // @Nullable
@Field(type = FieldType.Object, dynamic = Dynamic.TRUE) //
private Map<String, Object> objectTrue; private Map<String, Object> objectTrue;
@Nullable @Field(type = FieldType.Object, dynamic = Dynamic.STRICT) // @Nullable
@Field(type = FieldType.Object, dynamic = Dynamic.STRICT) //
private Map<String, Object> objectStrict; private Map<String, Object> objectStrict;
@Nullable @Field(type = FieldType.Object, dynamic = Dynamic.RUNTIME) // @Nullable
@Field(type = FieldType.Object, dynamic = Dynamic.RUNTIME) //
private Map<String, Object> objectRuntime; private Map<String, Object> objectRuntime;
@Nullable @Field(type = FieldType.Nested) // @Nullable
@Field(type = FieldType.Nested) //
private List<Map<String, Object>> nestedObjectInherit; private List<Map<String, Object>> nestedObjectInherit;
@Nullable @Field(type = FieldType.Nested, dynamic = Dynamic.FALSE) // @Nullable
@Field(type = FieldType.Nested, dynamic = Dynamic.FALSE) //
private List<Map<String, Object>> nestedObjectFalse; private List<Map<String, Object>> nestedObjectFalse;
@Nullable @Field(type = FieldType.Nested, dynamic = Dynamic.TRUE) // @Nullable
@Field(type = FieldType.Nested, dynamic = Dynamic.TRUE) //
private List<Map<String, Object>> nestedObjectTrue; private List<Map<String, Object>> nestedObjectTrue;
@Nullable @Field(type = FieldType.Nested, dynamic = Dynamic.STRICT) // @Nullable
@Field(type = FieldType.Nested, dynamic = Dynamic.STRICT) //
private List<Map<String, Object>> nestedObjectStrict; private List<Map<String, Object>> nestedObjectStrict;
@Nullable @Field(type = FieldType.Nested, dynamic = Dynamic.RUNTIME) // @Nullable
@Field(type = FieldType.Nested, dynamic = Dynamic.RUNTIME) //
private List<Map<String, Object>> nestedObjectRuntime; private List<Map<String, Object>> nestedObjectRuntime;
} }
@Document(indexName = "dynamic-detection-mapping-true") @Document(indexName = "#{@indexNameProvider.indexName()}")
@Mapping(dateDetection = Mapping.Detection.TRUE, numericDetection = Mapping.Detection.TRUE, @Mapping(dateDetection = Mapping.Detection.TRUE, numericDetection = Mapping.Detection.TRUE,
dynamicDateFormats = { "MM/dd/yyyy" }) dynamicDateFormats = { "MM/dd/yyyy" })
private static class DynamicDetectionMapping { private static class DynamicDetectionMapping {
@Id @Nullable private String id; @Id
@Nullable private String id;
} }
@Document(indexName = "runtime-fields") @Document(indexName = "#{@indexNameProvider.indexName()}")
@Mapping(runtimeFieldsPath = "/mappings/runtime-fields.json") @Mapping(runtimeFieldsPath = "/mappings/runtime-fields.json")
private static class RuntimeFieldEntity { private static class RuntimeFieldEntity {
@Id @Nullable private String id; @Id
@Field(type = Date, format = DateFormat.epoch_millis, name = "@timestamp") @Nullable private Instant timestamp; @Nullable private String id;
@Field(type = Date, format = DateFormat.epoch_millis, name = "@timestamp")
@Nullable private Instant timestamp;
} }
@Document(indexName = "fields-excluded-from-source") @Document(indexName = "#{@indexNameProvider.indexName()}")
private static class ExcludedFieldEntity { private static class ExcludedFieldEntity {
@Id @Nullable private String id; @Id
@Nullable @Field(name = "excluded-date", type = Date, format = DateFormat.date, @Nullable private String id;
@Nullable
@Field(name = "excluded-date", type = Date, format = DateFormat.date,
excludeFromSource = true) private LocalDate excludedDate; excludeFromSource = true) private LocalDate excludedDate;
@Nullable @Field(type = Nested) private NestedExcludedFieldEntity nestedEntity; @Nullable
@Field(type = Nested) private NestedExcludedFieldEntity nestedEntity;
} }
private static class NestedExcludedFieldEntity { private static class NestedExcludedFieldEntity {
@Nullable @Field(name = "excluded-text", type = Text, excludeFromSource = true) private String excludedText; @Nullable
@Field(name = "excluded-text", type = Text, excludeFromSource = true) private String excludedText;
} }
@Document(indexName = "#{@indexNameProvider.indexName()}")
private static class EntityWithAllTypes {
@Nullable
@Field(type = FieldType.Auto) String autoField;
@Nullable
@Field(type = FieldType.Text) String textField;
@Nullable
@Field(type = FieldType.Keyword) String keywordField;
@Nullable
@Field(type = FieldType.Long) String longField;
@Nullable
@Field(type = FieldType.Integer) String integerField;
@Nullable
@Field(type = FieldType.Short) String shortField;
@Nullable
@Field(type = FieldType.Byte) String byteField;
@Nullable
@Field(type = FieldType.Double) String doubleField;
@Nullable
@Field(type = FieldType.Float) String floatField;
@Nullable
@Field(type = FieldType.Half_Float) String halfFloatField;
@Nullable
@Field(type = FieldType.Scaled_Float) String scaledFloatField;
@Nullable
@Field(type = FieldType.Date) String dateField;
@Nullable
@Field(type = FieldType.Date_Nanos) String dateNanosField;
@Nullable
@Field(type = FieldType.Boolean) String booleanField;
@Nullable
@Field(type = FieldType.Binary) String binaryField;
@Nullable
@Field(type = FieldType.Integer_Range) String integerRangeField;
@Nullable
@Field(type = FieldType.Float_Range) String floatRangeField;
@Nullable
@Field(type = FieldType.Long_Range) String longRangeField;
@Nullable
@Field(type = FieldType.Double_Range) String doubleRangeField;
@Nullable
@Field(type = FieldType.Date_Range) String dateRangeField;
@Nullable
@Field(type = FieldType.Ip_Range) String ipRangeField;
@Nullable
@Field(type = FieldType.Object) String objectField;
@Nullable
@Field(type = FieldType.Nested) String nestedField;
@Nullable
@Field(type = FieldType.Ip) String ipField;
@Nullable
@Field(type = FieldType.TokenCount, analyzer = "standard") String tokenCountField;
@Nullable
@Field(type = FieldType.Percolator) String percolatorField;
@Nullable
@Field(type = FieldType.Flattened) String flattenedField;
@Nullable
@Field(type = FieldType.Search_As_You_Type) String searchAsYouTypeField;
@Nullable
@Field(type = FieldType.Rank_Feature) String rankFeatureField;
@Nullable
@Field(type = FieldType.Rank_Features) String rankFeaturesField;
@Nullable
@Field(type = FieldType.Wildcard) String wildcardField;
@Nullable
@Field(type = FieldType.Dense_Vector, dims = 1) String denseVectorField;
}
// endregion // endregion
} }