38
38
import org .elasticsearch .index .mapper .SimpleMappedFieldType ;
39
39
import org .elasticsearch .index .mapper .SourceValueFetcher ;
40
40
import org .elasticsearch .index .mapper .TextSearchInfo ;
41
+ import org .elasticsearch .index .mapper .TimeSeriesParams ;
41
42
import org .elasticsearch .index .mapper .ValueFetcher ;
42
43
import org .elasticsearch .index .query .SearchExecutionContext ;
43
44
import org .elasticsearch .search .DocValueFormat ;
@@ -91,6 +92,13 @@ public static class Builder extends FieldMapper.Builder {
91
92
92
93
private final Parameter <Map <String , String >> meta = Parameter .metaParam ();
93
94
95
+ /**
96
+ * Parameter that marks this field as a time series metric defining its time series metric type.
97
+ * For the numeric fields gauge and counter metric types are
98
+ * supported
99
+ */
100
+ private final Parameter <TimeSeriesParams .MetricType > metric ;
101
+
94
102
public Builder (String name , Settings settings ) {
95
103
this (name , IGNORE_MALFORMED_SETTING .get (settings ), COERCE_SETTING .get (settings ));
96
104
}
@@ -101,6 +109,18 @@ public Builder(String name, boolean ignoreMalformedByDefault, boolean coerceByDe
101
109
= Parameter .explicitBoolParam ("ignore_malformed" , true , m -> toType (m ).ignoreMalformed , ignoreMalformedByDefault );
102
110
this .coerce
103
111
= Parameter .explicitBoolParam ("coerce" , true , m -> toType (m ).coerce , coerceByDefault );
112
+
113
+ this .metric = TimeSeriesParams .metricParam (
114
+ m -> toType (m ).metricType ,
115
+ TimeSeriesParams .MetricType .gauge ,
116
+ TimeSeriesParams .MetricType .counter
117
+ ).addValidator (v -> {
118
+ if (v != null && hasDocValues .getValue () == false ) {
119
+ throw new IllegalArgumentException (
120
+ "Field [" + TimeSeriesParams .TIME_SERIES_METRIC_PARAM + "] requires that [" + hasDocValues .name + "] is true"
121
+ );
122
+ }
123
+ });
104
124
}
105
125
106
126
Builder scalingFactor (double scalingFactor ) {
@@ -113,15 +133,28 @@ Builder nullValue(double nullValue) {
113
133
return this ;
114
134
}
115
135
136
+ public Builder metric (TimeSeriesParams .MetricType metric ) {
137
+ this .metric .setValue (metric );
138
+ return this ;
139
+ }
140
+
116
141
@ Override
117
142
protected List <Parameter <?>> getParameters () {
118
- return List .of (indexed , hasDocValues , stored , ignoreMalformed , meta , scalingFactor , coerce , nullValue );
143
+ return List .of (indexed , hasDocValues , stored , ignoreMalformed , meta , scalingFactor , coerce , nullValue , metric );
119
144
}
120
145
121
146
@ Override
122
147
public ScaledFloatFieldMapper build (MapperBuilderContext context ) {
123
- ScaledFloatFieldType type = new ScaledFloatFieldType (context .buildFullName (name ), indexed .getValue (), stored .getValue (),
124
- hasDocValues .getValue (), meta .getValue (), scalingFactor .getValue (), nullValue .getValue ());
148
+ ScaledFloatFieldType type = new ScaledFloatFieldType (
149
+ context .buildFullName (name ),
150
+ indexed .getValue (),
151
+ stored .getValue (),
152
+ hasDocValues .getValue (),
153
+ meta .getValue (),
154
+ scalingFactor .getValue (),
155
+ nullValue .getValue (),
156
+ metric .getValue ()
157
+ );
125
158
return new ScaledFloatFieldMapper (name , type , multiFieldsBuilder .build (this , context ), copyTo .build (), this );
126
159
}
127
160
}
@@ -132,16 +165,20 @@ public static final class ScaledFloatFieldType extends SimpleMappedFieldType {
132
165
133
166
private final double scalingFactor ;
134
167
private final Double nullValue ;
168
+ private final TimeSeriesParams .MetricType metricType ;
169
+
135
170
136
171
public ScaledFloatFieldType (String name , boolean indexed , boolean stored , boolean hasDocValues ,
137
- Map <String , String > meta , double scalingFactor , Double nullValue ) {
172
+ Map <String , String > meta , double scalingFactor , Double nullValue ,
173
+ TimeSeriesParams .MetricType metricType ) {
138
174
super (name , indexed , stored , hasDocValues , TextSearchInfo .SIMPLE_MATCH_WITHOUT_TERMS , meta );
139
175
this .scalingFactor = scalingFactor ;
140
176
this .nullValue = nullValue ;
177
+ this .metricType = metricType ;
141
178
}
142
179
143
180
public ScaledFloatFieldType (String name , double scalingFactor ) {
144
- this (name , true , false , true , Collections .emptyMap (), scalingFactor , null );
181
+ this (name , true , false , true , Collections .emptyMap (), scalingFactor , null , null );
145
182
}
146
183
147
184
public double getScalingFactor () {
@@ -260,6 +297,14 @@ public DocValueFormat docValueFormat(String format, ZoneId timeZone) {
260
297
private double scale (Object input ) {
261
298
return new BigDecimal (Double .toString (parse (input ))).multiply (BigDecimal .valueOf (scalingFactor )).doubleValue ();
262
299
}
300
+
301
+ /**
302
+ * If field is a time series metric field, returns its metric type
303
+ * @return the metric type or null
304
+ */
305
+ public TimeSeriesParams .MetricType getMetricType () {
306
+ return metricType ;
307
+ }
263
308
}
264
309
265
310
private final Explicit <Boolean > ignoreMalformed ;
@@ -272,6 +317,7 @@ private double scale(Object input) {
272
317
273
318
private final boolean ignoreMalformedByDefault ;
274
319
private final boolean coerceByDefault ;
320
+ private final TimeSeriesParams .MetricType metricType ;
275
321
276
322
private ScaledFloatFieldMapper (
277
323
String simpleName ,
@@ -289,6 +335,7 @@ private ScaledFloatFieldMapper(
289
335
this .coerce = builder .coerce .getValue ();
290
336
this .ignoreMalformedByDefault = builder .ignoreMalformed .getDefaultValue ().value ();
291
337
this .coerceByDefault = builder .coerce .getDefaultValue ().value ();
338
+ this .metricType = builder .metric .getValue ();
292
339
}
293
340
294
341
boolean coerce () {
@@ -311,12 +358,11 @@ protected String contentType() {
311
358
312
359
@ Override
313
360
public FieldMapper .Builder getMergeBuilder () {
314
- return new Builder (simpleName (), ignoreMalformedByDefault , coerceByDefault ).init (this );
361
+ return new Builder (simpleName (), ignoreMalformedByDefault , coerceByDefault ).metric ( metricType ). init (this );
315
362
}
316
363
317
364
@ Override
318
365
protected void parseCreateField (DocumentParserContext context ) throws IOException {
319
-
320
366
XContentParser parser = context .parser ();
321
367
Object value ;
322
368
Number numericValue = null ;
0 commit comments