This commit adds a mechanism to MapperTestCase that allows implementing test classes to check that their parameters can be updated, or throw conflict errors as advertised. Child classes override the registerParameters method and tell the passed-in UpdateChecker class about their parameters. Simple conflicts can be checked, using the existing minimal mappings as a base to compare against, or alternatively a particular initial mapping can be provided to check edge cases (eg, norms can be updated from true to false, but not vice versa). Updates are registered with a predicate that checks that the update has in fact been applied to the resulting FieldMapper. Fixes #61631
This commit is contained in:
parent
4b9ddb48b6
commit
e28750b001
|
@ -282,6 +282,14 @@ public class ScaledFloatFieldMapper extends ParametrizedFieldMapper {
|
|||
this.coerceByDefault = builder.coerce.getDefaultValue().value();
|
||||
}
|
||||
|
||||
boolean coerce() {
|
||||
return coerce.value();
|
||||
}
|
||||
|
||||
boolean ignoreMalformed() {
|
||||
return ignoreMalformed.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScaledFloatFieldType fieldType() {
|
||||
return (ScaledFloatFieldType) super.fieldType();
|
||||
|
|
|
@ -33,7 +33,6 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
@ -54,12 +53,9 @@ public class RankFeatureFieldMapperTests extends FieldMapperTestCase2<RankFeatur
|
|||
return org.elasticsearch.common.collect.Set.of("analyzer", "similarity", "store", "doc_values", "index");
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
addModifier("positive_score_impact", false, (a, b) -> {
|
||||
a.positiveScoreImpact(true);
|
||||
b.positiveScoreImpact(false);
|
||||
});
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerConflictCheck("positive_score_impact", b -> b.field("positive_score_impact", false));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -59,6 +59,11 @@ public class RankFeaturesFieldMapperTests extends FieldMapperTestCase2<RankFeatu
|
|||
b.field("type", "rank_features");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) {
|
||||
// no parameters to configure
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsMeta() {
|
||||
return false;
|
||||
|
|
|
@ -56,6 +56,25 @@ public class ScaledFloatFieldMapperTests extends MapperTestCase {
|
|||
b.field("type", "scaled_float").field("scaling_factor", 10.0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerConflictCheck(
|
||||
"scaling_factor",
|
||||
fieldMapping(this::minimalMapping),
|
||||
fieldMapping(b -> {
|
||||
b.field("type", "scaled_float");
|
||||
b.field("scaling_factor", 5.0);
|
||||
}));
|
||||
checker.registerConflictCheck("doc_values", b -> b.field("doc_values", false));
|
||||
checker.registerConflictCheck("index", b -> b.field("index", false));
|
||||
checker.registerConflictCheck("store", b -> b.field("store", true));
|
||||
checker.registerConflictCheck("null_value", b -> b.field("null_value", 1));
|
||||
checker.registerUpdateCheck(b -> b.field("coerce", false),
|
||||
m -> assertFalse(((ScaledFloatFieldMapper) m).coerce()));
|
||||
checker.registerUpdateCheck(b -> b.field("ignore_malformed", true),
|
||||
m -> assertTrue(((ScaledFloatFieldMapper) m).ignoreMalformed()));
|
||||
}
|
||||
|
||||
public void testExistsQueryDocValuesDisabled() throws IOException {
|
||||
MapperService mapperService = createMapperService(fieldMapping(b -> {
|
||||
minimalMapping(b);
|
||||
|
|
|
@ -34,8 +34,6 @@ import org.apache.lucene.search.MultiPhraseQuery;
|
|||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.SynonymQuery;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.search.similarities.BM25Similarity;
|
||||
import org.apache.lucene.search.similarities.BooleanSimilarity;
|
||||
import org.apache.lucene.search.spans.FieldMaskingSpanQuery;
|
||||
import org.apache.lucene.search.spans.SpanNearQuery;
|
||||
import org.apache.lucene.search.spans.SpanTermQuery;
|
||||
|
@ -55,9 +53,7 @@ import org.elasticsearch.index.query.MatchPhrasePrefixQueryBuilder;
|
|||
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
|
||||
import org.elasticsearch.index.query.MultiMatchQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryShardContext;
|
||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -80,20 +76,53 @@ import static org.hamcrest.core.IsInstanceOf.instanceOf;
|
|||
public class SearchAsYouTypeFieldMapperTests extends FieldMapperTestCase2<SearchAsYouTypeFieldMapper.Builder> {
|
||||
|
||||
@Override
|
||||
protected void writeFieldValue(XContentBuilder builder) throws IOException {
|
||||
builder.value("new york city");
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerConflictCheck("max_shingle_size", b -> b.field("max_shingle_size", 4));
|
||||
checker.registerConflictCheck("similarity", b -> b.field("similarity", "boolean"));
|
||||
checker.registerConflictCheck("index", b -> b.field("index", false));
|
||||
checker.registerConflictCheck("store", b -> b.field("store", true));
|
||||
checker.registerConflictCheck("analyzer", b -> b.field("analyzer", "keyword"));
|
||||
checker.registerConflictCheck("index_options", b -> b.field("index_options", "docs"));
|
||||
checker.registerConflictCheck("term_vector", b -> b.field("term_vector", "yes"));
|
||||
|
||||
// norms can be set from true to false, but not vice versa
|
||||
checker.registerConflictCheck("norms",
|
||||
fieldMapping(b -> {
|
||||
b.field("type", "text");
|
||||
b.field("norms", false);
|
||||
}),
|
||||
fieldMapping(b -> {
|
||||
b.field("type", "text");
|
||||
b.field("norms", true);
|
||||
}));
|
||||
checker.registerUpdateCheck(
|
||||
b -> {
|
||||
b.field("type", "search_as_you_type");
|
||||
b.field("norms", true);
|
||||
},
|
||||
b -> {
|
||||
b.field("type", "search_as_you_type");
|
||||
b.field("norms", false);
|
||||
},
|
||||
m -> assertFalse(m.fieldType().getTextSearchInfo().hasNorms())
|
||||
);
|
||||
|
||||
checker.registerUpdateCheck(b -> {
|
||||
b.field("analyzer", "default");
|
||||
b.field("search_analyzer", "keyword");
|
||||
},
|
||||
m -> assertEquals("keyword", m.fieldType().getTextSearchInfo().getSearchAnalyzer().name()));
|
||||
checker.registerUpdateCheck(b -> {
|
||||
b.field("analyzer", "default");
|
||||
b.field("search_analyzer", "keyword");
|
||||
b.field("search_quote_analyzer", "keyword");
|
||||
},
|
||||
m -> assertEquals("keyword", m.fieldType().getTextSearchInfo().getSearchQuoteAnalyzer().name()));
|
||||
|
||||
}
|
||||
|
||||
@Before
|
||||
public void addModifiers() {
|
||||
addModifier("max_shingle_size", false, (a, b) -> {
|
||||
a.maxShingleSize(3);
|
||||
b.maxShingleSize(2);
|
||||
});
|
||||
addModifier("similarity", false, (a, b) -> {
|
||||
a.similarity(new SimilarityProvider("BM25", new BM25Similarity()));
|
||||
b.similarity(new SimilarityProvider("boolean", new BooleanSimilarity()));
|
||||
});
|
||||
protected void writeFieldValue(XContentBuilder builder) throws IOException {
|
||||
builder.value("new york city");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -578,51 +578,51 @@ public class ICUCollationKeywordFieldMapper extends FieldMapper {
|
|||
conflicts.add("mapper [" + name() + "] has different [collator]");
|
||||
}
|
||||
if (!Objects.equals(rules, icuMergeWith.rules)) {
|
||||
conflicts.add("Cannot update rules setting for [" + CONTENT_TYPE + "]");
|
||||
conflicts.add("Cannot update parameter [rules] for [" + CONTENT_TYPE + "]");
|
||||
}
|
||||
|
||||
if (!Objects.equals(language, icuMergeWith.language)) {
|
||||
conflicts.add("Cannot update language setting for [" + CONTENT_TYPE + "]");
|
||||
conflicts.add("Cannot update parameter [language] for [" + CONTENT_TYPE + "]");
|
||||
}
|
||||
|
||||
if (!Objects.equals(country, icuMergeWith.country)) {
|
||||
conflicts.add("Cannot update country setting for [" + CONTENT_TYPE + "]");
|
||||
conflicts.add("Cannot update parameter [country] for [" + CONTENT_TYPE + "]");
|
||||
}
|
||||
|
||||
if (!Objects.equals(variant, icuMergeWith.variant)) {
|
||||
conflicts.add("Cannot update variant setting for [" + CONTENT_TYPE + "]");
|
||||
conflicts.add("Cannot update parameter [variant] for [" + CONTENT_TYPE + "]");
|
||||
}
|
||||
|
||||
if (!Objects.equals(strength, icuMergeWith.strength)) {
|
||||
conflicts.add("Cannot update strength setting for [" + CONTENT_TYPE + "]");
|
||||
conflicts.add("Cannot update parameter [strength] for [" + CONTENT_TYPE + "]");
|
||||
}
|
||||
|
||||
if (!Objects.equals(decomposition, icuMergeWith.decomposition)) {
|
||||
conflicts.add("Cannot update decomposition setting for [" + CONTENT_TYPE + "]");
|
||||
conflicts.add("Cannot update parameter [decomposition] for [" + CONTENT_TYPE + "]");
|
||||
}
|
||||
|
||||
if (!Objects.equals(alternate, icuMergeWith.alternate)) {
|
||||
conflicts.add("Cannot update alternate setting for [" + CONTENT_TYPE + "]");
|
||||
conflicts.add("Cannot update parameter [alternate] for [" + CONTENT_TYPE + "]");
|
||||
}
|
||||
|
||||
if (caseLevel != icuMergeWith.caseLevel) {
|
||||
conflicts.add("Cannot update case_level setting for [" + CONTENT_TYPE + "]");
|
||||
conflicts.add("Cannot update parameter [case_level] for [" + CONTENT_TYPE + "]");
|
||||
}
|
||||
|
||||
if (!Objects.equals(caseFirst, icuMergeWith.caseFirst)) {
|
||||
conflicts.add("Cannot update case_first setting for [" + CONTENT_TYPE + "]");
|
||||
conflicts.add("Cannot update parameter [case_first] for [" + CONTENT_TYPE + "]");
|
||||
}
|
||||
|
||||
if (numeric != icuMergeWith.numeric) {
|
||||
conflicts.add("Cannot update numeric setting for [" + CONTENT_TYPE + "]");
|
||||
conflicts.add("Cannot update parameter [numeric] for [" + CONTENT_TYPE + "]");
|
||||
}
|
||||
|
||||
if (!Objects.equals(variableTop, icuMergeWith.variableTop)) {
|
||||
conflicts.add("Cannot update variable_top setting for [" + CONTENT_TYPE + "]");
|
||||
conflicts.add("Cannot update parameter [variable_top] for [" + CONTENT_TYPE + "]");
|
||||
}
|
||||
|
||||
if (hiraganaQuaternaryMode != icuMergeWith.hiraganaQuaternaryMode) {
|
||||
conflicts.add("Cannot update hiragana_quaternary_mode setting for [" + CONTENT_TYPE + "]");
|
||||
conflicts.add("Cannot update parameter [hiragana_quaternary_mode] for [" + CONTENT_TYPE + "]");
|
||||
}
|
||||
|
||||
this.ignoreAbove = icuMergeWith.ignoreAbove;
|
||||
|
|
|
@ -34,7 +34,6 @@ import org.elasticsearch.common.settings.Settings;
|
|||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.plugin.analysis.icu.AnalysisICUPlugin;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
@ -63,31 +62,16 @@ public class ICUCollationKeywordFieldMapperTests extends FieldMapperTestCase2<IC
|
|||
return org.elasticsearch.common.collect.Set.of("analyzer", "similarity");
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
addModifier("strength", false, (a, b) -> {
|
||||
a.strength("primary");
|
||||
b.strength("secondary");
|
||||
});
|
||||
addModifier("decomposition", false, (a, b) -> {
|
||||
a.decomposition("no");
|
||||
b.decomposition("canonical");
|
||||
});
|
||||
addModifier("alternate", false, (a, b) -> {
|
||||
a.alternate("shifted");
|
||||
b.alternate("non-ignorable");
|
||||
});
|
||||
addBooleanModifier("case_level", false, ICUCollationKeywordFieldMapper.Builder::caseLevel);
|
||||
addModifier("case_first", false, (a, b) -> {
|
||||
a.caseFirst("upper");
|
||||
a.caseFirst("lower");
|
||||
});
|
||||
addBooleanModifier("numeric", false, ICUCollationKeywordFieldMapper.Builder::numeric);
|
||||
addModifier("variable_top", false, (a, b) -> {
|
||||
a.variableTop(";");
|
||||
b.variableTop(":");
|
||||
});
|
||||
addBooleanModifier("hiragana_quaternary_mode", false, ICUCollationKeywordFieldMapper.Builder::hiraganaQuaternaryMode);
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerConflictCheck("strength", b -> b.field("strength", "secondary"));
|
||||
checker.registerConflictCheck("decomposition", b -> b.field("decomposition", "canonical"));
|
||||
checker.registerConflictCheck("alternate", b -> b.field("alternate", "non-ignorable"));
|
||||
checker.registerConflictCheck("case_level", b -> b.field("case_level", true));
|
||||
checker.registerConflictCheck("case_first", b -> b.field("case_first", "lower"));
|
||||
checker.registerConflictCheck("numeric", b -> b.field("numeric", true));
|
||||
checker.registerConflictCheck("variable_top", b -> b.field("variable_top", ":"));
|
||||
checker.registerConflictCheck("hiragana_quaternary_mode", b -> b.field("hiragana_quaternary_mode", true));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -59,6 +59,11 @@ public class Murmur3FieldMapperTests extends FieldMapperTestCase2<Murmur3FieldMa
|
|||
b.field("type", "murmur3");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) {
|
||||
// no parameters to configure
|
||||
}
|
||||
|
||||
public void testDefaults() throws Exception {
|
||||
DocumentMapper mapper = createDocumentMapper(fieldMapping(this::minimalMapping));
|
||||
ParsedDocument parsedDoc = mapper.parse(source(b -> b.field("field", "value")));
|
||||
|
|
|
@ -134,6 +134,7 @@ public abstract class AbstractPointGeometryFieldMapper<Parsed, Processed> extend
|
|||
|
||||
@Override
|
||||
protected void mergeOptions(FieldMapper other, List<String> conflicts) {
|
||||
super.mergeOptions(other, conflicts);
|
||||
AbstractPointGeometryFieldMapper gpfm = (AbstractPointGeometryFieldMapper)other;
|
||||
// TODO make this un-updateable
|
||||
if (gpfm.nullValue != null) {
|
||||
|
|
|
@ -188,6 +188,7 @@ public abstract class AbstractShapeGeometryFieldMapper<Parsed, Processed> extend
|
|||
|
||||
@Override
|
||||
protected final void mergeOptions(FieldMapper other, List<String> conflicts) {
|
||||
super.mergeOptions(other, conflicts);
|
||||
AbstractShapeGeometryFieldMapper gsfm = (AbstractShapeGeometryFieldMapper)other;
|
||||
if (gsfm.coerce.explicit()) {
|
||||
this.coerce = gsfm.coerce;
|
||||
|
|
|
@ -137,7 +137,7 @@ public class CompletionFieldMapper extends ParametrizedFieldMapper {
|
|||
b.startArray(n);
|
||||
c.toXContent(b, ToXContent.EMPTY_PARAMS);
|
||||
b.endArray();
|
||||
}, ContextMappings::toString);
|
||||
}, Objects::toString);
|
||||
private final Parameter<Integer> maxInputLength = Parameter.intParam("max_input_length", true,
|
||||
m -> toType(m).maxInputLength, Defaults.DEFAULT_MAX_INPUT_LENGTH)
|
||||
.addDeprecatedName("max_input_len")
|
||||
|
@ -351,6 +351,10 @@ public class CompletionFieldMapper extends ParametrizedFieldMapper {
|
|||
return true;
|
||||
}
|
||||
|
||||
int getMaxInputLength() {
|
||||
return maxInputLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and indexes inputs
|
||||
*
|
||||
|
|
|
@ -400,7 +400,7 @@ public abstract class FieldMapper extends Mapper implements Cloneable {
|
|||
conflicts.add("mapper [" + name() + "] has different [norms] values, cannot change from disable to enabled");
|
||||
}
|
||||
if (fieldType.storeTermVectors() != other.storeTermVectors()) {
|
||||
conflicts.add("mapper [" + name() + "] has different [store_term_vector] values");
|
||||
conflicts.add("mapper [" + name() + "] has different [term_vector] values");
|
||||
}
|
||||
if (fieldType.storeTermVectorOffsets() != other.storeTermVectorOffsets()) {
|
||||
conflicts.add("mapper [" + name() + "] has different [store_term_vector_offsets] values");
|
||||
|
|
|
@ -345,6 +345,10 @@ public class IpFieldMapper extends ParametrizedFieldMapper {
|
|||
this.indexCreatedVersion = builder.indexCreatedVersion;
|
||||
}
|
||||
|
||||
boolean ignoreMalformed() {
|
||||
return ignoreMalformed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IpFieldType fieldType() {
|
||||
return (IpFieldType) super.fieldType();
|
||||
|
|
|
@ -92,7 +92,8 @@ public final class KeywordFieldMapper extends ParametrizedFieldMapper {
|
|||
private final Parameter<String> indexOptions
|
||||
= Parameter.restrictedStringParam("index_options", false, m -> toType(m).indexOptions, "docs", "freqs");
|
||||
private final Parameter<Boolean> hasNorms
|
||||
= Parameter.boolParam("norms", false, m -> toType(m).fieldType.omitNorms() == false, false);
|
||||
= Parameter.boolParam("norms", true, m -> toType(m).fieldType.omitNorms() == false, false)
|
||||
.setMergeValidator((o, n) -> o == n || (o && n == false)); // norms can be updated from 'true' to 'false' but not vv
|
||||
private final Parameter<SimilarityProvider> similarity = new Parameter<>("similarity", false, () -> null,
|
||||
(n, c, o) -> TypeParsers.resolveSimilarity(c, n, o), m -> toType(m).similarity)
|
||||
.setSerializer((b, f, v) -> b.field(f, v == null ? null : v.name()), v -> v == null ? null : v.name())
|
||||
|
|
|
@ -1014,6 +1014,14 @@ public class NumberFieldMapper extends ParametrizedFieldMapper {
|
|||
this.coerceByDefault = builder.coerce.getDefaultValue().value();
|
||||
}
|
||||
|
||||
boolean coerce() {
|
||||
return coerce.value();
|
||||
}
|
||||
|
||||
boolean ignoreMalformed() {
|
||||
return ignoreMalformed.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NumberFieldType fieldType() {
|
||||
return (NumberFieldType) super.fieldType();
|
||||
|
|
|
@ -144,7 +144,6 @@ public abstract class ParametrizedFieldMapper extends FieldMapper {
|
|||
private final Supplier<T> defaultValue;
|
||||
private final TriFunction<String, ParserContext, Object, T> parser;
|
||||
private final Function<FieldMapper, T> initializer;
|
||||
private final boolean updateable;
|
||||
private boolean acceptsNull = false;
|
||||
private Consumer<T> validator = null;
|
||||
private Serializer<T> serializer = XContentBuilder::field;
|
||||
|
@ -169,7 +168,6 @@ public abstract class ParametrizedFieldMapper extends FieldMapper {
|
|||
this.value = null;
|
||||
this.parser = parser;
|
||||
this.initializer = initializer;
|
||||
this.updateable = updateable;
|
||||
this.mergeValidator = (previous, toMerge) -> updateable || Objects.equals(previous, toMerge);
|
||||
}
|
||||
|
||||
|
|
|
@ -274,6 +274,10 @@ public class RangeFieldMapper extends ParametrizedFieldMapper {
|
|||
this.coerceByDefault = builder.coerce.getDefaultValue().value();
|
||||
}
|
||||
|
||||
boolean coerce() {
|
||||
return coerce.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParametrizedFieldMapper.Builder getMergeBuilder() {
|
||||
return new Builder(simpleName(), type, coerceByDefault).init(this);
|
||||
|
|
|
@ -47,6 +47,12 @@ public class BinaryFieldMapperTests extends MapperTestCase {
|
|||
b.field("type", "binary");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerConflictCheck("doc_values", b -> b.field("doc_values", true));
|
||||
checker.registerConflictCheck("store", b -> b.field("store", true));
|
||||
}
|
||||
|
||||
public void testExistsQueryDocValuesEnabled() throws IOException {
|
||||
MapperService mapperService = createMapperService(fieldMapping(b -> {
|
||||
minimalMapping(b);
|
||||
|
|
|
@ -58,6 +58,14 @@ public class BooleanFieldMapperTests extends MapperTestCase {
|
|||
assertWarnings("Parameter [boost] on field [field] is deprecated and will be removed in 8.0");
|
||||
}
|
||||
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerConflictCheck("doc_values", b -> b.field("doc_values", false));
|
||||
checker.registerConflictCheck("index", b -> b.field("index", false));
|
||||
checker.registerConflictCheck("store", b -> b.field("store", true));
|
||||
checker.registerConflictCheck("null_value", b -> b.field("null_value", true));
|
||||
checker.registerUpdateCheck(b -> b.field("boost", 2.0), m -> assertEquals(m.fieldType().boost(), 2.0, 0));
|
||||
}
|
||||
|
||||
public void testExistsQueryDocValuesDisabled() throws IOException {
|
||||
MapperService mapperService = createMapperService(fieldMapping(b -> {
|
||||
minimalMapping(b);
|
||||
|
|
|
@ -87,6 +87,31 @@ public class CompletionFieldMapperTests extends MapperTestCase {
|
|||
b.field("max_input_length", 50);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerConflictCheck("analyzer", b -> b.field("analyzer", "standard"));
|
||||
checker.registerConflictCheck("preserve_separators", b -> b.field("preserve_separators", false));
|
||||
checker.registerConflictCheck("preserve_position_increments", b -> b.field("preserve_position_increments", false));
|
||||
checker.registerConflictCheck("contexts", b -> {
|
||||
b.startArray("contexts");
|
||||
{
|
||||
b.startObject();
|
||||
b.field("name", "place_type");
|
||||
b.field("type", "category");
|
||||
b.field("path", "cat");
|
||||
b.endObject();
|
||||
}
|
||||
b.endArray();
|
||||
});
|
||||
|
||||
checker.registerUpdateCheck(b -> b.field("search_analyzer", "standard"),
|
||||
m -> assertEquals("standard", m.fieldType().getTextSearchInfo().getSearchAnalyzer().name()));
|
||||
checker.registerUpdateCheck(b -> b.field("max_input_length", 30), m -> {
|
||||
CompletionFieldMapper cfm = (CompletionFieldMapper) m;
|
||||
assertEquals(30, cfm.getMaxInputLength());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IndexAnalyzers createIndexAnalyzers(IndexSettings indexSettings) {
|
||||
Map<String, NamedAnalyzer> analyzers = new HashMap<>();
|
||||
|
|
|
@ -54,6 +54,19 @@ public class DateFieldMapperTests extends MapperTestCase {
|
|||
b.field("type", "date");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerConflictCheck("doc_values", b -> b.field("doc_values", false));
|
||||
checker.registerConflictCheck("index", b -> b.field("index", false));
|
||||
checker.registerConflictCheck("store", b -> b.field("store", true));
|
||||
checker.registerConflictCheck("format", b -> b.field("format", "yyyy-MM-dd"));
|
||||
checker.registerConflictCheck("locale", b -> b.field("locale", "es"));
|
||||
checker.registerConflictCheck("null_value", b -> b.field("null_value", "34500000"));
|
||||
checker.registerUpdateCheck(b -> b.field("ignore_malformed", true),
|
||||
m -> assertTrue(((DateFieldMapper)m).getIgnoreMalformed()));
|
||||
checker.registerUpdateCheck(b -> b.field("boost", 2.0), m -> assertEquals(m.fieldType().boost(), 2.0, 0));
|
||||
}
|
||||
|
||||
public void testExistsQueryDocValuesDisabled() throws IOException {
|
||||
MapperService mapperService = createMapperService(fieldMapping(b -> {
|
||||
minimalMapping(b);
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.elasticsearch.Version;
|
|||
import org.elasticsearch.cluster.metadata.IndexMetadata;
|
||||
import org.elasticsearch.common.collect.List;
|
||||
import org.elasticsearch.common.geo.GeoPoint;
|
||||
import org.elasticsearch.common.geo.GeoUtils;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
|
@ -57,6 +58,23 @@ public class GeoPointFieldMapperTests extends FieldMapperTestCase2<GeoPointField
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerUpdateCheck(b -> b.field("ignore_malformed", true), m -> {
|
||||
GeoPointFieldMapper gpfm = (GeoPointFieldMapper) m;
|
||||
assertTrue(gpfm.ignoreMalformed.value());
|
||||
});
|
||||
checker.registerUpdateCheck(b -> b.field("ignore_z_value", false), m -> {
|
||||
GeoPointFieldMapper gpfm = (GeoPointFieldMapper) m;
|
||||
assertFalse(gpfm.ignoreZValue.value());
|
||||
});
|
||||
GeoPoint point = GeoUtils.parseFromString("41.12,-71.34");
|
||||
// TODO this should not be updateable!
|
||||
checker.registerUpdateCheck(b -> b.field("null_value", "41.12,-71.34"), m -> {
|
||||
GeoPointFieldMapper gpfm = (GeoPointFieldMapper) m;
|
||||
assertEquals(gpfm.nullValue, point);
|
||||
});
|
||||
}
|
||||
|
||||
protected void writeFieldValue(XContentBuilder builder) throws IOException {
|
||||
builder.value(stringEncode(1.3, 1.2));
|
||||
}
|
||||
|
|
|
@ -54,6 +54,26 @@ public class GeoShapeFieldMapperTests extends FieldMapperTestCase2<GeoShapeField
|
|||
return new GeoShapeFieldMapper.Builder("geoshape");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerUpdateCheck(b -> b.field("orientation", "right"), m -> {
|
||||
GeoShapeFieldMapper gsfm = (GeoShapeFieldMapper) m;
|
||||
assertEquals(ShapeBuilder.Orientation.RIGHT, gsfm.orientation());
|
||||
});
|
||||
checker.registerUpdateCheck(b -> b.field("ignore_malformed", true), m -> {
|
||||
GeoShapeFieldMapper gpfm = (GeoShapeFieldMapper) m;
|
||||
assertTrue(gpfm.ignoreMalformed.value());
|
||||
});
|
||||
checker.registerUpdateCheck(b -> b.field("ignore_z_value", false), m -> {
|
||||
GeoShapeFieldMapper gpfm = (GeoShapeFieldMapper) m;
|
||||
assertFalse(gpfm.ignoreZValue.value());
|
||||
});
|
||||
checker.registerUpdateCheck(b -> b.field("coerce", true), m -> {
|
||||
GeoShapeFieldMapper gpfm = (GeoShapeFieldMapper) m;
|
||||
assertTrue(gpfm.coerce.value());
|
||||
});
|
||||
}
|
||||
|
||||
@Before
|
||||
public void addModifiers() {
|
||||
addModifier("orientation", true, (a, b) -> {
|
||||
|
|
|
@ -51,6 +51,16 @@ public class IpFieldMapperTests extends MapperTestCase {
|
|||
b.field("type", "ip");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerConflictCheck("doc_values", b -> b.field("doc_values", false));
|
||||
checker.registerConflictCheck("index", b -> b.field("index", false));
|
||||
checker.registerConflictCheck("store", b -> b.field("store", true));
|
||||
checker.registerConflictCheck("null_value", b -> b.field("null_value", "::1"));
|
||||
checker.registerUpdateCheck(b -> b.field("ignore_malformed", false),
|
||||
m -> assertFalse(((IpFieldMapper) m).ignoreMalformed()));
|
||||
}
|
||||
|
||||
public void testExistsQueryDocValuesDisabled() throws IOException {
|
||||
MapperService mapperService = createMapperService(fieldMapping(b -> {
|
||||
minimalMapping(b);
|
||||
|
|
|
@ -164,6 +164,39 @@ public class KeywordFieldMapperTests extends MapperTestCase {
|
|||
assertWarnings("Parameter [boost] on field [field] is deprecated and will be removed in 8.0");
|
||||
}
|
||||
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerConflictCheck("doc_values", b -> b.field("doc_values", false));
|
||||
checker.registerConflictCheck("index", b -> b.field("index", false));
|
||||
checker.registerConflictCheck("store", b -> b.field("store", true));
|
||||
checker.registerConflictCheck("index_options", b -> b.field("index_options", "freqs"));
|
||||
checker.registerConflictCheck("null_value", b -> b.field("null_value", "foo"));
|
||||
checker.registerConflictCheck("similarity", b -> b.field("similarity", "boolean"));
|
||||
checker.registerConflictCheck("normalizer", b -> b.field("normalizer", "lowercase"));
|
||||
|
||||
checker.registerUpdateCheck(b -> b.field("eager_global_ordinals", true),
|
||||
m -> assertTrue(m.fieldType().eagerGlobalOrdinals()));
|
||||
checker.registerUpdateCheck(b -> b.field("ignore_above", 256),
|
||||
m -> assertEquals(256, ((KeywordFieldMapper)m).ignoreAbove()));
|
||||
checker.registerUpdateCheck(b -> b.field("split_queries_on_whitespace", true),
|
||||
m -> assertEquals("_whitespace", m.fieldType().getTextSearchInfo().getSearchAnalyzer().name()));
|
||||
|
||||
// norms can be set from true to false, but not vice versa
|
||||
checker.registerConflictCheck("norms", b -> b.field("norms", true));
|
||||
checker.registerUpdateCheck(
|
||||
b -> {
|
||||
b.field("type", "keyword");
|
||||
b.field("norms", true);
|
||||
},
|
||||
b -> {
|
||||
b.field("type", "keyword");
|
||||
b.field("norms", false);
|
||||
},
|
||||
m -> assertFalse(m.fieldType().getTextSearchInfo().hasNorms())
|
||||
);
|
||||
|
||||
checker.registerUpdateCheck(b -> b.field("boost", 2.0), m -> assertEquals(m.fieldType().boost(), 2.0, 0));
|
||||
}
|
||||
|
||||
public void testDefaults() throws Exception {
|
||||
XContentBuilder mapping = fieldMapping(this::minimalMapping);
|
||||
DocumentMapper mapper = createDocumentMapper(mapping);
|
||||
|
|
|
@ -40,7 +40,6 @@ import org.elasticsearch.geometry.Point;
|
|||
import org.elasticsearch.index.query.QueryShardContext;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.test.TestGeoShapeFieldMapperPlugin;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
@ -56,6 +55,7 @@ import static org.hamcrest.Matchers.not;
|
|||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class LegacyGeoShapeFieldMapperTests extends FieldMapperTestCase2<LegacyGeoShapeFieldMapper.Builder> {
|
||||
|
||||
@Override
|
||||
|
@ -73,32 +73,42 @@ public class LegacyGeoShapeFieldMapperTests extends FieldMapperTestCase2<LegacyG
|
|||
return org.elasticsearch.common.collect.Set.of("analyzer", "similarity", "doc_values", "store");
|
||||
}
|
||||
|
||||
@Before
|
||||
public void addModifiers() {
|
||||
addModifier("tree", false, (a, b) -> {
|
||||
a.deprecatedParameters.tree = "geohash";
|
||||
b.deprecatedParameters.tree = "quadtree";
|
||||
@Override
|
||||
protected void minimalMapping(XContentBuilder b) throws IOException {
|
||||
b.field("type", "geo_shape").field("strategy", "recursive");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
|
||||
checker.registerConflictCheck("strategy",
|
||||
fieldMapping(this::minimalMapping),
|
||||
fieldMapping(b -> {
|
||||
b.field("type", "geo_shape");
|
||||
b.field("strategy", "term");
|
||||
}));
|
||||
|
||||
checker.registerConflictCheck("tree", b -> b.field("tree", "geohash"));
|
||||
checker.registerConflictCheck("tree_levels", b -> b.field("tree_levels", 5));
|
||||
checker.registerConflictCheck("precision", b -> b.field("precision", 10));
|
||||
checker.registerUpdateCheck(b -> b.field("orientation", "right"), m -> {
|
||||
LegacyGeoShapeFieldMapper gsfm = (LegacyGeoShapeFieldMapper) m;
|
||||
assertEquals(ShapeBuilder.Orientation.RIGHT, gsfm.orientation());
|
||||
});
|
||||
addModifier("strategy", false, (a, b) -> {
|
||||
a.deprecatedParameters.strategy = SpatialStrategy.TERM;
|
||||
b.deprecatedParameters.strategy = SpatialStrategy.RECURSIVE;
|
||||
checker.registerUpdateCheck(b -> b.field("ignore_malformed", true), m -> {
|
||||
LegacyGeoShapeFieldMapper gpfm = (LegacyGeoShapeFieldMapper) m;
|
||||
assertTrue(gpfm.ignoreMalformed.value());
|
||||
});
|
||||
addModifier("tree_levels", false, (a, b) -> {
|
||||
a.deprecatedParameters.treeLevels = 2;
|
||||
b.deprecatedParameters.treeLevels = 3;
|
||||
checker.registerUpdateCheck(b -> b.field("ignore_z_value", false), m -> {
|
||||
LegacyGeoShapeFieldMapper gpfm = (LegacyGeoShapeFieldMapper) m;
|
||||
assertFalse(gpfm.ignoreZValue.value());
|
||||
});
|
||||
addModifier("precision", false, (a, b) -> {
|
||||
a.deprecatedParameters.precision = "10";
|
||||
b.deprecatedParameters.precision = "20";
|
||||
});
|
||||
addModifier("distance_error_pct", true, (a, b) -> {
|
||||
a.deprecatedParameters.distanceErrorPct = 0.5;
|
||||
b.deprecatedParameters.distanceErrorPct = 0.6;
|
||||
});
|
||||
addModifier("orientation", true, (a, b) -> {
|
||||
a.orientation = ShapeBuilder.Orientation.RIGHT;
|
||||
b.orientation = ShapeBuilder.Orientation.LEFT;
|
||||
checker.registerUpdateCheck(b -> b.field("coerce", true), m -> {
|
||||
LegacyGeoShapeFieldMapper gpfm = (LegacyGeoShapeFieldMapper) m;
|
||||
assertTrue(gpfm.coerce.value());
|
||||
});
|
||||
// TODO - distance_error_pct ends up being subsumed into a calculated value, how to test
|
||||
checker.registerUpdateCheck(b -> b.field("distance_error_pct", 0.8), m -> {});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -106,11 +116,6 @@ public class LegacyGeoShapeFieldMapperTests extends FieldMapperTestCase2<LegacyG
|
|||
return List.of(new TestGeoShapeFieldMapperPlugin());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void minimalMapping(XContentBuilder b) throws IOException {
|
||||
b.field("type", "geo_shape").field("strategy", "recursive");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsMeta() {
|
||||
return false;
|
||||
|
@ -601,7 +606,7 @@ public class LegacyGeoShapeFieldMapperTests extends FieldMapperTestCase2<LegacyG
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void assertSerializationWarnings() {
|
||||
protected void assertParseMaximalWarnings() {
|
||||
assertWarnings("Field parameter [strategy] is deprecated and will be removed in a future version.",
|
||||
"Field parameter [tree] is deprecated and will be removed in a future version.",
|
||||
"Field parameter [tree_levels] is deprecated and will be removed in a future version.",
|
||||
|
@ -610,6 +615,11 @@ public class LegacyGeoShapeFieldMapperTests extends FieldMapperTestCase2<LegacyG
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void assertSerializationWarnings() {
|
||||
assertParseMinimalWarnings();
|
||||
}
|
||||
|
||||
public void testGeoShapeArrayParsing() throws Exception {
|
||||
DocumentMapper mapper = createDocumentMapper(fieldMapping(b -> b.field("type", "geo_shape").field("tree", "quadtree")));
|
||||
ParsedDocument document = mapper.parse(source(b -> {
|
||||
|
|
|
@ -59,6 +59,17 @@ public class NumberFieldMapperTests extends AbstractNumericFieldMapperTestCase {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerConflictCheck("doc_values", b -> b.field("doc_values", false));
|
||||
checker.registerConflictCheck("index", b -> b.field("index", false));
|
||||
checker.registerConflictCheck("store", b -> b.field("store", true));
|
||||
checker.registerConflictCheck("null_value", b -> b.field("null_value", 1));
|
||||
checker.registerUpdateCheck(b -> b.field("coerce", false),
|
||||
m -> assertFalse(((NumberFieldMapper) m).coerce()));
|
||||
checker.registerUpdateCheck(b -> b.field("ignore_malformed", true),
|
||||
m -> assertTrue(((NumberFieldMapper) m).ignoreMalformed()));
|
||||
}
|
||||
|
||||
protected void writeFieldValue(XContentBuilder builder) throws IOException {
|
||||
builder.value(123);
|
||||
}
|
||||
|
|
|
@ -99,6 +99,15 @@ public class RangeFieldMapperTests extends AbstractNumericFieldMapperTestCase {
|
|||
assertWarnings("Parameter [boost] on field [field] is deprecated and will be removed in 8.0");
|
||||
}
|
||||
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerConflictCheck("doc_values", b -> b.field("doc_values", false));
|
||||
checker.registerConflictCheck("index", b -> b.field("index", false));
|
||||
checker.registerConflictCheck("store", b -> b.field("store", true));
|
||||
checker.registerUpdateCheck(b -> b.field("coerce", false),
|
||||
m -> assertFalse(((RangeFieldMapper)m).coerce()));
|
||||
checker.registerUpdateCheck(b -> b.field("boost", 2.0), m -> assertEquals(m.fieldType().boost(), 2.0, 0));
|
||||
}
|
||||
|
||||
private Object getFrom(String type) {
|
||||
if (type.equals("date_range")) {
|
||||
return FROM_DATE;
|
||||
|
|
|
@ -45,8 +45,6 @@ import org.apache.lucene.search.PhraseQuery;
|
|||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.SynonymQuery;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.search.similarities.BM25Similarity;
|
||||
import org.apache.lucene.search.similarities.BooleanSimilarity;
|
||||
import org.apache.lucene.search.spans.FieldMaskingSpanQuery;
|
||||
import org.apache.lucene.search.spans.SpanNearQuery;
|
||||
import org.apache.lucene.search.spans.SpanOrQuery;
|
||||
|
@ -73,8 +71,6 @@ import org.elasticsearch.index.query.MatchPhrasePrefixQueryBuilder;
|
|||
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
|
||||
import org.elasticsearch.index.query.QueryShardContext;
|
||||
import org.elasticsearch.index.search.MatchQuery;
|
||||
import org.elasticsearch.index.similarity.SimilarityProvider;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
@ -132,36 +128,76 @@ public class TextFieldMapperTests extends FieldMapperTestCase2<TextFieldMapper.B
|
|||
.searchAnalyzer(new NamedAnalyzer("standard", AnalyzerScope.INDEX, new StandardAnalyzer()));
|
||||
}
|
||||
|
||||
@Before
|
||||
public void addModifiers() {
|
||||
addBooleanModifier("fielddata", true, TextFieldMapper.Builder::fielddata);
|
||||
addModifier("fielddata_frequency_filter.min", true, (a, b) -> {
|
||||
a.fielddataFrequencyFilter(1, 10, 10);
|
||||
a.fielddataFrequencyFilter(2, 10, 10);
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerUpdateCheck(b -> b.field("fielddata", true), m -> {
|
||||
TextFieldType ft = (TextFieldType) m.fieldType();
|
||||
assertTrue(ft.fielddata());
|
||||
});
|
||||
addModifier("fielddata_frequency_filter.max", true, (a, b) -> {
|
||||
a.fielddataFrequencyFilter(1, 10, 10);
|
||||
a.fielddataFrequencyFilter(1, 12, 10);
|
||||
});
|
||||
addModifier("fielddata_frequency_filter.min_segment_size", true, (a, b) -> {
|
||||
a.fielddataFrequencyFilter(1, 10, 10);
|
||||
a.fielddataFrequencyFilter(1, 10, 11);
|
||||
});
|
||||
addModifier("index_phrases", false, (a, b) -> {
|
||||
a.indexPhrases(true);
|
||||
b.indexPhrases(false);
|
||||
});
|
||||
addModifier("index_prefixes", false, (a, b) -> {
|
||||
a.indexPrefixes(2, 4);
|
||||
});
|
||||
addModifier("index_options", false, (a, b) -> {
|
||||
a.indexOptions(IndexOptions.DOCS_AND_FREQS);
|
||||
b.indexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS);
|
||||
});
|
||||
addModifier("similarity", false, (a, b) -> {
|
||||
a.similarity(new SimilarityProvider("BM25", new BM25Similarity()));
|
||||
b.similarity(new SimilarityProvider("boolean", new BooleanSimilarity()));
|
||||
checker.registerUpdateCheck(b -> {
|
||||
b.field("fielddata", true);
|
||||
b.startObject("fielddata_frequency_filter");
|
||||
{
|
||||
b.field("min", 10);
|
||||
b.field("max", 20);
|
||||
b.field("min_segment_size", 100);
|
||||
}
|
||||
b.endObject();
|
||||
}, m -> {
|
||||
TextFieldType ft = (TextFieldType) m.fieldType();
|
||||
assertEquals(10, ft.fielddataMinFrequency(), 0);
|
||||
assertEquals(20, ft.fielddataMaxFrequency(), 0);
|
||||
assertEquals(100, ft.fielddataMinSegmentSize());
|
||||
});
|
||||
checker.registerUpdateCheck(b -> b.field("eager_global_ordinals", "true"),
|
||||
m -> assertTrue(m.fieldType().eagerGlobalOrdinals()));
|
||||
checker.registerUpdateCheck(b -> {
|
||||
b.field("analyzer", "default");
|
||||
b.field("search_analyzer", "keyword");
|
||||
},
|
||||
m -> assertEquals("keyword", m.fieldType().getTextSearchInfo().getSearchAnalyzer().name()));
|
||||
checker.registerUpdateCheck(b -> {
|
||||
b.field("analyzer", "default");
|
||||
b.field("search_analyzer", "keyword");
|
||||
b.field("search_quote_analyzer", "keyword");
|
||||
},
|
||||
m -> assertEquals("keyword", m.fieldType().getTextSearchInfo().getSearchQuoteAnalyzer().name()));
|
||||
|
||||
|
||||
checker.registerConflictCheck("index", b -> b.field("index", false));
|
||||
checker.registerConflictCheck("store", b -> b.field("store", true));
|
||||
checker.registerConflictCheck("index_phrases", b -> b.field("index_phrases", true));
|
||||
checker.registerConflictCheck("index_prefixes", b -> b.startObject("index_prefixes").endObject());
|
||||
checker.registerConflictCheck("index_options", b -> b.field("index_options", "docs"));
|
||||
checker.registerConflictCheck("similarity", b -> b.field("similarity", "boolean"));
|
||||
checker.registerConflictCheck("analyzer", b -> b.field("analyzer", "keyword"));
|
||||
checker.registerConflictCheck("term_vector", b -> b.field("term_vector", "yes"));
|
||||
|
||||
// TODO position_increment_gap should not be updateable!
|
||||
//checker.registerConflictCheck("position_increment_gap", b -> b.field("position_increment_gap", 10));
|
||||
|
||||
// norms can be set from true to false, but not vice versa
|
||||
checker.registerConflictCheck("norms",
|
||||
fieldMapping(b -> {
|
||||
b.field("type", "text");
|
||||
b.field("norms", false);
|
||||
}),
|
||||
fieldMapping(b -> {
|
||||
b.field("type", "text");
|
||||
b.field("norms", true);
|
||||
}));
|
||||
checker.registerUpdateCheck(
|
||||
b -> {
|
||||
b.field("type", "text");
|
||||
b.field("norms", true);
|
||||
},
|
||||
b -> {
|
||||
b.field("type", "text");
|
||||
b.field("norms", false);
|
||||
},
|
||||
m -> assertFalse(m.fieldType().getTextSearchInfo().hasNorms())
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.lucene.search.NormsFieldExistsQuery;
|
|||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.TermQuery;
|
||||
import org.apache.lucene.util.SetOnce;
|
||||
import org.elasticsearch.common.CheckedConsumer;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
|
@ -45,9 +46,13 @@ import org.elasticsearch.search.lookup.SearchLookup;
|
|||
import org.elasticsearch.search.lookup.SourceLookup;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.hamcrest.Matchers.anyOf;
|
||||
|
@ -100,7 +105,7 @@ public abstract class MapperTestCase extends MapperServiceTestCase {
|
|||
protected void assertExistsQuery(MappedFieldType fieldType, Query query, ParseContext.Document fields) {
|
||||
if (fieldType.hasDocValues()) {
|
||||
assertThat(query, instanceOf(DocValuesFieldExistsQuery.class));
|
||||
DocValuesFieldExistsQuery fieldExistsQuery = (DocValuesFieldExistsQuery)query;
|
||||
DocValuesFieldExistsQuery fieldExistsQuery = (DocValuesFieldExistsQuery) query;
|
||||
assertEquals("field", fieldExistsQuery.getField());
|
||||
assertDocValuesField(fields, "field");
|
||||
assertNoFieldNamesField(fields);
|
||||
|
@ -283,7 +288,9 @@ public abstract class MapperTestCase extends MapperServiceTestCase {
|
|||
throws IOException {
|
||||
|
||||
BiFunction<MappedFieldType, Supplier<SearchLookup>, IndexFieldData<?>> fieldDataLookup = (mft, lookupSource) -> mft
|
||||
.fielddataBuilder("test", () -> { throw new UnsupportedOperationException(); })
|
||||
.fielddataBuilder("test", () -> {
|
||||
throw new UnsupportedOperationException();
|
||||
})
|
||||
.build(new IndexFieldDataCache.None(), new NoneCircuitBreakerService(), mapperService);
|
||||
SetOnce<List<?>> result = new SetOnce<>();
|
||||
withLuceneIndex(mapperService, iw -> {
|
||||
|
@ -299,4 +306,127 @@ public abstract class MapperTestCase extends MapperServiceTestCase {
|
|||
});
|
||||
return result.get();
|
||||
}
|
||||
|
||||
private class UpdateCheck {
|
||||
final XContentBuilder init;
|
||||
final XContentBuilder update;
|
||||
final Consumer<FieldMapper> check;
|
||||
|
||||
private UpdateCheck(CheckedConsumer<XContentBuilder, IOException> update,
|
||||
Consumer<FieldMapper> check) throws IOException {
|
||||
this.init = fieldMapping(MapperTestCase.this::minimalMapping);
|
||||
this.update = fieldMapping(b -> {
|
||||
minimalMapping(b);
|
||||
update.accept(b);
|
||||
});
|
||||
this.check = check;
|
||||
}
|
||||
|
||||
private UpdateCheck(CheckedConsumer<XContentBuilder, IOException> init,
|
||||
CheckedConsumer<XContentBuilder, IOException> update,
|
||||
Consumer<FieldMapper> check) throws IOException {
|
||||
this.init = fieldMapping(init);
|
||||
this.update = fieldMapping(update);
|
||||
this.check = check;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConflictCheck {
|
||||
final XContentBuilder init;
|
||||
final XContentBuilder update;
|
||||
|
||||
private ConflictCheck(XContentBuilder init, XContentBuilder update) {
|
||||
this.init = init;
|
||||
this.update = update;
|
||||
}
|
||||
}
|
||||
|
||||
public class ParameterChecker {
|
||||
|
||||
List<UpdateCheck> updateChecks = new ArrayList<>();
|
||||
Map<String, ConflictCheck> conflictChecks = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Register a check that a parameter can be updated, using the minimal mapping as a base
|
||||
*
|
||||
* @param update a field builder applied on top of the minimal mapping
|
||||
* @param check a check that the updated parameter has been applied to the FieldMapper
|
||||
*/
|
||||
public void registerUpdateCheck(CheckedConsumer<XContentBuilder, IOException> update,
|
||||
Consumer<FieldMapper> check) throws IOException {
|
||||
updateChecks.add(new UpdateCheck(update, check));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a check that a parameter can be updated
|
||||
*
|
||||
* @param init the initial mapping
|
||||
* @param update the updated mapping
|
||||
* @param check a check that the updated parameter has been applied to the FieldMapper
|
||||
*/
|
||||
public void registerUpdateCheck(CheckedConsumer<XContentBuilder, IOException> init,
|
||||
CheckedConsumer<XContentBuilder, IOException> update,
|
||||
Consumer<FieldMapper> check) throws IOException {
|
||||
updateChecks.add(new UpdateCheck(init, update, check));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a check that a parameter update will cause a conflict, using the minimal mapping as a base
|
||||
*
|
||||
* @param param the parameter name, expected to appear in the error message
|
||||
* @param update a field builder applied on top of the minimal mapping
|
||||
*/
|
||||
public void registerConflictCheck(String param, CheckedConsumer<XContentBuilder, IOException> update) throws IOException {
|
||||
conflictChecks.put(param, new ConflictCheck(
|
||||
fieldMapping(MapperTestCase.this::minimalMapping),
|
||||
fieldMapping(b -> {
|
||||
minimalMapping(b);
|
||||
update.accept(b);
|
||||
})
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a check that a parameter update will cause a conflict
|
||||
*
|
||||
* @param param the parameter name, expected to appear in the error message
|
||||
* @param init the initial mapping
|
||||
* @param update the updated mapping
|
||||
*/
|
||||
public void registerConflictCheck(String param, XContentBuilder init, XContentBuilder update) {
|
||||
conflictChecks.put(param, new ConflictCheck(init, update));
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void registerParameters(ParameterChecker checker) throws IOException;
|
||||
|
||||
public void testUpdates() throws IOException {
|
||||
ParameterChecker checker = new ParameterChecker();
|
||||
registerParameters(checker);
|
||||
for (UpdateCheck updateCheck : checker.updateChecks) {
|
||||
MapperService mapperService = createMapperService(updateCheck.init);
|
||||
merge(mapperService, updateCheck.update);
|
||||
FieldMapper mapper = (FieldMapper) mapperService.documentMapper().mappers().getMapper("field");
|
||||
updateCheck.check.accept(mapper);
|
||||
// do it again to ensure that we don't get conflicts the second time
|
||||
merge(mapperService, updateCheck.update);
|
||||
mapper = (FieldMapper) mapperService.documentMapper().mappers().getMapper("field");
|
||||
updateCheck.check.accept(mapper);
|
||||
|
||||
}
|
||||
for (String param : checker.conflictChecks.keySet()) {
|
||||
MapperService mapperService = createMapperService(checker.conflictChecks.get(param).init);
|
||||
// merging the same change is fine
|
||||
merge(mapperService, checker.conflictChecks.get(param).init);
|
||||
// merging the conflicting update should throw an exception
|
||||
Exception e = expectThrows(IllegalArgumentException.class,
|
||||
"No conflict when updating parameter [" + param + "]",
|
||||
() -> merge(mapperService, checker.conflictChecks.get(param).update));
|
||||
assertThat(e.getMessage(), anyOf(
|
||||
containsString("Cannot update parameter [" + param + "]"),
|
||||
containsString("different [" + param + "]")));
|
||||
}
|
||||
assertParseMaximalWarnings();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -148,6 +148,10 @@ public class HistogramFieldMapper extends FieldMapper {
|
|||
this.ignoreMalformed = ignoreMalformed;
|
||||
}
|
||||
|
||||
boolean ignoreMalformed() {
|
||||
return ignoreMalformed.value();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mergeOptions(FieldMapper other, List<String> conflicts) {
|
||||
HistogramFieldMapper gpfmMergeWith = (HistogramFieldMapper) other;
|
||||
|
|
|
@ -51,6 +51,12 @@ public class HistogramFieldMapperTests extends FieldMapperTestCase2<HistogramFie
|
|||
b.field("type", "histogram");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerUpdateCheck(b -> b.field("ignore_malformed", true),
|
||||
m -> assertTrue(((HistogramFieldMapper)m).ignoreMalformed()));
|
||||
}
|
||||
|
||||
public void testParseValue() throws Exception {
|
||||
DocumentMapper mapper = createDocumentMapper(fieldMapping(this::minimalMapping));
|
||||
ParsedDocument doc = mapper.parse(
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.elasticsearch.index.mapper.ValueFetcher;
|
|||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.search.lookup.SourceLookup;
|
||||
import org.elasticsearch.xpack.constantkeyword.ConstantKeywordMapperPlugin;
|
||||
import org.elasticsearch.xpack.constantkeyword.mapper.ConstantKeywordFieldMapper.ConstantKeywordFieldType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
|
@ -120,8 +121,8 @@ public class ConstantKeywordFieldMapperTests extends MapperTestCase {
|
|||
b.field("type", "constant_keyword");
|
||||
b.field("value", 74);
|
||||
}));
|
||||
ConstantKeywordFieldMapper.ConstantKeywordFieldType ft
|
||||
= (ConstantKeywordFieldMapper.ConstantKeywordFieldType) mapperService.fieldType("field");
|
||||
ConstantKeywordFieldType ft
|
||||
= (ConstantKeywordFieldType) mapperService.fieldType("field");
|
||||
assertEquals("74", ft.value());
|
||||
}
|
||||
|
||||
|
@ -145,6 +146,23 @@ public class ConstantKeywordFieldMapperTests extends MapperTestCase {
|
|||
b.field("type", "constant_keyword");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
checker.registerUpdateCheck(b -> b.field("value", "foo"), m -> {
|
||||
ConstantKeywordFieldType ft = (ConstantKeywordFieldType) m.fieldType();
|
||||
assertEquals("foo", ft.value());
|
||||
});
|
||||
checker.registerConflictCheck("value",
|
||||
fieldMapping(b -> {
|
||||
b.field("type", "constant_keyword");
|
||||
b.field("value", "foo");
|
||||
}),
|
||||
fieldMapping(b -> {
|
||||
b.field("type", "constant_keyword");
|
||||
b.field("value", "bar");
|
||||
}));
|
||||
}
|
||||
|
||||
public void testFetchValue() throws Exception {
|
||||
MapperService mapperService = createMapperService(fieldMapping(b -> b.field("type", "constant_keyword")));
|
||||
FieldMapper fieldMapper = (FieldMapper) mapperService.documentMapper().mappers().getMapper("field");
|
||||
|
|
|
@ -50,6 +50,11 @@ public class VersionStringFieldMapperTests extends MapperTestCase {
|
|||
builder.value("1.2.3");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) throws IOException {
|
||||
// no configurable parameters
|
||||
}
|
||||
|
||||
public void testDefaults() throws Exception {
|
||||
XContentBuilder mapping = fieldMapping(this::minimalMapping);
|
||||
DocumentMapper mapper = createDocumentMapper(mapping);
|
||||
|
|
|
@ -60,6 +60,14 @@ public final class RuntimeFieldMapper extends ParametrizedFieldMapper {
|
|||
this.scriptCompiler = scriptCompiler;
|
||||
}
|
||||
|
||||
String runtimeType() {
|
||||
return runtimeType;
|
||||
}
|
||||
|
||||
Script script() {
|
||||
return script;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParametrizedFieldMapper.Builder getMergeBuilder() {
|
||||
return new RuntimeFieldMapper.Builder(simpleName(), scriptCompiler).init(this);
|
||||
|
|
|
@ -76,6 +76,11 @@ public class RuntimeFieldMapperTests extends MapperTestCase {
|
|||
b.startObject("script").field("source", "dummy_source").field("lang", "test").endObject();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerParameters(ParameterChecker checker) {
|
||||
// TODO need to be able to pass a completely new config rather than updating minimal mapping
|
||||
}
|
||||
|
||||
public void testRuntimeTypeIsRequired() throws Exception {
|
||||
XContentBuilder mapping = XContentFactory.jsonBuilder()
|
||||
.startObject()
|
||||
|
|
Loading…
Reference in New Issue