diff --git a/benchmarks/src/main/java/org/elasticsearch/benchmark/script/ScriptScoreBenchmark.java b/benchmarks/src/main/java/org/elasticsearch/benchmark/script/ScriptScoreBenchmark.java index 19829074d96f1..05ac262c533e5 100644 --- a/benchmarks/src/main/java/org/elasticsearch/benchmark/script/ScriptScoreBenchmark.java +++ b/benchmarks/src/main/java/org/elasticsearch/benchmark/script/ScriptScoreBenchmark.java @@ -80,7 +80,7 @@ public class ScriptScoreBenchmark { private final ScriptModule scriptModule = new ScriptModule(Settings.EMPTY, pluginsService.filterPlugins(ScriptPlugin.class)); private final Map fieldTypes = Map.ofEntries( - Map.entry("n", new NumberFieldType("n", NumberType.LONG, false, false, true, true, null, Map.of(), null, false)) + Map.entry("n", new NumberFieldType("n", NumberType.LONG, false, false, true, true, null, Map.of(), null, false, null)) ); private final IndexFieldDataCache fieldDataCache = new IndexFieldDataCache.None(); private final CircuitBreakerService breakerService = new NoneCircuitBreakerService(); diff --git a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/TokenCountFieldMapper.java b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/TokenCountFieldMapper.java index 7d9b09e8f67d0..1f428317153b0 100644 --- a/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/TokenCountFieldMapper.java +++ b/modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/TokenCountFieldMapper.java @@ -75,9 +75,27 @@ public TokenCountFieldMapper build(MapperBuilderContext context) { static class TokenCountFieldType extends NumberFieldMapper.NumberFieldType { - TokenCountFieldType(String name, boolean isSearchable, boolean isStored, - boolean hasDocValues, Number nullValue, Map meta) { - super(name, NumberFieldMapper.NumberType.INTEGER, isSearchable, isStored, hasDocValues, false, nullValue, meta, null, false); + TokenCountFieldType( + String name, + boolean isSearchable, + boolean isStored, + boolean hasDocValues, + Number nullValue, + Map meta + ) { + super( + name, + NumberFieldMapper.NumberType.INTEGER, + isSearchable, + isStored, + hasDocValues, + false, + nullValue, + meta, + null, + false, + null + ); } @Override diff --git a/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java index 13f5085b82c6e..6018f410be6a3 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/FieldMapper.java @@ -32,6 +32,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; +import java.util.EnumSet; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; @@ -905,6 +906,67 @@ public static Parameter restrictedStringParam(String name, boolean updat }); } + /** + * Defines a parameter that takes any of the values of an enumeration. + * + * @param name the parameter name + * @param updateable whether the parameter can be changed by a mapping update + * @param initializer a function that reads the parameter value from an existing mapper + * @param defaultValue the default value, to be used if the parameter is undefined in a mapping + * @param enumClass the enumeration class the parameter takes values from + */ + public static > Parameter enumParam( + String name, + boolean updateable, + Function initializer, + T defaultValue, + Class enumClass + ) { + Set acceptedValues = EnumSet.allOf(enumClass); + return restrictedEnumParam(name, updateable, initializer, defaultValue, enumClass, acceptedValues); + } + + /** + * Defines a parameter that takes one of a restricted set of values from an enumeration. + * + * @param name the parameter name + * @param updateable whether the parameter can be changed by a mapping update + * @param initializer a function that reads the parameter value from an existing mapper + * @param defaultValue the default value, to be used if the parameter is undefined in a mapping + * @param enumClass the enumeration class the parameter takes values from + * @param values the set of values that the parameter can take + */ + public static > Parameter restrictedEnumParam( + String name, + boolean updateable, + Function initializer, + T defaultValue, + Class enumClass, + Set values + ) { + assert values.size() > 0; + return new Parameter(name, updateable, () -> defaultValue, (n, c, o) -> { + if (o == null) { + return defaultValue; + } + try { + @SuppressWarnings("unchecked") + T enumValue = Enum.valueOf(enumClass, (String) o); + return enumValue; + } catch (IllegalArgumentException e) { + throw new MapperParsingException( + "Unknown value [" + o + "] for field [" + name + "] - accepted values are " + values + ); + } + }, initializer).addValidator(v -> { + if (v != null && values.contains(v) == false) { + throw new MapperParsingException( + "Unknown value [" + v + "] for field [" + name + "] - accepted values are " + values + ); + } + }); + } + /** * Defines a parameter that takes an analyzer name * @param name the parameter name diff --git a/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java b/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java index a31846bba5236..03c9e8395526d 100644 --- a/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java +++ b/server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java @@ -37,6 +37,7 @@ import org.elasticsearch.index.fielddata.IndexFieldData; import org.elasticsearch.index.fielddata.IndexNumericFieldData.NumericType; import org.elasticsearch.index.fielddata.plain.SortedNumericIndexFieldData; +import org.elasticsearch.index.mapper.TimeSeriesParams.MetricType; import org.elasticsearch.index.query.SearchExecutionContext; import org.elasticsearch.script.DoubleFieldScript; import org.elasticsearch.script.LongFieldScript; @@ -83,8 +84,18 @@ public static class Builder extends FieldMapper.Builder { private final Parameter