From 01cda354244b0ecd1dd45bd0fc84eff112747052 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 6 May 2019 15:58:24 +0200 Subject: [PATCH] DATAES-568 - Polishing. Add package-info and nullability annotations to org.springframework.data.elasticsearch.core.mapping. Extract method to avoid excessive nesting. Add ticket references/convert old references to test methods. Move test models to inner classes. Use static imports for JSON Assert. Formatting. Original pull request: #281. --- .../core/ElasticsearchRestTemplate.java | 28 +- .../core/ElasticsearchTemplate.java | 2 +- .../elasticsearch/core/MappingBuilder.java | 175 +++++++------ .../SimpleElasticsearchMappingContext.java | 8 +- .../SimpleElasticsearchPersistentEntity.java | 43 ++-- ...SimpleElasticsearchPersistentProperty.java | 10 +- .../core/mapping/package-info.java | 6 + .../core/MappingBuilderTests.java | 242 +++++++++++++----- .../SimpleDynamicTemplatesMappingTests.java | 20 +- .../SimpleElasticsearchDateMappingTests.java | 10 +- .../entities/FieldNameEntity.java | 106 -------- .../entities/MinimalChildEntity.java | 35 --- 12 files changed, 347 insertions(+), 338 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/mapping/package-info.java delete mode 100644 src/test/java/org/springframework/data/elasticsearch/entities/FieldNameEntity.java delete mode 100644 src/test/java/org/springframework/data/elasticsearch/entities/MinimalChildEntity.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index fd511f6d28..ea7772a183 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -89,6 +89,7 @@ import org.elasticsearch.search.suggest.SuggestBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -108,7 +109,21 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; -import org.springframework.data.elasticsearch.core.query.*; +import org.springframework.data.elasticsearch.core.query.AliasQuery; +import org.springframework.data.elasticsearch.core.query.CriteriaQuery; +import org.springframework.data.elasticsearch.core.query.DeleteQuery; +import org.springframework.data.elasticsearch.core.query.FetchSourceFilter; +import org.springframework.data.elasticsearch.core.query.GetQuery; +import org.springframework.data.elasticsearch.core.query.IndexBoost; +import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.ScriptField; +import org.springframework.data.elasticsearch.core.query.SearchQuery; +import org.springframework.data.elasticsearch.core.query.SourceFilter; +import org.springframework.data.elasticsearch.core.query.StringQuery; +import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.util.CloseableIterator; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -224,7 +239,7 @@ public boolean putMapping(Class clazz) { } try { MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter); - return putMapping(clazz, mappingBuilder.buildMapping(clazz)); + return putMapping(clazz, mappingBuilder.buildPropertyMapping(clazz)); } catch (Exception e) { throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e); } @@ -497,8 +512,7 @@ public Page queryForPage(StringQuery query, Class clazz, SearchResultM @Override public CloseableIterator stream(CriteriaQuery query, Class clazz) { final long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); - return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz), clazz, - resultsMapper); + return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz), clazz, resultsMapper); } @Override @@ -509,8 +523,7 @@ public CloseableIterator stream(SearchQuery query, Class clazz) { @Override public CloseableIterator stream(SearchQuery query, final Class clazz, final SearchResultMapper mapper) { final long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); - return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz, mapper), clazz, - mapper); + return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz, mapper), clazz, mapper); } private CloseableIterator doStream(final long scrollTimeInMillis, final ScrolledPage page, @@ -1453,8 +1466,7 @@ List convertAliasResponse(String aliasResponse) { node = node.findValue("aliases"); Map aliasData = mapper.readValue(mapper.writeValueAsString(node), - new TypeReference>() { - }); + new TypeReference>() {}); Iterable> aliasIter = aliasData.entrySet(); List aliasMetaDataList = new ArrayList(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 245531b6cf..d6bc220ec8 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -206,7 +206,7 @@ public boolean putMapping(Class clazz) { } try { MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter); - return putMapping(clazz, mappingBuilder.buildMapping(clazz)); + return putMapping(clazz, mappingBuilder.buildPropertyMapping(clazz)); } catch (Exception e) { throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java index 94f82957c1..0b8e9484fc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java @@ -27,16 +27,25 @@ import org.elasticsearch.common.xcontent.XContentType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.core.io.ClassPathResource; import org.springframework.data.annotation.Transient; -import org.springframework.data.elasticsearch.annotations.*; +import org.springframework.data.elasticsearch.annotations.CompletionContext; +import org.springframework.data.elasticsearch.annotations.CompletionField; +import org.springframework.data.elasticsearch.annotations.DateFormat; +import org.springframework.data.elasticsearch.annotations.DynamicTemplates; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.data.elasticsearch.annotations.GeoPointField; +import org.springframework.data.elasticsearch.annotations.InnerField; +import org.springframework.data.elasticsearch.annotations.Mapping; +import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.completion.Completion; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.mapping.PropertyHandler; -import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.TypeInformation; import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; @@ -61,34 +70,33 @@ */ class MappingBuilder { - public static final String FIELD_DATA = "fielddata"; - public static final String FIELD_STORE = "store"; - public static final String FIELD_TYPE = "type"; - public static final String FIELD_INDEX = "index"; - public static final String FIELD_FORMAT = "format"; - public static final String FIELD_SEARCH_ANALYZER = "search_analyzer"; - public static final String FIELD_INDEX_ANALYZER = "analyzer"; - public static final String FIELD_NORMALIZER = "normalizer"; - public static final String FIELD_PROPERTIES = "properties"; - public static final String FIELD_PARENT = "_parent"; - public static final String FIELD_COPY_TO = "copy_to"; - public static final String FIELD_CONTEXT_NAME = "name"; - public static final String FIELD_CONTEXT_TYPE = "type"; - public static final String FIELD_CONTEXT_PRECISION = "precision"; - public static final String FIELD_DYNAMIC_TEMPLATES = "dynamic_templates"; - - public static final String COMPLETION_PRESERVE_SEPARATORS = "preserve_separators"; - public static final String COMPLETION_PRESERVE_POSITION_INCREMENTS = "preserve_position_increments"; - public static final String COMPLETION_MAX_INPUT_LENGTH = "max_input_length"; - public static final String COMPLETION_CONTEXTS = "contexts"; - - public static final String TYPE_VALUE_KEYWORD = "keyword"; - public static final String TYPE_VALUE_GEO_POINT = "geo_point"; - public static final String TYPE_VALUE_COMPLETION = "completion"; - public static final String TYPE_VALUE_GEO_HASH_PREFIX = "geohash_prefix"; - public static final String TYPE_VALUE_GEO_HASH_PRECISION = "geohash_precision"; + private static final String FIELD_DATA = "fielddata"; + private static final String FIELD_STORE = "store"; + private static final String FIELD_TYPE = "type"; + private static final String FIELD_INDEX = "index"; + private static final String FIELD_FORMAT = "format"; + private static final String FIELD_SEARCH_ANALYZER = "search_analyzer"; + private static final String FIELD_INDEX_ANALYZER = "analyzer"; + private static final String FIELD_NORMALIZER = "normalizer"; + private static final String FIELD_PROPERTIES = "properties"; + private static final String FIELD_PARENT = "_parent"; + private static final String FIELD_COPY_TO = "copy_to"; + private static final String FIELD_CONTEXT_NAME = "name"; + private static final String FIELD_CONTEXT_TYPE = "type"; + private static final String FIELD_CONTEXT_PRECISION = "precision"; + private static final String FIELD_DYNAMIC_TEMPLATES = "dynamic_templates"; + + private static final String COMPLETION_PRESERVE_SEPARATORS = "preserve_separators"; + private static final String COMPLETION_PRESERVE_POSITION_INCREMENTS = "preserve_position_increments"; + private static final String COMPLETION_MAX_INPUT_LENGTH = "max_input_length"; + private static final String COMPLETION_CONTEXTS = "contexts"; + + private static final String TYPE_VALUE_KEYWORD = "keyword"; + private static final String TYPE_VALUE_GEO_POINT = "geo_point"; + private static final String TYPE_VALUE_COMPLETION = "completion"; + private static final Logger logger = LoggerFactory.getLogger(ElasticsearchRestTemplate.class); - private static SimpleTypeHolder SIMPLE_TYPE_HOLDER = SimpleTypeHolder.DEFAULT; + private final ElasticsearchConverter elasticsearchConverter; MappingBuilder(ElasticsearchConverter elasticsearchConverter) { @@ -101,7 +109,7 @@ class MappingBuilder { * @return JSON string * @throws IOException */ - String buildMapping(Class clazz) throws IOException { + String buildPropertyMapping(Class clazz) throws IOException { ElasticsearchPersistentEntity entity = elasticsearchConverter.getMappingContext() .getRequiredPersistentEntity(clazz); @@ -157,70 +165,76 @@ private void mapEntity(XContentBuilder builder, @Nullable ElasticsearchPersisten return; } - if (property.isAnnotationPresent(Mapping.class)) { + buildPropertyMapping(builder, isRootObject, property); + } catch (IOException e) { + logger.warn("error mapping property with name {}", property.getName(), e); + } + }); + } - String mappingPath = property.getRequiredAnnotation(Mapping.class).mappingPath(); - if (!StringUtils.isEmpty(mappingPath)) { + if (writeNestedProperties) { + builder.endObject().endObject(); + } + } - ClassPathResource mappings = new ClassPathResource(mappingPath); - if (mappings.exists()) { - builder.rawField(property.getFieldName(), mappings.getInputStream(), XContentType.JSON); - return; - } - } - } + private void buildPropertyMapping(XContentBuilder builder, boolean isRootObject, + ElasticsearchPersistentProperty property) throws IOException { - boolean isGeoPointProperty = isGeoPointProperty(property); - boolean isCompletionProperty = isCompletionProperty(property); - boolean isNestedOrObjectProperty = isNestedOrObjectProperty(property); + if (property.isAnnotationPresent(Mapping.class)) { - Field fieldAnnotation = property.findAnnotation(Field.class); - if (!isGeoPointProperty && !isCompletionProperty && property.isEntity() && hasRelevantAnnotation(property)) { + String mappingPath = property.getRequiredAnnotation(Mapping.class).mappingPath(); + if (!StringUtils.isEmpty(mappingPath)) { - if (fieldAnnotation == null) { - return; - } + ClassPathResource mappings = new ClassPathResource(mappingPath); + if (mappings.exists()) { + builder.rawField(property.getFieldName(), mappings.getInputStream(), XContentType.JSON); + return; + } + } + } - Iterator> iterator = property.getPersistentEntityTypes().iterator(); - ElasticsearchPersistentEntity persistentEntity = iterator.hasNext() - ? elasticsearchConverter.getMappingContext().getPersistentEntity(iterator.next()) - : null; + boolean isGeoPointProperty = isGeoPointProperty(property); + boolean isCompletionProperty = isCompletionProperty(property); + boolean isNestedOrObjectProperty = isNestedOrObjectProperty(property); - mapEntity(builder, persistentEntity, false, property.getFieldName(), isNestedOrObjectProperty, - fieldAnnotation.type(), fieldAnnotation); + Field fieldAnnotation = property.findAnnotation(Field.class); + if (!isGeoPointProperty && !isCompletionProperty && property.isEntity() && hasRelevantAnnotation(property)) { - if (isNestedOrObjectProperty) { - return; - } - } + if (fieldAnnotation == null) { + return; + } - MultiField multiField = property.findAnnotation(MultiField.class); + Iterator> iterator = property.getPersistentEntityTypes().iterator(); + ElasticsearchPersistentEntity persistentEntity = iterator.hasNext() + ? elasticsearchConverter.getMappingContext().getPersistentEntity(iterator.next()) + : null; - if (isGeoPointProperty) { - applyGeoPointFieldMapping(builder, property); - return; - } + mapEntity(builder, persistentEntity, false, property.getFieldName(), isNestedOrObjectProperty, + fieldAnnotation.type(), fieldAnnotation); - if (isCompletionProperty) { - CompletionField completionField = property.findAnnotation(CompletionField.class); - applyCompletionFieldMapping(builder, property, completionField); - } + if (isNestedOrObjectProperty) { + return; + } + } - if (isRootObject && fieldAnnotation != null && property.isIdProperty()) { - applyDefaultIdFieldMapping(builder, property); - } else if (multiField != null) { - addMultiFieldMapping(builder, property, multiField, isNestedOrObjectProperty); - } else if (fieldAnnotation != null) { - addSingleFieldMapping(builder, property, fieldAnnotation, isNestedOrObjectProperty); - } - } catch (IOException e) { - logger.warn("error mapping property with name {}", property.getName(), e); - } - }); + MultiField multiField = property.findAnnotation(MultiField.class); + + if (isGeoPointProperty) { + applyGeoPointFieldMapping(builder, property); + return; } - if (writeNestedProperties) { - builder.endObject().endObject(); + if (isCompletionProperty) { + CompletionField completionField = property.findAnnotation(CompletionField.class); + applyCompletionFieldMapping(builder, property, completionField); + } + + if (isRootObject && fieldAnnotation != null && property.isIdProperty()) { + applyDefaultIdFieldMapping(builder, property); + } else if (multiField != null) { + addMultiFieldMapping(builder, property, multiField, isNestedOrObjectProperty); + } else if (fieldAnnotation != null) { + addSingleFieldMapping(builder, property, fieldAnnotation, isNestedOrObjectProperty); } } @@ -321,6 +335,7 @@ private void addMultiFieldMapping(XContentBuilder builder, ElasticsearchPersiste private void addFieldMappingParameters(XContentBuilder builder, Object annotation, boolean nestedOrObjectField) throws IOException { + boolean index = true; boolean store = false; boolean fielddata = false; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchMappingContext.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchMappingContext.java index 6b5887b048..0fcb3ae0ed 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchMappingContext.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchMappingContext.java @@ -22,6 +22,7 @@ import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.TypeInformation; +import org.springframework.lang.Nullable; /** * SimpleElasticsearchMappingContext @@ -30,10 +31,11 @@ * @author Mohsin Husen * @author Mark Paluch */ -public class SimpleElasticsearchMappingContext extends - AbstractMappingContext, ElasticsearchPersistentProperty> implements ApplicationContextAware { +public class SimpleElasticsearchMappingContext + extends AbstractMappingContext, ElasticsearchPersistentProperty> + implements ApplicationContextAware { - private ApplicationContext context; + private @Nullable ApplicationContext context; @Override protected SimpleElasticsearchPersistentEntity createPersistentEntity(TypeInformation typeInformation) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java index 38c7b60f5c..93b4e4611f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java @@ -55,21 +55,22 @@ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntit private final StandardEvaluationContext context; private final SpelExpressionParser parser; - private String indexName; - private String indexType; + private @Nullable String indexName; + private @Nullable String indexType; private boolean useServerConfiguration; private short shards; private short replicas; - private String refreshInterval; - private String indexStoreType; - private String parentType; - private ElasticsearchPersistentProperty parentIdProperty; - private ElasticsearchPersistentProperty scoreProperty; - private String settingPath; + private @Nullable String refreshInterval; + private @Nullable String indexStoreType; + private @Nullable String parentType; + private @Nullable ElasticsearchPersistentProperty parentIdProperty; + private @Nullable ElasticsearchPersistentProperty scoreProperty; + private @Nullable String settingPath; private VersionType versionType; private boolean createIndexAndMapping; public SimpleElasticsearchPersistentEntity(TypeInformation typeInformation) { + super(typeInformation); this.context = new StandardEvaluationContext(); this.parser = new SpelExpressionParser(); @@ -104,7 +105,7 @@ public void setApplicationContext(ApplicationContext applicationContext) throws @Override public String getIndexName() { - if(indexName != null) { + if (indexName != null) { Expression expression = parser.parseExpression(indexName, ParserContext.TEMPLATE_EXPRESSION); return expression.getValue(context, String.class); } @@ -115,7 +116,7 @@ public String getIndexName() { @Override public String getIndexType() { - if(indexType != null) { + if (indexType != null) { Expression expression = parser.parseExpression(indexType, ParserContext.TEMPLATE_EXPRESSION); return expression.getValue(context, String.class); } @@ -192,9 +193,10 @@ public void addPersistentProperty(ElasticsearchPersistentProperty property) { ElasticsearchPersistentProperty parentProperty = this.parentIdProperty; if (parentProperty != null) { - throw new MappingException( - String.format("Attempt to add parent property %s but already have property %s registered " - + "as parent property. Check your mapping configuration!", property.getField(), parentProperty.getField())); + throw new MappingException(String.format( + "Attempt to add parent property %s but already have property %s registered " + + "as parent property. Check your mapping configuration!", + property.getField(), parentProperty.getField())); } Parent parentAnnotation = property.findAnnotation(Parent.class); @@ -203,26 +205,27 @@ public void addPersistentProperty(ElasticsearchPersistentProperty property) { } if (property.isScoreProperty()) { - + ElasticsearchPersistentProperty scoreProperty = this.scoreProperty; if (scoreProperty != null) { - throw new MappingException( - String.format("Attempt to add score property %s but already have property %s registered " - + "as score property. Check your mapping configuration!", property.getField(), scoreProperty.getField())); + throw new MappingException(String.format( + "Attempt to add score property %s but already have property %s registered " + + "as score property. Check your mapping configuration!", + property.getField(), scoreProperty.getField())); } this.scoreProperty = property; } } - - /* + + /* * (non-Javadoc) * @see org.springframework.data.mapping.model.BasicPersistentEntity#setPersistentPropertyAccessorFactory(org.springframework.data.mapping.model.PersistentPropertyAccessorFactory) */ @Override public void setPersistentPropertyAccessorFactory(PersistentPropertyAccessorFactory factory) { - + // Do nothing to avoid the usage of ClassGeneratingPropertyAccessorFactory for now // DATACMNS-1322 switches to proper immutability behavior which Spring Data Elasticsearch // cannot yet implement diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java index d13cc7fbed..cdedcaad38 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java @@ -27,6 +27,7 @@ import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty; import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; +import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; /** @@ -47,7 +48,7 @@ public class SimpleElasticsearchPersistentProperty extends private final boolean isScore; private final boolean isParent; private final boolean isId; - private final String annotatedFieldName; + private final @Nullable String annotatedFieldName; public SimpleElasticsearchPersistentProperty(Property property, PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { @@ -59,20 +60,21 @@ public SimpleElasticsearchPersistentProperty(Property property, this.isScore = isAnnotationPresent(Score.class); this.isParent = isAnnotationPresent(Parent.class); - if (isVersionProperty() && getType() != Long.class) { + if (isVersionProperty() && !getType().equals(Long.class)) { throw new MappingException(String.format("Version property %s must be of type Long!", property.getName())); } - if (isScore && !Arrays.asList(Float.TYPE, Float.class).contains(getType())) { + if (isScore && !getType().equals(Float.TYPE) && !getType().equals(Float.class)) { throw new MappingException( String.format("Score property %s must be either of type float or Float!", property.getName())); } - if (isParent && getType() != String.class) { + if (isParent && !getType().equals(String.class)) { throw new MappingException(String.format("Parent property %s must be of type String!", property.getName())); } } + @Nullable private String getAnnotatedFieldName() { if (isAnnotationPresent(Field.class)) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/package-info.java new file mode 100644 index 0000000000..5a5dac8c04 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/package-info.java @@ -0,0 +1,6 @@ + +/** + * Infrastructure for the Elasticsearch document-to-object mapping subsystem. + */ +@org.springframework.lang.NonNullApi +package org.springframework.data.elasticsearch.core.mapping; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/MappingBuilderTests.java index dab674240c..48b5a59f95 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/MappingBuilderTests.java @@ -19,11 +19,12 @@ import static org.elasticsearch.index.query.QueryBuilders.*; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; +import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; import static org.springframework.data.elasticsearch.utils.IndexBuilder.*; import java.io.IOException; import java.math.BigDecimal; -import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -31,12 +32,32 @@ import org.json.JSONException; import org.junit.Test; import org.junit.runner.RunWith; -import org.skyscreamer.jsonassert.JSONAssert; + import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.CompletionField; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.data.elasticsearch.annotations.InnerField; +import org.springframework.data.elasticsearch.annotations.Mapping; +import org.springframework.data.elasticsearch.annotations.MultiField; +import org.springframework.data.elasticsearch.annotations.Parent; import org.springframework.data.elasticsearch.builder.SampleInheritedEntityBuilder; +import org.springframework.data.elasticsearch.core.completion.Completion; +import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.SearchQuery; -import org.springframework.data.elasticsearch.entities.*; +import org.springframework.data.elasticsearch.entities.Book; +import org.springframework.data.elasticsearch.entities.CopyToEntity; +import org.springframework.data.elasticsearch.entities.GeoEntity; +import org.springframework.data.elasticsearch.entities.Group; +import org.springframework.data.elasticsearch.entities.NormalizerEntity; +import org.springframework.data.elasticsearch.entities.SampleInheritedEntity; +import org.springframework.data.elasticsearch.entities.SampleTransientEntity; +import org.springframework.data.elasticsearch.entities.SimpleRecursiveEntity; +import org.springframework.data.elasticsearch.entities.StockPrice; +import org.springframework.data.elasticsearch.entities.User; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -64,30 +85,33 @@ public void shouldNotFailOnCircularReference() { elasticsearchTemplate.refresh(SimpleRecursiveEntity.class); } - @Test + @Test // DATAES-568 public void testInfiniteLoopAvoidance() throws IOException, JSONException { - final String expected = "{\"mapping\":{\"properties\":{\"message\":{\"store\":true,\"" + + String expected = "{\"mapping\":{\"properties\":{\"message\":{\"store\":true,\"" + "type\":\"text\",\"index\":false," + "\"analyzer\":\"standard\"}}}}"; - String mapping = getMappingBuilder().buildMapping(SampleTransientEntity.class); + String mapping = getMappingBuilder().buildPropertyMapping(SampleTransientEntity.class); - JSONAssert.assertEquals(expected, mapping, false); + assertEquals(expected, mapping, false); } - @Test + @Test // DATAES-568 public void shouldUseValueFromAnnotationType() throws IOException, JSONException { + // Given - final String expected = "{\"price\":{\"properties\":{\"price\":{\"store\":false,\"type\":\"double\"}}}}"; + String expected = "{\"price\":{\"properties\":{\"price\":{\"store\":false,\"type\":\"double\"}}}}"; // When - String mapping = getMappingBuilder().buildMapping(StockPrice.class); + String mapping = getMappingBuilder().buildPropertyMapping(StockPrice.class); // Then - JSONAssert.assertEquals(expected, mapping, false); + assertEquals(expected, mapping, false); } @Test // DATAES-530 - public void shouldAddStockPriceDocumentToIndex() throws IOException { + public void shouldAddStockPriceDocumentToIndex() { + // Given // When @@ -111,34 +135,31 @@ public void shouldAddStockPriceDocumentToIndex() throws IOException { assertThat(entry.getPrice(), is(BigDecimal.valueOf(price))); } - @Test + @Test // DATAES-568 public void shouldCreateMappingForSpecifiedParentType() throws IOException, JSONException { - final String expected = "{\"mapping\":{\"_parent\":{\"type\":\"parentType\"},\"properties\":{}}}"; - String mapping = getMappingBuilder().buildMapping(MinimalChildEntity.class); + String expected = "{\"mapping\":{\"_parent\":{\"type\":\"parentType\"},\"properties\":{}}}"; + + String mapping = getMappingBuilder().buildPropertyMapping(MinimalChildEntity.class); - JSONAssert.assertEquals(expected, mapping, false); + assertEquals(expected, mapping, false); } - /* - * DATAES-76 - */ - @Test + @Test // DATAES-76 public void shouldBuildMappingWithSuperclass() throws IOException, JSONException { - final String expected = "{\"mapping\":{\"properties\":{\"message\":{\"store\":true,\"" + + String expected = "{\"mapping\":{\"properties\":{\"message\":{\"store\":true,\"" + "type\":\"text\",\"index\":false,\"analyzer\":\"standard\"}" + ",\"createdDate\":{\"store\":false," + "\"type\":\"date\",\"index\":false}}}}"; - String mapping = getMappingBuilder().buildMapping(SampleInheritedEntity.class); + String mapping = getMappingBuilder().buildPropertyMapping(SampleInheritedEntity.class); - JSONAssert.assertEquals(expected, mapping, false); + assertEquals(expected, mapping, false); } - /* - * DATAES-76 - */ - @Test - public void shouldAddSampleInheritedEntityDocumentToIndex() throws IOException { + @Test // DATAES-76 + public void shouldAddSampleInheritedEntityDocumentToIndex() { + // Given // When @@ -156,13 +177,15 @@ public void shouldAddSampleInheritedEntityDocumentToIndex() throws IOException { List result = elasticsearchTemplate.queryForList(searchQuery, SampleInheritedEntity.class); // Then assertThat(result.size(), is(1)); + SampleInheritedEntity entry = result.get(0); assertThat(entry.getCreatedDate(), is(createdDate)); assertThat(entry.getMessage(), is(message)); } - @Test + @Test // DATAES-568 public void shouldBuildMappingsForGeoPoint() throws IOException, JSONException { + // given String expected = "{\"geo-test-index\": {\"properties\": {" + "\"pointA\":{\"type\":\"geo_point\"}," + "\"pointB\":{\"type\":\"geo_point\"}," + "\"pointC\":{\"type\":\"geo_point\"}," @@ -170,17 +193,15 @@ public void shouldBuildMappingsForGeoPoint() throws IOException, JSONException { // when String mapping; - mapping = getMappingBuilder().buildMapping(GeoEntity.class); + mapping = getMappingBuilder().buildPropertyMapping(GeoEntity.class); // then - JSONAssert.assertEquals(expected, mapping, false); + assertEquals(expected, mapping, false); } - /** - * DATAES-260 - StacOverflow when two reverse relationship. - */ - @Test + @Test // DATAES-260 - StackOverflow when two reverse relationship. public void shouldHandleReverseRelationship() { + // given elasticsearchTemplate.createIndex(User.class); elasticsearchTemplate.putMapping(User.class); @@ -189,21 +210,21 @@ public void shouldHandleReverseRelationship() { // when // then - } - @Test + @Test // DATAES-285 public void shouldMapBooks() { + // given elasticsearchTemplate.createIndex(Book.class); elasticsearchTemplate.putMapping(Book.class); // when // then - } @Test // DATAES-420 public void shouldUseBothAnalyzer() { + // given elasticsearchTemplate.deleteIndex(Book.class); elasticsearchTemplate.createIndex(Book.class); @@ -224,7 +245,7 @@ public void shouldUseBothAnalyzer() { } @Test // DATAES-492 - public void shouldUseKeywordNormalizer() throws IOException { + public void shouldUseKeywordNormalizer() { // given elasticsearchTemplate.deleteIndex(NormalizerEntity.class); @@ -245,7 +266,7 @@ public void shouldUseKeywordNormalizer() throws IOException { } @Test // DATAES-503 - public void shouldUseCopyTo() throws IOException { + public void shouldUseCopyTo() { // given elasticsearchTemplate.deleteIndex(CopyToEntity.class); @@ -259,107 +280,188 @@ public void shouldUseCopyTo() throws IOException { Map fieldLastName = (Map) properties.get("lastName"); // then - List copyToValue = Arrays.asList("name"); + List copyToValue = Collections.singletonList("name"); assertThat(fieldFirstName.get("copy_to"), equalTo(copyToValue)); assertThat(fieldLastName.get("copy_to"), equalTo(copyToValue)); } @Test // DATAES-568 public void shouldUseFieldNameOnId() throws IOException, JSONException { + // given - final String expected = "{\"fieldname-type\":{\"properties\":{" - + "\"id-property\":{\"type\":\"keyword\",\"index\":true}" + "}}}"; + String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}" + + "}}}"; // when - String mapping = getMappingBuilder().buildMapping(FieldNameEntity.IdEntity.class); + String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.IdEntity.class); // then - JSONAssert.assertEquals(expected, mapping, false); + assertEquals(expected, mapping, false); } @Test // DATAES-568 public void shouldUseFieldNameOnText() throws IOException, JSONException { + // given - final String expected = "{\"fieldname-type\":{\"properties\":{" - + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + "\"text-property\":{\"store\":false,\"type\":\"text\"}" + "}}}"; // when - String mapping = getMappingBuilder().buildMapping(FieldNameEntity.TextEntity.class); + String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.TextEntity.class); // then - JSONAssert.assertEquals(expected, mapping, false); + assertEquals(expected, mapping, false); } @Test // DATAES-568 public void shouldUseFieldNameOnMapping() throws IOException, JSONException { + // given - final String expected = "{\"fieldname-type\":{\"properties\":{" - + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + "\"mapping-property\":{\"type\":\"string\",\"analyzer\":\"standard_lowercase_asciifolding\"}" + "}}}"; // when - String mapping = getMappingBuilder().buildMapping(FieldNameEntity.MappingEntity.class); + String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.MappingEntity.class); // then - JSONAssert.assertEquals(expected, mapping, false); + assertEquals(expected, mapping, false); } @Test // DATAES-568 public void shouldUseFieldNameOnGeoPoint() throws IOException, JSONException { + // given - final String expected = "{\"fieldname-type\":{\"properties\":{" - + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + "\"geopoint-property\":{\"type\":\"geo_point\"}" - + "}}}"; + String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + + "\"geopoint-property\":{\"type\":\"geo_point\"}" + "}}}"; // when - String mapping = getMappingBuilder().buildMapping(FieldNameEntity.GeoPointEntity.class); + String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.GeoPointEntity.class); // then - JSONAssert.assertEquals(expected, mapping, false); + assertEquals(expected, mapping, false); } @Test // DATAES-568 public void shouldUseFieldNameOnCircularEntity() throws IOException, JSONException { + // given - final String expected = "{\"fieldname-type\":{\"properties\":{" - + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + "\"circular-property\":{\"type\":\"object\",\"properties\":{\"id-property\":{\"store\":false}}}" + "}}}"; // when - String mapping = getMappingBuilder().buildMapping(FieldNameEntity.CircularEntity.class); + String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.CircularEntity.class); // then - JSONAssert.assertEquals(expected, mapping, false); + assertEquals(expected, mapping, false); } @Test // DATAES-568 public void shouldUseFieldNameOnCompletion() throws IOException, JSONException { + // given - final String expected = "{\"fieldname-type\":{\"properties\":{" - + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + "\"completion-property\":{\"type\":\"completion\",\"max_input_length\":100,\"preserve_position_increments\":true,\"preserve_separators\":true,\"search_analyzer\":\"simple\",\"analyzer\":\"simple\"},\"completion-property\":{\"store\":false}" + "}}}"; // when - String mapping = getMappingBuilder().buildMapping(FieldNameEntity.CompletionEntity.class); + String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.CompletionEntity.class); // then - JSONAssert.assertEquals(expected, mapping, false); + assertEquals(expected, mapping, false); } @Test // DATAES-568 public void shouldUseFieldNameOnMultiField() throws IOException, JSONException { + // given - final String expected = "{\"fieldname-type\":{\"properties\":{" - + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + "\"multifield-property\":{\"store\":false,\"type\":\"text\",\"analyzer\":\"whitespace\",\"fields\":{\"prefix\":{\"store\":false,\"type\":\"text\",\"analyzer\":\"stop\",\"search_analyzer\":\"standard\"}}}" + "}}}"; // when - String mapping = getMappingBuilder().buildMapping(FieldNameEntity.MultiFieldEntity.class); + String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.MultiFieldEntity.class); // then - JSONAssert.assertEquals(expected, mapping, false); + assertEquals(expected, mapping, false); + } + + /** + * @author Peter-Josef Meisch + */ + @SuppressWarnings("unused") + static class FieldNameEntity { + + @Document(indexName = "fieldname-index", type = "fieldname-type") + static class IdEntity { + @Id @Field("id-property") private String id; + } + + @Document(indexName = "fieldname-index", type = "fieldname-type") + static class TextEntity { + + @Id @Field("id-property") private String id; + + @Field(name = "text-property", type = FieldType.Text) // + private String textProperty; + } + + @Document(indexName = "fieldname-index", type = "fieldname-type") + static class MappingEntity { + + @Id @Field("id-property") private String id; + + @Field("mapping-property") @Mapping(mappingPath = "/mappings/test-field-analyzed-mappings.json") // + private byte[] mappingProperty; + } + + @Document(indexName = "fieldname-index", type = "fieldname-type") + static class GeoPointEntity { + + @Id @Field("id-property") private String id; + + @Field("geopoint-property") private GeoPoint geoPoint; + } + + @Document(indexName = "fieldname-index", type = "fieldname-type") + static class CircularEntity { + + @Id @Field("id-property") private String id; + + @Field(name = "circular-property", type = FieldType.Object, ignoreFields = { "circular-property" }) // + private CircularEntity circularProperty; + } + + @Document(indexName = "fieldname-index", type = "fieldname-type") + static class CompletionEntity { + + @Id @Field("id-property") private String id; + + @Field("completion-property") @CompletionField(maxInputLength = 100) // + private Completion suggest; + } + + @Document(indexName = "fieldname-index", type = "fieldname-type") + static class MultiFieldEntity { + + @Id @Field("id-property") private String id; + + @Field("multifield-property") // + @MultiField(mainField = @Field(type = FieldType.Text, analyzer = "whitespace"), otherFields = { + @InnerField(suffix = "prefix", type = FieldType.Text, analyzer = "stop", searchAnalyzer = "standard") }) // + private String description; + } + } + + /** + * MinimalChildEntity + * + * @author Peter-josef Meisch + */ + @Document(indexName = "test-index-minimal", type = "mapping") + static class MinimalChildEntity { + + @Id private String id; + + @Parent(type = "parentType") private String parentId; } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/SimpleDynamicTemplatesMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/SimpleDynamicTemplatesMappingTests.java index 71ddaa90d9..339537f0c2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/SimpleDynamicTemplatesMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/SimpleDynamicTemplatesMappingTests.java @@ -1,10 +1,12 @@ package org.springframework.data.elasticsearch.core; +import static org.junit.Assert.*; + import java.io.IOException; -import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.data.elasticsearch.entities.SampleDynamicTemplatesEntity; import org.springframework.data.elasticsearch.entities.SampleDynamicTemplatesEntityTwo; import org.springframework.test.context.ContextConfiguration; @@ -20,26 +22,30 @@ @ContextConfiguration("classpath:elasticsearch-template-test.xml") public class SimpleDynamicTemplatesMappingTests extends MappingContextBaseTests { - @Test + @Test // DATAES-568 public void testCorrectDynamicTemplatesMappings() throws IOException { - String mapping = getMappingBuilder().buildMapping(SampleDynamicTemplatesEntity.class); + + String mapping = getMappingBuilder().buildPropertyMapping(SampleDynamicTemplatesEntity.class); String EXPECTED_MAPPING_ONE = "{\"test-dynamictemplatestype\":{\"dynamic_templates\":" + "[{\"with_custom_analyzer\":{" + "\"mapping\":{\"type\":\"string\",\"analyzer\":\"standard_lowercase_asciifolding\"}," + "\"path_match\":\"names.*\"}}]," + "\"properties\":{\"names\":{\"type\":\"object\"}}}}"; - Assert.assertEquals(EXPECTED_MAPPING_ONE, mapping); + + assertEquals(EXPECTED_MAPPING_ONE, mapping); } - @Test + @Test // DATAES-568 public void testCorrectDynamicTemplatesMappingsTwo() throws IOException { - String mapping = getMappingBuilder().buildMapping(SampleDynamicTemplatesEntityTwo.class); + + String mapping = getMappingBuilder().buildPropertyMapping(SampleDynamicTemplatesEntityTwo.class); String EXPECTED_MAPPING_TWO = "{\"test-dynamictemplatestype\":{\"dynamic_templates\":" + "[{\"with_custom_analyzer\":{" + "\"mapping\":{\"type\":\"string\",\"analyzer\":\"standard_lowercase_asciifolding\"}," + "\"path_match\":\"names.*\"}}," + "{\"participantA1_with_custom_analyzer\":{" + "\"mapping\":{\"type\":\"string\",\"analyzer\":\"standard_lowercase_asciifolding\"}," + "\"path_match\":\"participantA1.*\"}}]," + "\"properties\":{\"names\":{\"type\":\"object\"}}}}"; - Assert.assertEquals(EXPECTED_MAPPING_TWO, mapping); + + assertEquals(EXPECTED_MAPPING_TWO, mapping); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/SimpleElasticsearchDateMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/SimpleElasticsearchDateMappingTests.java index bdce10abf9..022906825c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/SimpleElasticsearchDateMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/SimpleElasticsearchDateMappingTests.java @@ -15,10 +15,12 @@ */ package org.springframework.data.elasticsearch.core; +import static org.junit.Assert.*; + import java.io.IOException; -import org.junit.Assert; import org.junit.Test; + import org.springframework.data.elasticsearch.entities.SampleDateMappingEntity; /** @@ -34,11 +36,11 @@ public class SimpleElasticsearchDateMappingTests extends MappingContextBaseTests + "\"defaultFormatDate\":{\"store\":false,\"type\":\"date\"},\"basicFormatDate\":{\"store\":false,\"" + "type\":\"date\",\"format\":\"basic_date\"}}}}"; - @Test + @Test // DATAES-568 public void testCorrectDateMappings() throws IOException { - String mapping = getMappingBuilder().buildMapping(SampleDateMappingEntity.class); + String mapping = getMappingBuilder().buildPropertyMapping(SampleDateMappingEntity.class); - Assert.assertEquals(EXPECTED_MAPPING, mapping); + assertEquals(EXPECTED_MAPPING, mapping); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/entities/FieldNameEntity.java b/src/test/java/org/springframework/data/elasticsearch/entities/FieldNameEntity.java deleted file mode 100644 index d5fc2e1cdf..0000000000 --- a/src/test/java/org/springframework/data/elasticsearch/entities/FieldNameEntity.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */package org.springframework.data.elasticsearch.entities; - -import org.springframework.data.annotation.Id; -import org.springframework.data.elasticsearch.annotations.CompletionField; -import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.annotations.Field; -import org.springframework.data.elasticsearch.annotations.FieldType; -import org.springframework.data.elasticsearch.annotations.InnerField; -import org.springframework.data.elasticsearch.annotations.Mapping; -import org.springframework.data.elasticsearch.annotations.MultiField; -import org.springframework.data.elasticsearch.core.completion.Completion; -import org.springframework.data.elasticsearch.core.geo.GeoPoint; - -/** - * @author Peter-Josef Meisch - */ -public class FieldNameEntity { - - @Document(indexName = "fieldname-index", type = "fieldname-type") - public static class IdEntity { - @Id @Field("id-property") - private String id; - } - - @Document(indexName = "fieldname-index", type = "fieldname-type") - public static class TextEntity { - - @Id @Field("id-property") - private String id; - - @Field(name = "text-property", type = FieldType.Text) - private String textProperty; - } - - @Document(indexName = "fieldname-index", type = "fieldname-type") - public static class MappingEntity { - - @Id @Field("id-property") - private String id; - - @Field("mapping-property") @Mapping(mappingPath = "/mappings/test-field-analyzed-mappings.json") - private byte[] mappingProperty; - } - - @Document(indexName = "fieldname-index", type = "fieldname-type") - public static class GeoPointEntity { - - @Id @Field("id-property") - private String id; - - @Field("geopoint-property") - private GeoPoint geoPoint; - } - - @Document(indexName = "fieldname-index", type = "fieldname-type") - public static class CircularEntity { - - @Id @Field("id-property") - private String id; - - @Field(name = "circular-property", type = FieldType.Object, - ignoreFields = { "circular-property" }) - private CircularEntity circularProperty; - } - - @Document(indexName = "fieldname-index", type = "fieldname-type") - public static class CompletionEntity { - - @Id @Field("id-property") - private String id; - - @Field("completion-property") - @CompletionField(maxInputLength = 100) - private Completion suggest; - } - - @Document(indexName = "fieldname-index", type = "fieldname-type") - public static class MultiFieldEntity { - - @Id @Field("id-property") - private String id; - - @Field("multifield-property") - @MultiField( - mainField = @Field(type = FieldType.Text, analyzer = "whitespace"), - otherFields = { - @InnerField(suffix = "prefix", type = FieldType.Text, analyzer = "stop", searchAnalyzer = "standard") - } - ) - private String description; - } -} diff --git a/src/test/java/org/springframework/data/elasticsearch/entities/MinimalChildEntity.java b/src/test/java/org/springframework/data/elasticsearch/entities/MinimalChildEntity.java deleted file mode 100644 index 7172dc10e2..0000000000 --- a/src/test/java/org/springframework/data/elasticsearch/entities/MinimalChildEntity.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2019 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.elasticsearch.entities; - -import org.springframework.data.annotation.Id; -import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.annotations.Parent; - -/** - * MinimalChildEntity - * - * @author Peter-josef Meisch - */ -@Document(indexName = "test-index-minimal", type = "mapping") -public class MinimalChildEntity { - - @Id - private String id; - - @Parent(type = "parentType") - private String parentId; -}