mirror of
https://github.com/spring-projects/spring-data-elasticsearch.git
synced 2025-06-14 08:02:11 +00:00
DATAES-621 - Add missing fieldtypes and parameters to mapping.
Original PR: #311
This commit is contained in:
parent
490347f286
commit
f0117e7b6a
@ -50,8 +50,8 @@ public @interface Field {
|
||||
|
||||
/**
|
||||
* The <em>name</em> to be used to store the field inside the document.
|
||||
* <p>√5
|
||||
* If not set, the name of the annotated property is used.
|
||||
* <p>
|
||||
* √5 If not set, the name of the annotated property is used.
|
||||
*
|
||||
* @since 3.2
|
||||
*/
|
||||
@ -86,4 +86,66 @@ public @interface Field {
|
||||
* @since 4.0
|
||||
*/
|
||||
int ignoreAbove() default -1;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
boolean coerce() default true;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
boolean docValues() default true;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
boolean ignoreMalformed() default false;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
IndexOptions indexOptions() default IndexOptions.none;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
boolean indexPhrases() default false;
|
||||
|
||||
/**
|
||||
* implemented as array to enable the empty default value
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
IndexPrefixes[] indexPrefixes() default {};
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
boolean norms() default true;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
String nullValue() default "";
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
int positionIncrementGap() default -1;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
Similarity similarity() default Similarity.Default;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
TermVector termVector() default TermVector.none;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
double scalingFactor() default 1;
|
||||
}
|
||||
|
@ -20,22 +20,34 @@ package org.springframework.data.elasticsearch.annotations;
|
||||
* @author Mohsin Husen
|
||||
* @author Artur Konczak
|
||||
* @author Zeng Zetang
|
||||
* @author Peter-Josef Meisch
|
||||
*/
|
||||
public enum FieldType {
|
||||
Text,
|
||||
Byte,
|
||||
Short,
|
||||
Integer,
|
||||
Long,
|
||||
Date,
|
||||
Half_Float,
|
||||
Float,
|
||||
Double,
|
||||
Boolean,
|
||||
Object,
|
||||
Auto,
|
||||
Nested,
|
||||
Ip,
|
||||
Attachment,
|
||||
Keyword
|
||||
Auto,
|
||||
Text,
|
||||
Keyword,
|
||||
Long,
|
||||
Integer,
|
||||
Short,
|
||||
Byte,
|
||||
Double,
|
||||
Float,
|
||||
Half_Float,
|
||||
Scaled_Float,
|
||||
Date,
|
||||
Date_Nanos,
|
||||
Boolean,
|
||||
Binary,
|
||||
Integer_Range,
|
||||
Float_Range,
|
||||
Long_Range,
|
||||
Double_Range,
|
||||
Date_Range,
|
||||
Ip_Range,
|
||||
Object,
|
||||
Nested,
|
||||
Ip,
|
||||
TokenCount,
|
||||
Percolator,
|
||||
Flattened
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.annotations;
|
||||
|
||||
/**
|
||||
* @author Peter-Josef Meisch
|
||||
* @since 4.0
|
||||
*/
|
||||
public enum IndexOptions {
|
||||
none, docs, freqs, positions, offsets
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.annotations;
|
||||
|
||||
/**
|
||||
* @author Peter-Josef Meisch
|
||||
* @since 4.0
|
||||
*/
|
||||
public @interface IndexPrefixes {
|
||||
static final int MIN_DEFAULT = 2;
|
||||
static final int MAX_DEFAULT = 2;
|
||||
|
||||
int minChars() default MIN_DEFAULT;
|
||||
|
||||
int maxChars() default MAX_DEFAULT;
|
||||
}
|
@ -25,6 +25,7 @@ import java.lang.annotation.Target;
|
||||
* @author Mohsin Husen
|
||||
* @author Sascha Woo
|
||||
* @author Xiao Yu
|
||||
* @author Peter-Josef Meisch
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
@ -54,4 +55,66 @@ public @interface InnerField {
|
||||
* @since 4.0
|
||||
*/
|
||||
int ignoreAbove() default -1;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
boolean coerce() default true;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
boolean docValues() default true;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
boolean ignoreMalformed() default false;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
IndexOptions indexOptions() default IndexOptions.none;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
boolean indexPhrases() default false;
|
||||
|
||||
/**
|
||||
* implemented as array to enable the empty default value
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
IndexPrefixes[] indexPrefixes() default {};
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
boolean norms() default true;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
String nullValue() default "";
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
int positionIncrementGap() default -1;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
Similarity similarity() default Similarity.Default;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
TermVector termVector() default TermVector.none;
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
double scalingFactor() default 1;
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.annotations;
|
||||
|
||||
/**
|
||||
* @author Peter-Josef Meisch
|
||||
* @since 4.0
|
||||
*/
|
||||
public enum Similarity {
|
||||
Default("default"), BM25("BM25"), classic("classic"), Boolean("boolean");
|
||||
|
||||
// need to use a custom name because 'boolean' can't be used as enum name
|
||||
private final String toStringName;
|
||||
|
||||
Similarity(String name) {
|
||||
this.toStringName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringName;
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.annotations;
|
||||
|
||||
/**
|
||||
* @author Peter-Josef Meisch
|
||||
* @since 4.0
|
||||
*/
|
||||
public enum TermVector {
|
||||
none, no, yes, with_positions, with_offsets, woth_positions_offsets, with_positions_payloads, with_positions_offets_payloads
|
||||
}
|
@ -101,6 +101,7 @@ import org.springframework.data.elasticsearch.core.client.support.AliasData;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
|
||||
import org.springframework.data.elasticsearch.core.indexmapping.MappingBuilder;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||
|
@ -88,6 +88,7 @@ import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
|
||||
import org.springframework.data.elasticsearch.core.indexmapping.MappingBuilder;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
|
||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||
|
@ -20,7 +20,6 @@ import java.nio.charset.Charset;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
@ -28,9 +27,10 @@ import org.springframework.util.StreamUtils;
|
||||
* Utility to read {@link org.springframework.core.io.Resource}s.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Peter-Josef Meisch
|
||||
* @since 3.2
|
||||
*/
|
||||
abstract class ResourceUtil {
|
||||
public abstract class ResourceUtil {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ResourceUtil.class);
|
||||
|
||||
|
@ -13,13 +13,15 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core;
|
||||
package org.springframework.data.elasticsearch.core.indexmapping;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentFactory.*;
|
||||
import static org.springframework.data.elasticsearch.core.indexmapping.MappingParameters.*;
|
||||
import static org.springframework.util.StringUtils.*;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
@ -31,7 +33,6 @@ import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
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;
|
||||
@ -39,6 +40,8 @@ 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.ElasticsearchRestTemplate;
|
||||
import org.springframework.data.elasticsearch.core.ResourceUtil;
|
||||
import org.springframework.data.elasticsearch.core.completion.Completion;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
@ -47,7 +50,6 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersiste
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
@ -69,24 +71,15 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Xiao Yu
|
||||
*/
|
||||
class MappingBuilder {
|
||||
public class MappingBuilder {
|
||||
|
||||
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 FIELD_IGNORE_ABOVE = "ignore_above";
|
||||
|
||||
private static final String COMPLETION_PRESERVE_SEPARATORS = "preserve_separators";
|
||||
private static final String COMPLETION_PRESERVE_POSITION_INCREMENTS = "preserve_position_increments";
|
||||
@ -101,7 +94,7 @@ class MappingBuilder {
|
||||
|
||||
private final ElasticsearchConverter elasticsearchConverter;
|
||||
|
||||
MappingBuilder(ElasticsearchConverter elasticsearchConverter) {
|
||||
public MappingBuilder(ElasticsearchConverter elasticsearchConverter) {
|
||||
this.elasticsearchConverter = elasticsearchConverter;
|
||||
}
|
||||
|
||||
@ -111,7 +104,7 @@ class MappingBuilder {
|
||||
* @return JSON string
|
||||
* @throws IOException
|
||||
*/
|
||||
String buildPropertyMapping(Class<?> clazz) throws IOException {
|
||||
public String buildPropertyMapping(Class<?> clazz) throws IOException {
|
||||
|
||||
ElasticsearchPersistentEntity<?> entity = elasticsearchConverter.getMappingContext()
|
||||
.getRequiredPersistentEntity(clazz);
|
||||
@ -124,7 +117,7 @@ class MappingBuilder {
|
||||
// Parent
|
||||
String parentType = entity.getParentType();
|
||||
if (hasText(parentType)) {
|
||||
builder.startObject(FIELD_PARENT).field(FIELD_TYPE, parentType).endObject();
|
||||
builder.startObject(FIELD_PARENT).field(FIELD_PARAM_TYPE, parentType).endObject();
|
||||
}
|
||||
|
||||
// Properties
|
||||
@ -149,7 +142,7 @@ class MappingBuilder {
|
||||
|
||||
String type = nestedOrObjectField ? fieldType.toString().toLowerCase()
|
||||
: FieldType.Object.toString().toLowerCase();
|
||||
builder.startObject(nestedObjectFieldName).field(FIELD_TYPE, type);
|
||||
builder.startObject(nestedObjectFieldName).field(FIELD_PARAM_TYPE, type);
|
||||
|
||||
if (nestedOrObjectField && FieldType.Nested == fieldType && parentFieldAnnotation != null
|
||||
&& parentFieldAnnotation.includeInParent()) {
|
||||
@ -250,14 +243,14 @@ class MappingBuilder {
|
||||
private void applyGeoPointFieldMapping(XContentBuilder builder, ElasticsearchPersistentProperty property)
|
||||
throws IOException {
|
||||
|
||||
builder.startObject(property.getFieldName()).field(FIELD_TYPE, TYPE_VALUE_GEO_POINT).endObject();
|
||||
builder.startObject(property.getFieldName()).field(FIELD_PARAM_TYPE, TYPE_VALUE_GEO_POINT).endObject();
|
||||
}
|
||||
|
||||
private void applyCompletionFieldMapping(XContentBuilder builder, ElasticsearchPersistentProperty property,
|
||||
@Nullable CompletionField annotation) throws IOException {
|
||||
|
||||
builder.startObject(property.getFieldName());
|
||||
builder.field(FIELD_TYPE, TYPE_VALUE_COMPLETION);
|
||||
builder.field(FIELD_PARAM_TYPE, TYPE_VALUE_COMPLETION);
|
||||
|
||||
if (annotation != null) {
|
||||
|
||||
@ -265,10 +258,10 @@ class MappingBuilder {
|
||||
builder.field(COMPLETION_PRESERVE_POSITION_INCREMENTS, annotation.preservePositionIncrements());
|
||||
builder.field(COMPLETION_PRESERVE_SEPARATORS, annotation.preserveSeparators());
|
||||
if (!StringUtils.isEmpty(annotation.searchAnalyzer())) {
|
||||
builder.field(FIELD_SEARCH_ANALYZER, annotation.searchAnalyzer());
|
||||
builder.field(FIELD_PARAM_SEARCH_ANALYZER, annotation.searchAnalyzer());
|
||||
}
|
||||
if (!StringUtils.isEmpty(annotation.analyzer())) {
|
||||
builder.field(FIELD_INDEX_ANALYZER, annotation.analyzer());
|
||||
builder.field(FIELD_PARAM_INDEX_ANALYZER, annotation.analyzer());
|
||||
}
|
||||
|
||||
if (annotation.contexts().length > 0) {
|
||||
@ -294,7 +287,7 @@ class MappingBuilder {
|
||||
private void applyDefaultIdFieldMapping(XContentBuilder builder, ElasticsearchPersistentProperty property)
|
||||
throws IOException {
|
||||
|
||||
builder.startObject(property.getFieldName()).field(FIELD_TYPE, TYPE_VALUE_KEYWORD).field(FIELD_INDEX, true)
|
||||
builder.startObject(property.getFieldName()).field(FIELD_PARAM_TYPE, TYPE_VALUE_KEYWORD).field(FIELD_INDEX, true)
|
||||
.endObject();
|
||||
}
|
||||
|
||||
@ -335,92 +328,15 @@ class MappingBuilder {
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
private void addFieldMappingParameters(XContentBuilder builder, Object annotation, boolean nestedOrObjectField)
|
||||
private void addFieldMappingParameters(XContentBuilder builder, Annotation annotation, boolean nestedOrObjectField)
|
||||
throws IOException {
|
||||
|
||||
boolean index = true;
|
||||
boolean store = false;
|
||||
boolean fielddata = false;
|
||||
FieldType type = null;
|
||||
DateFormat dateFormat = null;
|
||||
String datePattern = null;
|
||||
String analyzer = null;
|
||||
String searchAnalyzer = null;
|
||||
String normalizer = null;
|
||||
String[] copyTo = null;
|
||||
Integer ignoreAbove = null;
|
||||
MappingParameters mappingParameters = MappingParameters.from(annotation);
|
||||
|
||||
if (annotation instanceof Field) {
|
||||
// @Field
|
||||
Field fieldAnnotation = (Field) annotation;
|
||||
index = fieldAnnotation.index();
|
||||
store = fieldAnnotation.store();
|
||||
fielddata = fieldAnnotation.fielddata();
|
||||
type = fieldAnnotation.type();
|
||||
dateFormat = fieldAnnotation.format();
|
||||
datePattern = fieldAnnotation.pattern();
|
||||
analyzer = fieldAnnotation.analyzer();
|
||||
searchAnalyzer = fieldAnnotation.searchAnalyzer();
|
||||
normalizer = fieldAnnotation.normalizer();
|
||||
copyTo = fieldAnnotation.copyTo();
|
||||
ignoreAbove = fieldAnnotation.ignoreAbove() >= 0 ? fieldAnnotation.ignoreAbove() : null;
|
||||
} else if (annotation instanceof InnerField) {
|
||||
// @InnerField
|
||||
InnerField fieldAnnotation = (InnerField) annotation;
|
||||
index = fieldAnnotation.index();
|
||||
store = fieldAnnotation.store();
|
||||
fielddata = fieldAnnotation.fielddata();
|
||||
type = fieldAnnotation.type();
|
||||
dateFormat = fieldAnnotation.format();
|
||||
datePattern = fieldAnnotation.pattern();
|
||||
analyzer = fieldAnnotation.analyzer();
|
||||
searchAnalyzer = fieldAnnotation.searchAnalyzer();
|
||||
normalizer = fieldAnnotation.normalizer();
|
||||
ignoreAbove = fieldAnnotation.ignoreAbove() >= 0 ? fieldAnnotation.ignoreAbove() : null;
|
||||
} else {
|
||||
throw new IllegalArgumentException("annotation must be an instance of @Field or @InnerField");
|
||||
}
|
||||
|
||||
if (!nestedOrObjectField) {
|
||||
builder.field(FIELD_STORE, store);
|
||||
}
|
||||
|
||||
if (fielddata) {
|
||||
builder.field(FIELD_DATA, fielddata);
|
||||
}
|
||||
|
||||
if (type != FieldType.Auto) {
|
||||
builder.field(FIELD_TYPE, type.name().toLowerCase());
|
||||
|
||||
if (type == FieldType.Date && dateFormat != DateFormat.none) {
|
||||
builder.field(FIELD_FORMAT, dateFormat == DateFormat.custom ? datePattern : dateFormat.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (!index) {
|
||||
builder.field(FIELD_INDEX, index);
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(analyzer)) {
|
||||
builder.field(FIELD_INDEX_ANALYZER, analyzer);
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(searchAnalyzer)) {
|
||||
builder.field(FIELD_SEARCH_ANALYZER, searchAnalyzer);
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(normalizer)) {
|
||||
builder.field(FIELD_NORMALIZER, normalizer);
|
||||
}
|
||||
|
||||
if (copyTo != null && copyTo.length > 0) {
|
||||
builder.field(FIELD_COPY_TO, copyTo);
|
||||
}
|
||||
|
||||
if (ignoreAbove != null) {
|
||||
Assert.isTrue(ignoreAbove >= 0, "ignore_above must be a positive value");
|
||||
builder.field(FIELD_IGNORE_ABOVE, ignoreAbove);
|
||||
if (!nestedOrObjectField && mappingParameters.isStore()) {
|
||||
builder.field(FIELD_PARAM_STORE, mappingParameters.isStore());
|
||||
}
|
||||
mappingParameters.writeTypeAndParametersTo(builder);
|
||||
}
|
||||
|
||||
/**
|
@ -0,0 +1,272 @@
|
||||
/*
|
||||
* 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.core.indexmapping;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
import org.springframework.data.elasticsearch.annotations.IndexOptions;
|
||||
import org.springframework.data.elasticsearch.annotations.IndexPrefixes;
|
||||
import org.springframework.data.elasticsearch.annotations.InnerField;
|
||||
import org.springframework.data.elasticsearch.annotations.Similarity;
|
||||
import org.springframework.data.elasticsearch.annotations.TermVector;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A class to hold the mapping parameters that might be set on
|
||||
* {@link org.springframework.data.elasticsearch.annotations.Field } or
|
||||
* {@link org.springframework.data.elasticsearch.annotations.InnerField} annotation.
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
* @since 4.0
|
||||
*/
|
||||
public final class MappingParameters {
|
||||
|
||||
static final String FIELD_PARAM_COERCE = "coerce";
|
||||
static final String FIELD_PARAM_COPY_TO = "copy_to";
|
||||
static final String FIELD_PARAM_DOC_VALUES = "doc_values";
|
||||
static final String FIELD_PARAM_DATA = "fielddata";
|
||||
static final String FIELD_PARAM_FORMAT = "format";
|
||||
static final String FIELD_PARAM_IGNORE_ABOVE = "ignore_above";
|
||||
static final String FIELD_PARAM_IGNORE_MALFORMED = "ignore_malformed";
|
||||
static final String FIELD_PARAM_INDEX = "index";
|
||||
static final String FIELD_PARAM_INDEX_OPTIONS = "index_options";
|
||||
static final String FIELD_PARAM_INDEX_PHRASES = "index_phrases";
|
||||
static final String FIELD_PARAM_INDEX_PREFIXES = "index_prefixes";
|
||||
static final String FIELD_PARAM_INDEX_PREFIXES_MIN_CHARS = "min_chars";
|
||||
static final String FIELD_PARAM_INDEX_PREFIXES_MAX_CHARS = "max_chars";
|
||||
static final String FIELD_PARAM_INDEX_ANALYZER = "analyzer";
|
||||
static final String FIELD_PARAM_NORMALIZER = "normalizer";
|
||||
static final String FIELD_PARAM_NORMS = "norms";
|
||||
static final String FIELD_PARAM_NULL_VALUE = "null_value";
|
||||
static final String FIELD_PARAMETER_NAME_POSITION_INCREMENT_GAP = "position_increment_gap";
|
||||
static final String FIELD_PARAM_SCALING_FACTOR = "scaling_factor";
|
||||
static final String FIELD_PARAM_SEARCH_ANALYZER = "search_analyzer";
|
||||
static final String FIELD_PARAM_STORE = "store";
|
||||
static final String FIELD_PARAM_SIMILARITY = "similarity";
|
||||
static final String FIELD_PARAM_TERM_VECTOR = "term_vector";
|
||||
static final String FIELD_PARAM_TYPE = "type";
|
||||
|
||||
private boolean index = true;
|
||||
private boolean store = false;
|
||||
private boolean fielddata = false;
|
||||
private FieldType type = null;
|
||||
private DateFormat dateFormat = null;
|
||||
private String datePattern = null;
|
||||
private String analyzer = null;
|
||||
private String searchAnalyzer = null;
|
||||
private String normalizer = null;
|
||||
private String[] copyTo = null;
|
||||
private Integer ignoreAbove = null;
|
||||
private boolean coerce = true;
|
||||
private boolean docValues = true;
|
||||
private boolean ignoreMalformed = false;
|
||||
private IndexOptions indexOptions = null;
|
||||
boolean indexPhrases = false;
|
||||
private IndexPrefixes indexPrefixes = null;
|
||||
private boolean norms = true;
|
||||
private String nullValue = null;
|
||||
private Integer positionIncrementGap = null;
|
||||
private Similarity similarity = Similarity.Default;
|
||||
private TermVector termVector = TermVector.none;
|
||||
private double scalingFactor = 1.0;
|
||||
|
||||
/**
|
||||
* extracts the mapping parameters from the relevant annotations.
|
||||
*
|
||||
* @param annotation must not be {@literal null}.
|
||||
* @return empty Optional if the annotation does not have a conformant type.
|
||||
*/
|
||||
public static MappingParameters from(Annotation annotation) {
|
||||
|
||||
Assert.notNull(annotation, "annotation must not be null!");
|
||||
|
||||
if (annotation instanceof Field) {
|
||||
return new MappingParameters((Field) annotation);
|
||||
} else if (annotation instanceof InnerField) {
|
||||
return new MappingParameters((InnerField) annotation);
|
||||
} else {
|
||||
throw new IllegalArgumentException("annotation must be an instance of @Field or @InnerField");
|
||||
}
|
||||
}
|
||||
|
||||
private MappingParameters(Field field) {
|
||||
index = field.index();
|
||||
store = field.store();
|
||||
fielddata = field.fielddata();
|
||||
type = field.type();
|
||||
dateFormat = field.format();
|
||||
datePattern = field.pattern();
|
||||
analyzer = field.analyzer();
|
||||
searchAnalyzer = field.searchAnalyzer();
|
||||
normalizer = field.normalizer();
|
||||
copyTo = field.copyTo();
|
||||
ignoreAbove = field.ignoreAbove() >= 0 ? field.ignoreAbove() : null;
|
||||
coerce = field.coerce();
|
||||
docValues = field.docValues();
|
||||
Assert.isTrue(!((type == FieldType.Text || type == FieldType.Nested) && !docValues),
|
||||
"docValues false is not allowed for field type text");
|
||||
ignoreMalformed = field.ignoreMalformed();
|
||||
indexOptions = field.indexOptions();
|
||||
indexPhrases = field.indexPhrases();
|
||||
if (field.indexPrefixes().length > 0) {
|
||||
indexPrefixes = field.indexPrefixes()[0];
|
||||
}
|
||||
norms = field.norms();
|
||||
nullValue = field.nullValue();
|
||||
positionIncrementGap = field.positionIncrementGap();
|
||||
similarity = field.similarity();
|
||||
termVector = field.termVector();
|
||||
scalingFactor = field.scalingFactor();
|
||||
}
|
||||
|
||||
private MappingParameters(InnerField field) {
|
||||
index = field.index();
|
||||
store = field.store();
|
||||
fielddata = field.fielddata();
|
||||
type = field.type();
|
||||
dateFormat = field.format();
|
||||
datePattern = field.pattern();
|
||||
analyzer = field.analyzer();
|
||||
searchAnalyzer = field.searchAnalyzer();
|
||||
normalizer = field.normalizer();
|
||||
ignoreAbove = field.ignoreAbove() >= 0 ? field.ignoreAbove() : null;
|
||||
coerce = field.coerce();
|
||||
docValues = field.docValues();
|
||||
Assert.isTrue(!((type == FieldType.Text || type == FieldType.Nested) && !docValues),
|
||||
"docValues false is not allowed for field type text");
|
||||
ignoreMalformed = field.ignoreMalformed();
|
||||
indexOptions = field.indexOptions();
|
||||
indexPhrases = field.indexPhrases();
|
||||
if (field.indexPrefixes().length > 0) {
|
||||
indexPrefixes = field.indexPrefixes()[0];
|
||||
}
|
||||
norms = field.norms();
|
||||
nullValue = field.nullValue();
|
||||
positionIncrementGap = field.positionIncrementGap();
|
||||
similarity = field.similarity();
|
||||
termVector = field.termVector();
|
||||
scalingFactor = field.scalingFactor();
|
||||
}
|
||||
|
||||
public boolean isStore() {
|
||||
return store;
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the different fields to the builder.
|
||||
*
|
||||
* @param builder must not be {@literal null}.
|
||||
*/
|
||||
public void writeTypeAndParametersTo(XContentBuilder builder) throws IOException {
|
||||
Assert.notNull(builder, "builder must ot be null");
|
||||
|
||||
if (fielddata) {
|
||||
builder.field(FIELD_PARAM_DATA, fielddata);
|
||||
}
|
||||
|
||||
if (type != FieldType.Auto) {
|
||||
builder.field(FIELD_PARAM_TYPE, type.name().toLowerCase());
|
||||
if (type == FieldType.Date && dateFormat != DateFormat.none) {
|
||||
builder.field(FIELD_PARAM_FORMAT, dateFormat == DateFormat.custom ? datePattern : dateFormat.toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (!index) {
|
||||
builder.field(FIELD_PARAM_INDEX, index);
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(analyzer)) {
|
||||
builder.field(FIELD_PARAM_INDEX_ANALYZER, analyzer);
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(searchAnalyzer)) {
|
||||
builder.field(FIELD_PARAM_SEARCH_ANALYZER, searchAnalyzer);
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(normalizer)) {
|
||||
builder.field(FIELD_PARAM_NORMALIZER, normalizer);
|
||||
}
|
||||
|
||||
if (copyTo != null && copyTo.length > 0) {
|
||||
builder.field(FIELD_PARAM_COPY_TO, copyTo);
|
||||
}
|
||||
|
||||
if (ignoreAbove != null) {
|
||||
Assert.isTrue(ignoreAbove >= 0, "ignore_above must be a positive value");
|
||||
builder.field(FIELD_PARAM_IGNORE_ABOVE, ignoreAbove);
|
||||
}
|
||||
|
||||
if (!coerce) {
|
||||
builder.field(FIELD_PARAM_COERCE, coerce);
|
||||
}
|
||||
|
||||
if (!docValues) {
|
||||
builder.field(FIELD_PARAM_DOC_VALUES, docValues);
|
||||
}
|
||||
|
||||
if (ignoreMalformed) {
|
||||
builder.field(FIELD_PARAM_IGNORE_MALFORMED, ignoreMalformed);
|
||||
}
|
||||
|
||||
if (indexOptions != IndexOptions.none) {
|
||||
builder.field(FIELD_PARAM_INDEX_OPTIONS, indexOptions);
|
||||
}
|
||||
|
||||
if (indexPhrases) {
|
||||
builder.field(FIELD_PARAM_INDEX_PHRASES, indexPhrases);
|
||||
}
|
||||
|
||||
if (indexPrefixes != null) {
|
||||
builder.startObject(FIELD_PARAM_INDEX_PREFIXES);
|
||||
if (indexPrefixes.minChars() != IndexPrefixes.MIN_DEFAULT) {
|
||||
builder.field(FIELD_PARAM_INDEX_PREFIXES_MIN_CHARS, indexPrefixes.minChars());
|
||||
}
|
||||
if (indexPrefixes.maxChars() != IndexPrefixes.MAX_DEFAULT) {
|
||||
builder.field(FIELD_PARAM_INDEX_PREFIXES_MAX_CHARS, indexPrefixes.maxChars());
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
if (!norms) {
|
||||
builder.field(FIELD_PARAM_NORMS, norms);
|
||||
}
|
||||
|
||||
if (!StringUtils.isEmpty(nullValue)) {
|
||||
builder.field(FIELD_PARAM_NULL_VALUE, nullValue);
|
||||
}
|
||||
|
||||
if (positionIncrementGap != null && positionIncrementGap >= 0) {
|
||||
builder.field(FIELD_PARAMETER_NAME_POSITION_INCREMENT_GAP, positionIncrementGap);
|
||||
}
|
||||
|
||||
if (similarity != Similarity.Default) {
|
||||
builder.field(FIELD_PARAM_SIMILARITY, similarity);
|
||||
}
|
||||
|
||||
if (termVector != TermVector.none) {
|
||||
builder.field(FIELD_PARAM_TERM_VECTOR, termVector);
|
||||
}
|
||||
|
||||
if (type == FieldType.Scaled_Float) {
|
||||
builder.field(FIELD_PARAM_SCALING_FACTOR, scalingFactor);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
/**
|
||||
* infrastructure to define the Elasticsearch mapping for an index.
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
package org.springframework.data.elasticsearch.core.indexmapping;
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.elasticsearch.core;
|
||||
package org.springframework.data.elasticsearch.core.indexmapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.*;
|
||||
@ -30,6 +30,7 @@ import lombok.Setter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.Boolean;
|
||||
import java.lang.Double;
|
||||
import java.lang.Integer;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
@ -49,16 +50,8 @@ import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Transient;
|
||||
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.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.annotations.Parent;
|
||||
import org.springframework.data.elasticsearch.annotations.Setting;
|
||||
import org.springframework.data.elasticsearch.annotations.*;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.core.completion.Completion;
|
||||
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
|
||||
import org.springframework.data.elasticsearch.core.query.IndexQuery;
|
||||
@ -125,7 +118,7 @@ public class MappingBuilderTests extends MappingContextBaseTests {
|
||||
public void shouldUseValueFromAnnotationType() throws IOException, JSONException {
|
||||
|
||||
// Given
|
||||
String expected = "{\"price\":{\"properties\":{\"price\":{\"store\":false,\"type\":\"double\"}}}}";
|
||||
String expected = "{\"price\":{\"properties\":{\"price\":{\"type\":\"double\"}}}}";
|
||||
|
||||
// When
|
||||
String mapping = getMappingBuilder().buildPropertyMapping(StockPrice.class);
|
||||
@ -174,7 +167,7 @@ public class MappingBuilderTests extends MappingContextBaseTests {
|
||||
public void shouldBuildMappingWithSuperclass() throws IOException, JSONException {
|
||||
|
||||
String expected = "{\"mapping\":{\"properties\":{\"message\":{\"store\":true,\""
|
||||
+ "type\":\"text\",\"index\":false,\"analyzer\":\"standard\"}" + ",\"createdDate\":{\"store\":false,"
|
||||
+ "type\":\"text\",\"index\":false,\"analyzer\":\"standard\"}" + ",\"createdDate\":{"
|
||||
+ "\"type\":\"date\",\"index\":false}}}}";
|
||||
|
||||
String mapping = getMappingBuilder().buildPropertyMapping(SampleInheritedEntity.class);
|
||||
@ -329,7 +322,7 @@ public class MappingBuilderTests extends MappingContextBaseTests {
|
||||
|
||||
// given
|
||||
String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true},"
|
||||
+ "\"text-property\":{\"store\":false,\"type\":\"text\"}" + "}}}";
|
||||
+ "\"text-property\":{\"type\":\"text\"}" + "}}}";
|
||||
|
||||
// when
|
||||
String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.TextEntity.class);
|
||||
@ -371,7 +364,7 @@ public class MappingBuilderTests extends MappingContextBaseTests {
|
||||
|
||||
// given
|
||||
String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true},"
|
||||
+ "\"circular-property\":{\"type\":\"object\",\"properties\":{\"id-property\":{\"store\":false}}}" + "}}}";
|
||||
+ "\"circular-property\":{\"type\":\"object\",\"properties\":{\"id-property\":{}}}" + "}}}";
|
||||
|
||||
// when
|
||||
String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.CircularEntity.class);
|
||||
@ -385,7 +378,7 @@ public class MappingBuilderTests extends MappingContextBaseTests {
|
||||
|
||||
// given
|
||||
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}"
|
||||
+ "\"completion-property\":{\"type\":\"completion\",\"max_input_length\":100,\"preserve_position_increments\":true,\"preserve_separators\":true,\"search_analyzer\":\"simple\",\"analyzer\":\"simple\"},\"completion-property\":{}"
|
||||
+ "}}}";
|
||||
|
||||
// when
|
||||
@ -400,7 +393,7 @@ public class MappingBuilderTests extends MappingContextBaseTests {
|
||||
|
||||
// given
|
||||
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\"}}}"
|
||||
+ "\"multifield-property\":{\"type\":\"text\",\"analyzer\":\"whitespace\",\"fields\":{\"prefix\":{\"type\":\"text\",\"analyzer\":\"stop\",\"search_analyzer\":\"standard\"}}}"
|
||||
+ "}}}";
|
||||
|
||||
// when
|
||||
@ -414,7 +407,7 @@ public class MappingBuilderTests extends MappingContextBaseTests {
|
||||
public void shouldUseIgnoreAbove() throws IOException, JSONException {
|
||||
|
||||
// given
|
||||
String expected = "{\"ignore-above-type\":{\"properties\":{\"message\":{\"store\":false,\"type\":\"keyword\",\"ignore_above\":10}}}}";
|
||||
String expected = "{\"ignore-above-type\":{\"properties\":{\"message\":{\"type\":\"keyword\",\"ignore_above\":10}}}}";
|
||||
|
||||
// when
|
||||
String mapping = getMappingBuilder().buildPropertyMapping(IgnoreAboveEntity.class);
|
||||
@ -423,6 +416,104 @@ public class MappingBuilderTests extends MappingContextBaseTests {
|
||||
assertEquals(expected, mapping, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSetFieldMappingProperties() throws JSONException, IOException {
|
||||
String expected = "{\n" + //
|
||||
" \"fmp\": {\n" + //
|
||||
" \"properties\": {\n" + //
|
||||
" \"storeTrue\": {\n" + //
|
||||
" \"store\": true\n" + //
|
||||
" },\n" + //
|
||||
" \"storeFalse\": {},\n" + //
|
||||
" \"indexTrue\": {},\n" + //
|
||||
" \"indexFalse\": {\n" + //
|
||||
" \"index\": false\n" + //
|
||||
" },\n" + //
|
||||
" \"coerceTrue\": {},\n" + //
|
||||
" \"coerceFalse\": {\n" + //
|
||||
" \"coerce\": false\n" + //
|
||||
" },\n" + //
|
||||
" \"fielddataTrue\": {\n" + //
|
||||
" \"fielddata\": true\n" + //
|
||||
" },\n" + //
|
||||
" \"fielddataFalse\": {},\n" + //
|
||||
" \"type\": {\n" + //
|
||||
" \"type\": \"integer\"\n" + //
|
||||
" },\n" + //
|
||||
" \"ignoreAbove\": {\n" + //
|
||||
" \"ignore_above\": 42\n" + //
|
||||
" },\n" + //
|
||||
" \"copyTo\": {\n" + //
|
||||
" \"copy_to\": [\"foo\", \"bar\"]\n" + //
|
||||
" },\n" + //
|
||||
" \"date\": {\n" + //
|
||||
" \"type\": \"date\",\n" + //
|
||||
" \"format\": \"YYYYMMDD\"\n" + //
|
||||
" },\n" + //
|
||||
" \"analyzers\": {\n" + //
|
||||
" \"analyzer\": \"ana\",\n" + //
|
||||
" \"search_analyzer\": \"sana\",\n" + //
|
||||
" \"normalizer\": \"norma\"\n" + //
|
||||
" },\n" + //
|
||||
" \"docValuesTrue\": {\n" + //
|
||||
" \"type\": \"keyword\"\n" + //
|
||||
" },\n" + //
|
||||
" \"docValuesFalse\": {\n" + //
|
||||
" \"type\": \"keyword\",\n" + //
|
||||
" \"doc_values\": false\n" + //
|
||||
" },\n" + //
|
||||
" \"ignoreMalformedFalse\": {},\n" + //
|
||||
" \"ignoreMalformedTrue\": {\n" + //
|
||||
" \"ignore_malformed\": true\n" + //
|
||||
" },\n" + //
|
||||
" \"indexPhrasesTrue\": {\n" + //
|
||||
" \"index_phrases\": true\n" + //
|
||||
" },\n" + //
|
||||
" \"indexPhrasesFalse\": {},\n" + //
|
||||
" \"indexOptionsNone\": {},\n" + //
|
||||
" \"indexOptionsPositions\": {\n" + //
|
||||
" \"index_options\": \"positions\"\n" + //
|
||||
" },\n" + //
|
||||
" \"defaultIndexPrefixes\": {\n" + //
|
||||
" \"index_prefixes\":{}" + //
|
||||
" },\n" + //
|
||||
" \"customIndexPrefixes\": {\n" + //
|
||||
" \"index_prefixes\":{\"min_chars\":1,\"max_chars\":10}" + //
|
||||
" },\n" + //
|
||||
" \"normsTrue\": {},\n" + //
|
||||
" \"normsFalse\": {\n" + //
|
||||
" \"norms\": false\n" + //
|
||||
" },\n" + //
|
||||
" \"nullValueNotSet\": {},\n" + //
|
||||
" \"nullValueSet\": {\n" + //
|
||||
" \"null_value\": \"NULLNULL\"\n" + //
|
||||
" },\n" + //
|
||||
" \"positionIncrementGap\": {\n" + //
|
||||
" \"position_increment_gap\": 42\n" + //
|
||||
" },\n" + //
|
||||
" \"similarityDefault\": {},\n" + //
|
||||
" \"similarityBoolean\": {\n" + //
|
||||
" \"similarity\": \"boolean\"\n" + //
|
||||
" },\n" + //
|
||||
" \"termVectorDefault\": {},\n" + //
|
||||
" \"termVectorWithOffsets\": {\n" + //
|
||||
" \"term_vector\": \"with_offsets\"\n" + //
|
||||
" },\n" + //
|
||||
" \"scaledFloat\": {\n" + //
|
||||
" \"type\": \"scaled_float\",\n" + //
|
||||
" \"scaling_factor\": 100.0\n" + //
|
||||
" }\n" + //
|
||||
" }\n" + //
|
||||
" }\n" + //
|
||||
"}\n"; //
|
||||
|
||||
// when
|
||||
String mapping = getMappingBuilder().buildPropertyMapping(FieldMappingParameters.class);
|
||||
|
||||
// then
|
||||
assertEquals(expected, mapping, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Xiao Yu
|
||||
*/
|
||||
@ -821,4 +912,40 @@ public class MappingBuilderTests extends MappingContextBaseTests {
|
||||
@Field(type = FieldType.Nested, ignoreFields = { "groups" }) private Set<User> users = new HashSet<>();
|
||||
}
|
||||
|
||||
@Document(indexName = "test-index-field-mapping-parameters", type = "fmp")
|
||||
static class FieldMappingParameters {
|
||||
@Field private String indexTrue;
|
||||
@Field(index = false) private String indexFalse;
|
||||
@Field(store = true) private String storeTrue;
|
||||
@Field private String storeFalse;
|
||||
@Field private String coerceTrue;
|
||||
@Field(coerce = false) private String coerceFalse;
|
||||
@Field(fielddata = true) private String fielddataTrue;
|
||||
@Field private String fielddataFalse;
|
||||
@Field(copyTo = { "foo", "bar" }) private String copyTo;
|
||||
@Field(ignoreAbove = 42) private String ignoreAbove;
|
||||
@Field(type = FieldType.Integer) private String type;
|
||||
@Field(type = FieldType.Date, format = DateFormat.custom, pattern = "YYYYMMDD") private String date;
|
||||
@Field(analyzer = "ana", searchAnalyzer = "sana", normalizer = "norma") private String analyzers;
|
||||
@Field(type = Keyword, docValues = true) private String docValuesTrue;
|
||||
@Field(type = Keyword, docValues = false) private String docValuesFalse;
|
||||
@Field(ignoreMalformed = true) private String ignoreMalformedTrue;
|
||||
@Field(ignoreMalformed = false) private String ignoreMalformedFalse;
|
||||
@Field(indexOptions = IndexOptions.none) private String indexOptionsNone;
|
||||
@Field(indexOptions = IndexOptions.positions) private String indexOptionsPositions;
|
||||
@Field(indexPhrases = true) private String indexPhrasesTrue;
|
||||
@Field(indexPhrases = false) private String indexPhrasesFalse;
|
||||
@Field(indexPrefixes = @IndexPrefixes) private String defaultIndexPrefixes;
|
||||
@Field(indexPrefixes = @IndexPrefixes(minChars = 1, maxChars = 10)) private String customIndexPrefixes;
|
||||
@Field private String normsTrue;
|
||||
@Field(norms = false) private String normsFalse;
|
||||
@Field private String nullValueNotSet;
|
||||
@Field(nullValue = "NULLNULL") private String nullValueSet;
|
||||
@Field(positionIncrementGap = 42) private String positionIncrementGap;
|
||||
@Field private String similarityDefault;
|
||||
@Field(similarity = Similarity.Boolean) private String similarityBoolean;
|
||||
@Field private String termVectorDefault;
|
||||
@Field(termVector = TermVector.with_offsets) private String termVectorWithOffsets;
|
||||
@Field(type = FieldType.Scaled_Float, scalingFactor = 100.0) Double scaledFloat;
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.elasticsearch.core;
|
||||
package org.springframework.data.elasticsearch.core.indexmapping;
|
||||
|
||||
import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport;
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
@ -0,0 +1,68 @@
|
||||
package org.springframework.data.elasticsearch.core.indexmapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.junit.Test;
|
||||
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.Score;
|
||||
import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity;
|
||||
|
||||
/**
|
||||
* @author Peter-Josef Meisch
|
||||
*/
|
||||
public class MappingParametersTest extends MappingContextBaseTests {
|
||||
|
||||
private ElasticsearchPersistentEntity<?> entity = elasticsearchConverter.get().getMappingContext()
|
||||
.getRequiredPersistentEntity(AnnotatedClass.class);
|
||||
|
||||
@Test // DATAES-621
|
||||
public void shouldCreateParametersForFieldAnnotation() {
|
||||
Annotation annotation = entity.getRequiredPersistentProperty("field").findAnnotation(Field.class);
|
||||
|
||||
MappingParameters mappingParameters = MappingParameters.from(annotation);
|
||||
|
||||
assertThat(mappingParameters).isNotNull();
|
||||
}
|
||||
|
||||
@Test // DATAES-621
|
||||
public void shouldCreateParametersForInnerFieldAnnotation() {
|
||||
Annotation annotation = entity.getRequiredPersistentProperty("innerField").findAnnotation(InnerField.class);
|
||||
|
||||
MappingParameters mappingParameters = MappingParameters.from(annotation);
|
||||
|
||||
assertThat(mappingParameters).isNotNull();
|
||||
}
|
||||
|
||||
@Test // DATAES-621
|
||||
public void shouldNotCreateParametersForUnknownAnnotation() {
|
||||
Annotation annotation = entity.getRequiredPersistentProperty("score").findAnnotation(Score.class);
|
||||
|
||||
assertThatThrownBy(() -> MappingParameters.from(annotation)).isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test // DATAES-621
|
||||
public void shouldNotAllowDocValueFalseOnFieldTypeText() {
|
||||
Annotation annotation = entity.getRequiredPersistentProperty("docValuesText").findAnnotation(Field.class);
|
||||
|
||||
assertThatThrownBy(() -> MappingParameters.from(annotation)).isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test // DATAES-621
|
||||
public void shouldNotAllowDocValuesFalseOnFieldTypeNested() {
|
||||
Annotation annotation = entity.getRequiredPersistentProperty("docValuesNested").findAnnotation(Field.class);
|
||||
|
||||
assertThatThrownBy(() -> MappingParameters.from(annotation)).isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
static class AnnotatedClass {
|
||||
@Field private String field;
|
||||
@InnerField(suffix = "test", type = FieldType.Text) private String innerField;
|
||||
@Score private float score;
|
||||
@Field(type = FieldType.Text, docValues = false) private String docValuesText;
|
||||
@Field(type = FieldType.Nested, docValues = false) private String docValuesNested;
|
||||
}
|
||||
}
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core;
|
||||
package org.springframework.data.elasticsearch.core.indexmapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.elasticsearch.core;
|
||||
package org.springframework.data.elasticsearch.core.indexmapping;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
|
||||
@ -24,7 +24,6 @@ import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.DateFormat;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
@ -40,8 +39,8 @@ import org.springframework.data.elasticsearch.annotations.FieldType;
|
||||
public class SimpleElasticsearchDateMappingTests extends MappingContextBaseTests {
|
||||
|
||||
private static final String EXPECTED_MAPPING = "{\"mapping\":{\"properties\":{\"message\":{\"store\":true,"
|
||||
+ "\"type\":\"text\",\"index\":false,\"analyzer\":\"standard\"},\"customFormatDate\":{\"store\":false,\"type\":\"date\",\"format\":\"dd.MM.yyyy hh:mm\"},"
|
||||
+ "\"defaultFormatDate\":{\"store\":false,\"type\":\"date\"},\"basicFormatDate\":{\"store\":false,\""
|
||||
+ "\"type\":\"text\",\"index\":false,\"analyzer\":\"standard\"},\"customFormatDate\":{\"type\":\"date\",\"format\":\"dd.MM.yyyy hh:mm\"},"
|
||||
+ "\"defaultFormatDate\":{\"type\":\"date\"},\"basicFormatDate\":{\""
|
||||
+ "type\":\"date\",\"format\":\"basic_date\"}}}}";
|
||||
|
||||
@Test // DATAES-568
|
Loading…
x
Reference in New Issue
Block a user