Skip to content

Commit ecd0d83

Browse files
committed
Allow setting default_metric for numerics
1 parent 2bbb58a commit ecd0d83

File tree

15 files changed

+163
-6
lines changed

15 files changed

+163
-6
lines changed

benchmarks/src/main/java/org/elasticsearch/benchmark/_nightly/esql/ValuesSourceReaderBenchmark.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ private static BlockLoader numericBlockLoader(WhereAndBaseName w, NumberFieldMap
285285
false,
286286
null,
287287
null,
288+
null,
288289
false
289290
).blockLoader(new MappedFieldType.BlockLoaderContext() {
290291
@Override

benchmarks/src/main/java/org/elasticsearch/benchmark/script/ScriptScoreBenchmark.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,10 @@ public class ScriptScoreBenchmark {
8585
private final ScriptModule scriptModule = new ScriptModule(Settings.EMPTY, pluginsService.filterPlugins(ScriptPlugin.class).toList());
8686

8787
private final Map<String, MappedFieldType> fieldTypes = Map.ofEntries(
88-
Map.entry("n", new NumberFieldType("n", NumberType.LONG, false, false, true, true, null, Map.of(), null, false, null, null, false))
88+
Map.entry(
89+
"n",
90+
new NumberFieldType("n", NumberType.LONG, false, false, true, true, null, Map.of(), null, false, null, null, null, false)
91+
)
8992
);
9093
private final IndexFieldDataCache fieldDataCache = new IndexFieldDataCache.None();
9194
private final CircuitBreakerService breakerService = new NoneCircuitBreakerService();

modules/data-streams/src/main/java/org/elasticsearch/datastreams/DataStreamFeatures.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ public class DataStreamFeatures implements FeatureSpecification {
3030

3131
public static final NodeFeature FAILURE_STORE_IN_LOG_DATA_STREAMS = new NodeFeature("logs_data_streams.failure_store.enabled");
3232

33+
public static final NodeFeature DOWNSAMPLE_DEFAULT_METRIC_FOR_NUMERICS_FIX = new NodeFeature(
34+
"data_stream.downsample.default_metric_for_numerics_fix"
35+
);
36+
3337
@Override
3438
public Set<NodeFeature> getFeatures() {
3539
return Set.of(DataStream.DATA_STREAM_FAILURE_STORE_FEATURE);
@@ -41,7 +45,8 @@ public Set<NodeFeature> getTestFeatures() {
4145
DATA_STREAM_FAILURE_STORE_TSDB_FIX,
4246
DOWNSAMPLE_AGGREGATE_DEFAULT_METRIC_FIX,
4347
LOGS_STREAM_FEATURE,
44-
FAILURE_STORE_IN_LOG_DATA_STREAMS
48+
FAILURE_STORE_IN_LOG_DATA_STREAMS,
49+
DOWNSAMPLE_DEFAULT_METRIC_FOR_NUMERICS_FIX
4550
);
4651
}
4752
}

modules/mapper-extras/src/main/java/org/elasticsearch/index/mapper/extras/TokenCountFieldMapper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ static class TokenCountFieldType extends NumberFieldMapper.NumberFieldType {
117117
false,
118118
null,
119119
null,
120+
null,
120121
isSyntheticSource
121122
);
122123
}

plugins/mapper-size/src/main/java/org/elasticsearch/index/mapper/size/SizeFieldMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public SizeFieldMapper build() {
5050

5151
private static class SizeFieldType extends NumberFieldType {
5252
SizeFieldType() {
53-
super(NAME, NumberType.INTEGER, true, true, true, false, null, Collections.emptyMap(), null, false, null, null, false);
53+
super(NAME, NumberType.INTEGER, true, true, true, false, null, Collections.emptyMap(), null, false, null, null, null, false);
5454
}
5555

5656
@Override

server/src/main/java/org/elasticsearch/index/mapper/NumberFieldMapper.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.elasticsearch.index.fielddata.SourceValueFetcherSortedNumericIndexFieldData;
4646
import org.elasticsearch.index.fielddata.plain.SortedDoublesIndexFieldData;
4747
import org.elasticsearch.index.fielddata.plain.SortedNumericIndexFieldData;
48+
import org.elasticsearch.index.mapper.TimeSeriesParams.GaugeAggs;
4849
import org.elasticsearch.index.mapper.TimeSeriesParams.MetricType;
4950
import org.elasticsearch.index.query.SearchExecutionContext;
5051
import org.elasticsearch.script.DoubleFieldScript;
@@ -122,6 +123,8 @@ public static final class Builder extends FieldMapper.DimensionBuilder {
122123
*/
123124
private final Parameter<MetricType> metric;
124125

126+
private final Parameter<GaugeAggs> defaultMetric;
127+
125128
private final Parameter<Map<String, String>> meta = Parameter.metaParam();
126129

127130
private final ScriptCompiler scriptCompiler;
@@ -223,6 +226,20 @@ public Builder(
223226
}
224227
}).precludesParameters(dimension);
225228

229+
this.defaultMetric = TimeSeriesParams.defaultMetric(m -> toType(m).defaultMetric).addValidator(s -> {
230+
if (s != null && metric.getValue() != MetricType.GAUGE) {
231+
throw new IllegalArgumentException(
232+
"Field ["
233+
+ TimeSeriesParams.TIME_SERIES_METRIC_PARAM
234+
+ "] must be set to ["
235+
+ MetricType.GAUGE
236+
+ "] to allow setting of ["
237+
+ TimeSeriesParams.TIME_SERIES_DEFAULT_METRIC_PARAM
238+
+ "]"
239+
);
240+
}
241+
});
242+
226243
this.script.precludesParameters(ignoreMalformed, coerce, nullValue);
227244
addScriptValidation(script, indexed, hasDocValues);
228245

@@ -278,7 +295,8 @@ protected Parameter<?>[] getParameters() {
278295
onScriptErrorParam,
279296
meta,
280297
dimension,
281-
metric };
298+
metric,
299+
defaultMetric };
282300
}
283301

284302
@Override
@@ -1843,6 +1861,7 @@ public static class NumberFieldType extends SimpleMappedFieldType {
18431861
private final FieldValues<Number> scriptValues;
18441862
private final boolean isDimension;
18451863
private final MetricType metricType;
1864+
private final GaugeAggs defaultMetric;
18461865
private final IndexMode indexMode;
18471866
private final boolean isSyntheticSource;
18481867

@@ -1858,6 +1877,7 @@ public NumberFieldType(
18581877
FieldValues<Number> script,
18591878
boolean isDimension,
18601879
MetricType metricType,
1880+
GaugeAggs defaultMetric,
18611881
IndexMode indexMode,
18621882
boolean isSyntheticSource
18631883
) {
@@ -1868,6 +1888,7 @@ public NumberFieldType(
18681888
this.scriptValues = script;
18691889
this.isDimension = isDimension;
18701890
this.metricType = metricType;
1891+
this.defaultMetric = defaultMetric;
18711892
this.indexMode = indexMode;
18721893
this.isSyntheticSource = isSyntheticSource;
18731894
}
@@ -1885,6 +1906,7 @@ public NumberFieldType(
18851906
builder.scriptValues(),
18861907
builder.dimension.getValue(),
18871908
builder.metric.getValue(),
1909+
builder.defaultMetric.getValue(),
18881910
builder.indexMode,
18891911
isSyntheticSource
18901912
);
@@ -1895,7 +1917,7 @@ public NumberFieldType(String name, NumberType type) {
18951917
}
18961918

18971919
public NumberFieldType(String name, NumberType type, boolean isIndexed) {
1898-
this(name, type, isIndexed, false, true, true, null, Collections.emptyMap(), null, false, null, null, false);
1920+
this(name, type, isIndexed, false, true, true, null, Collections.emptyMap(), null, false, null, null, null, false);
18991921
}
19001922

19011923
@Override
@@ -2092,6 +2114,7 @@ public MetricType getMetricType() {
20922114
private final ScriptCompiler scriptCompiler;
20932115
private final Script script;
20942116
private final MetricType metricType;
2117+
private final GaugeAggs defaultMetric;
20952118
private boolean allowMultipleValues;
20962119
private final IndexVersion indexCreatedVersion;
20972120
private final boolean isSyntheticSource;
@@ -2123,6 +2146,7 @@ private NumberFieldMapper(
21232146
this.scriptCompiler = builder.scriptCompiler;
21242147
this.script = builder.script.getValue();
21252148
this.metricType = builder.metric.getValue();
2149+
this.defaultMetric = builder.defaultMetric.getValue();
21262150
this.allowMultipleValues = builder.allowMultipleValues;
21272151
this.indexCreatedVersion = builder.indexCreatedVersion;
21282152
this.isSyntheticSource = isSyntheticSource;

server/src/main/java/org/elasticsearch/index/mapper/TimeSeriesParams.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
import java.util.Arrays;
1313
import java.util.EnumSet;
14+
import java.util.List;
1415
import java.util.Locale;
16+
import java.util.Set;
1517
import java.util.function.Function;
1618

1719
/**
@@ -21,6 +23,7 @@ public final class TimeSeriesParams {
2123

2224
public static final String TIME_SERIES_METRIC_PARAM = "time_series_metric";
2325
public static final String TIME_SERIES_DIMENSION_PARAM = "time_series_dimension";
26+
public static final String TIME_SERIES_DEFAULT_METRIC_PARAM = "default_metric";
2427

2528
private TimeSeriesParams() {}
2629

@@ -33,7 +36,7 @@ private TimeSeriesParams() {}
3336
* single number metrics, and `false` for the POSITION metric.
3437
*/
3538
public enum MetricType {
36-
GAUGE(new String[] { "max", "min", "value_count", "sum" }),
39+
GAUGE(GaugeAggs.allValuesAsString().toArray(String[]::new)),
3740
COUNTER(new String[] { "last_value" }),
3841
POSITION(new String[] {}, false);
3942

@@ -74,6 +77,22 @@ public static MetricType fromString(String value) {
7477
}
7578
}
7679

80+
public enum GaugeAggs {
81+
MAX,
82+
MIN,
83+
SUM,
84+
VALUE_COUNT;
85+
86+
@Override
87+
public final String toString() {
88+
return name().toLowerCase(Locale.ROOT);
89+
}
90+
91+
private static List<String> allValuesAsString() {
92+
return Arrays.stream(GaugeAggs.values()).map(GaugeAggs::toString).toList();
93+
}
94+
}
95+
7796
public static FieldMapper.Parameter<MetricType> metricParam(Function<FieldMapper, MetricType> initializer, MetricType... values) {
7897
assert values.length > 0;
7998
EnumSet<MetricType> acceptedValues = EnumSet.noneOf(MetricType.class);
@@ -88,6 +107,17 @@ public static FieldMapper.Parameter<MetricType> metricParam(Function<FieldMapper
88107
).acceptsNull();
89108
}
90109

110+
public static FieldMapper.Parameter<GaugeAggs> defaultMetric(Function<FieldMapper, GaugeAggs> initializer) {
111+
return FieldMapper.Parameter.restrictedEnumParam(
112+
TIME_SERIES_DEFAULT_METRIC_PARAM,
113+
false,
114+
initializer,
115+
(GaugeAggs) null,
116+
GaugeAggs.class,
117+
Set.of(GaugeAggs.values())
118+
);
119+
}
120+
91121
public static FieldMapper.Parameter<Boolean> dimensionParam(Function<FieldMapper, Boolean> initializer) {
92122
return FieldMapper.Parameter.boolParam(TIME_SERIES_DIMENSION_PARAM, false, initializer, false);
93123
}

server/src/test/java/org/elasticsearch/index/fielddata/IndexFieldDataServiceTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ public void testRequireDocValuesOnLongs() {
337337
false,
338338
null,
339339
null,
340+
null,
340341
false
341342
)
342343
);
@@ -358,6 +359,7 @@ public void testRequireDocValuesOnDoubles() {
358359
false,
359360
null,
360361
null,
362+
null,
361363
false
362364
)
363365
);

server/src/test/java/org/elasticsearch/index/mapper/NumberFieldTypeTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ private static MappedFieldType unsearchable() {
141141
false,
142142
null,
143143
null,
144+
null,
144145
false
145146
);
146147
}

server/src/test/java/org/elasticsearch/search/aggregations/AggregatorBaseTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ private ValuesSourceConfig getVSConfig(
9393
false,
9494
null,
9595
null,
96+
null,
9697
false
9798
);
9899
return ValuesSourceConfig.resolveFieldOnly(ft, context);

0 commit comments

Comments
 (0)