Allow to customize mappings parameters.
Signed-off-by: Andriy Redko <drreta@gmail.com>
This commit is contained in:
@@ -112,9 +112,15 @@ public class MappingBuilder {
|
||||
|
||||
protected final ElasticsearchConverter elasticsearchConverter;
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final MappingParametersCustomizer customizer;
|
||||
|
||||
public MappingBuilder(ElasticsearchConverter elasticsearchConverter) {
|
||||
this(elasticsearchConverter, MappingParameters::from);
|
||||
}
|
||||
|
||||
public MappingBuilder(ElasticsearchConverter elasticsearchConverter, MappingParametersCustomizer customizer) {
|
||||
this.elasticsearchConverter = elasticsearchConverter;
|
||||
this.customizer = customizer;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -589,7 +595,7 @@ public class MappingBuilder {
|
||||
private void addFieldMappingParameters(ObjectNode fieldNode, Annotation annotation, boolean nestedOrObjectField)
|
||||
throws IOException {
|
||||
|
||||
MappingParameters mappingParameters = MappingParameters.from(annotation);
|
||||
MappingParameters mappingParameters = customizer.from(annotation);
|
||||
|
||||
if (!nestedOrObjectField && mappingParameters.isStore()) {
|
||||
fieldNode.put(FIELD_PARAM_STORE, true);
|
||||
|
||||
+134
-3
@@ -35,6 +35,8 @@ 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.
|
||||
* The class allows extensibility (non-final) to simplify mapping parameters customization,
|
||||
* provided by {@link org.springframework.data.elasticsearch.core.index.MappingParametersCustomizer}.
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Aleksei Arsenev
|
||||
@@ -42,9 +44,10 @@ import org.springframework.util.StringUtils;
|
||||
* @author Morgan Lutz
|
||||
* @author Sascha Woo
|
||||
* @author Haibo Liu
|
||||
* @author Andriy Redko
|
||||
* @since 4.0
|
||||
*/
|
||||
public final class MappingParameters {
|
||||
public class MappingParameters {
|
||||
|
||||
static final String FIELD_PARAM_COERCE = "coerce";
|
||||
static final String FIELD_PARAM_COPY_TO = "copy_to";
|
||||
@@ -137,7 +140,7 @@ public final class MappingParameters {
|
||||
}
|
||||
}
|
||||
|
||||
private MappingParameters(Field field) {
|
||||
protected MappingParameters(Field field) {
|
||||
index = field.index();
|
||||
store = field.store();
|
||||
fielddata = field.fielddata();
|
||||
@@ -184,7 +187,7 @@ public final class MappingParameters {
|
||||
eagerGlobalOrdinals = field.eagerGlobalOrdinals();
|
||||
}
|
||||
|
||||
private MappingParameters(InnerField field) {
|
||||
protected MappingParameters(InnerField field) {
|
||||
index = field.index();
|
||||
store = field.store();
|
||||
fielddata = field.fielddata();
|
||||
@@ -417,4 +420,132 @@ public final class MappingParameters {
|
||||
objectNode.put(FIELD_PARAM_EAGER_GLOBAL_ORDINALS, eagerGlobalOrdinals);
|
||||
}
|
||||
}
|
||||
|
||||
protected String analyzer() {
|
||||
return analyzer;
|
||||
}
|
||||
|
||||
protected boolean coerce() {
|
||||
return coerce;
|
||||
}
|
||||
|
||||
protected String[] copyTo() {
|
||||
return copyTo;
|
||||
}
|
||||
|
||||
protected DateFormat[] dateFormats() {
|
||||
return dateFormats;
|
||||
}
|
||||
|
||||
protected String[] dateFormatPatterns() {
|
||||
return dateFormatPatterns;
|
||||
}
|
||||
|
||||
protected boolean hasDocValues() {
|
||||
return docValues;
|
||||
}
|
||||
|
||||
protected boolean hasEagerGlobalOrdinals() {
|
||||
return eagerGlobalOrdinals;
|
||||
}
|
||||
|
||||
protected boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
protected boolean hasFielddata() {
|
||||
return fielddata;
|
||||
}
|
||||
|
||||
protected Integer ignoreAbove() {
|
||||
return ignoreAbove;
|
||||
}
|
||||
|
||||
protected boolean isIgnoreMalformed() {
|
||||
return ignoreMalformed;
|
||||
}
|
||||
|
||||
protected boolean isIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
protected IndexOptions indexOptions() {
|
||||
return indexOptions;
|
||||
}
|
||||
|
||||
protected boolean isIndexPhrases() {
|
||||
return indexPhrases;
|
||||
}
|
||||
|
||||
protected IndexPrefixes indexPrefixes() {
|
||||
return indexPrefixes;
|
||||
}
|
||||
|
||||
protected String normalizer() {
|
||||
return normalizer;
|
||||
}
|
||||
|
||||
protected boolean hasNorms() {
|
||||
return norms;
|
||||
}
|
||||
|
||||
protected Integer maxShingleSize() {
|
||||
return maxShingleSize;
|
||||
}
|
||||
|
||||
protected String nullValue() {
|
||||
return nullValue;
|
||||
}
|
||||
|
||||
protected NullValueType nullValueType() {
|
||||
return nullValueType;
|
||||
}
|
||||
|
||||
protected Integer positionIncrementGap() {
|
||||
return positionIncrementGap;
|
||||
}
|
||||
|
||||
protected boolean positiveScoreImpact() {
|
||||
return positiveScoreImpact;
|
||||
}
|
||||
|
||||
protected Integer dims() {
|
||||
return dims;
|
||||
}
|
||||
|
||||
protected String elementType() {
|
||||
return elementType;
|
||||
}
|
||||
|
||||
protected KnnSimilarity knnSimilarity() {
|
||||
return knnSimilarity;
|
||||
}
|
||||
|
||||
protected KnnIndexOptions knnIndexOptions() {
|
||||
return knnIndexOptions;
|
||||
}
|
||||
|
||||
protected String searchAnalyzer() {
|
||||
return searchAnalyzer;
|
||||
}
|
||||
|
||||
protected double scalingFactor() {
|
||||
return scalingFactor;
|
||||
}
|
||||
|
||||
protected String similarity() {
|
||||
return similarity;
|
||||
}
|
||||
|
||||
protected TermVector termVector() {
|
||||
return termVector;
|
||||
}
|
||||
|
||||
protected FieldType type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
protected String mappedTypeName() {
|
||||
return mappedTypeName;
|
||||
}
|
||||
}
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2019-present 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.index;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.jspecify.annotations.NonNull;
|
||||
|
||||
/**
|
||||
* Allows to customize {@link org.springframework.data.elasticsearch.core.index.MappingParameters}
|
||||
* that are being emitted for each supported annotation.
|
||||
*
|
||||
* @author Andriy Redko
|
||||
* @since 6.1.0
|
||||
*/
|
||||
public interface MappingParametersCustomizer {
|
||||
/**
|
||||
* Customize @link org.springframework.data.elasticsearch.core.index.MappingParameters}
|
||||
* for each supported annotation.
|
||||
*
|
||||
* @param annotation supported annotation
|
||||
* @return customized @link org.springframework.data.elasticsearch.core.index.MappingParameters}
|
||||
*/
|
||||
@NonNull MappingParameters from(@NonNull Annotation annotation);
|
||||
}
|
||||
+5
@@ -31,6 +31,7 @@ import org.springframework.data.mapping.MappingException;
|
||||
* Subclass of {@link MappingBuilder} with specialized methods To inhibit blocking calls
|
||||
*
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Andriy Redko
|
||||
* @since 4.3
|
||||
*/
|
||||
public class ReactiveMappingBuilder extends MappingBuilder {
|
||||
@@ -38,6 +39,10 @@ public class ReactiveMappingBuilder extends MappingBuilder {
|
||||
public ReactiveMappingBuilder(ElasticsearchConverter elasticsearchConverter) {
|
||||
super(elasticsearchConverter);
|
||||
}
|
||||
|
||||
public ReactiveMappingBuilder(ElasticsearchConverter elasticsearchConverter, MappingParametersCustomizer customizer) {
|
||||
super(elasticsearchConverter, customizer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildPropertyMapping(Class<?> clazz) throws MappingException {
|
||||
|
||||
@@ -19,11 +19,13 @@ import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationS
|
||||
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
|
||||
import org.springframework.data.elasticsearch.core.index.MappingBuilder;
|
||||
import org.springframework.data.elasticsearch.core.index.MappingParametersCustomizer;
|
||||
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
|
||||
import org.springframework.data.util.Lazy;
|
||||
|
||||
/**
|
||||
* @author Peter-Josef Meisch
|
||||
* @author Andriy Redko
|
||||
*/
|
||||
public abstract class MappingContextBaseTests {
|
||||
|
||||
@@ -42,6 +44,10 @@ public abstract class MappingContextBaseTests {
|
||||
return mappingContext;
|
||||
}
|
||||
|
||||
final protected MappingBuilder getMappingBuilder(MappingParametersCustomizer customizer) {
|
||||
return new MappingBuilder(elasticsearchConverter.get(), customizer);
|
||||
}
|
||||
|
||||
final protected MappingBuilder getMappingBuilder() {
|
||||
return new MappingBuilder(elasticsearchConverter.get());
|
||||
}
|
||||
|
||||
+32
@@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.*;
|
||||
import static org.skyscreamer.jsonassert.JSONAssert.*;
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldType.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
@@ -49,6 +50,8 @@ import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Polygon;
|
||||
import org.springframework.data.mapping.MappingException;
|
||||
|
||||
import tools.jackson.databind.node.ObjectNode;
|
||||
|
||||
/**
|
||||
* @author Stuart Stevenson
|
||||
* @author Jakub Vavrik
|
||||
@@ -1339,6 +1342,35 @@ public class MappingBuilderUnitTests extends MappingContextBaseTests {
|
||||
assertEquals(expected, result, true);
|
||||
}
|
||||
|
||||
@Test // #1700
|
||||
@DisplayName("should allow mapping parameters tion")
|
||||
void shouldAllowMappingParametersCustomization() throws JSONException {
|
||||
String expected = """
|
||||
{
|
||||
"properties": {
|
||||
"my_vector": {
|
||||
"type": "dense_vector",
|
||||
"dimensions": 16
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
final MappingParametersCustomizer customizer = annotation -> new MappingParameters((Field) annotation) {
|
||||
@Override
|
||||
public void writeTypeAndParametersTo(ObjectNode objectNode) throws IOException {
|
||||
if (type() == FieldType.Dense_Vector) {
|
||||
objectNode.put(FIELD_PARAM_TYPE, mappedTypeName());
|
||||
objectNode.put("dimensions", dims());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
String mapping = getMappingBuilder(customizer)
|
||||
.buildPropertyMapping(DenseVectorEntity.class);
|
||||
|
||||
assertEquals(expected, mapping, false);
|
||||
}
|
||||
// region entities
|
||||
|
||||
@Document(indexName = "ignore-above-index")
|
||||
|
||||
Reference in New Issue
Block a user