diff --git a/docs/changelog/88695.yaml b/docs/changelog/88695.yaml new file mode 100644 index 0000000000000..cd8f9b6cb866a --- /dev/null +++ b/docs/changelog/88695.yaml @@ -0,0 +1,5 @@ +pr: 88695 +summary: "[TSDB] Metric fields in the field caps API" +area: TSDB +type: enhancement +issues: [] diff --git a/docs/reference/search/field-caps.asciidoc b/docs/reference/search/field-caps.asciidoc index fda14aed559fa..e51bf01e2f651 100644 --- a/docs/reference/search/field-caps.asciidoc +++ b/docs/reference/search/field-caps.asciidoc @@ -137,11 +137,13 @@ field types are all described as the `keyword` type family. `time_series_dimension`:: preview:[] - Whether this field is used as a time series dimension. + Whether this field is used as a time series dimension on all indices. + For non-time-series indices this field is not present. `time_series_metric`:: preview:[] - Contains metric type if this fields is used as a time series metrics, absent if the field is not used as metric. + Contains the metric type if the field is used as a time series metric on all indices, absent if the field is + not used as a metric. For non-time-series indices this field is not included. `indices`:: The list of indices where this field has the same type family, or null if all indices @@ -157,12 +159,12 @@ field types are all described as the `keyword` type family. `non_dimension_indices`:: experimental:[] - If this list is present in response then some indices have the field marked as a dimension and other indices, the + If this list is present in the response, some indices have the field marked as a dimension and other indices, the ones in this list, do not. `metric_conflicts_indices`:: experimental:[] - The list of indices where this field is present if these indices don't have the same `time_series_metric` value for + The list of indices where this field is present, if these indices don't have the same `time_series_metric` value for this field. `meta`:: diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/field_caps/40_time_series.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/field_caps/40_time_series.yml index ad36eaf872d57..345939c44883a 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/field_caps/40_time_series.yml +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/field_caps/40_time_series.yml @@ -12,6 +12,11 @@ setup: index: number_of_replicas: 0 number_of_shards: 2 + mode: time_series + routing_path: [ metricset, k8s.pod.uid ] + time_series: + start_time: 2021-04-28T00:00:00Z + end_time: 2021-04-29T00:00:00Z mappings: properties: "@timestamp": @@ -59,6 +64,11 @@ setup: index: number_of_replicas: 0 number_of_shards: 2 + mode: time_series + routing_path: [ k8s.pod.uid ] + time_series: + start_time: 2021-04-28T00:00:00Z + end_time: 2021-04-29T00:00:00Z mappings: properties: "@timestamp": diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/tsdb/05_dimension_and_metric_in_non_tsdb_index.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/tsdb/05_dimension_and_metric_in_non_tsdb_index.yml index 4b6a376637617..458b27149fd87 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/tsdb/05_dimension_and_metric_in_non_tsdb_index.yml +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/tsdb/05_dimension_and_metric_in_non_tsdb_index.yml @@ -183,8 +183,8 @@ can't shadow metrics: # Test that _tsid field is not added if an index is not a time-series index no _tsid in standard indices: - skip: - version: " - 8.0.99" - reason: _tsid support introduced in 8.1.0 + version: " - 8.4.99" + reason: time series params only on time series indices introduced in 8.5.0 - do: indices.create: @@ -209,11 +209,11 @@ no _tsid in standard indices: - match: {fields.metricset.keyword.searchable: true} - match: {fields.metricset.keyword.aggregatable: true} - - match: {fields.metricset.keyword.time_series_dimension: true} - is_false: fields.metricset.keyword.indices - is_false: fields.metricset.keyword.non_searchable_indices - is_false: fields.metricset.keyword.non_aggregatable_indices - is_false: fields._tsid # _tsid metadata field must not exist in non-time-series indices + - is_false: fields.metricset.keyword.time_series_dimension # time_series_dimension param is ignored in non-time-series indices --- no nested dimensions: diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/tsdb/110_field_caps.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/tsdb/110_field_caps.yml new file mode 100644 index 0000000000000..7af36d5cfe7a0 --- /dev/null +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/tsdb/110_field_caps.yml @@ -0,0 +1,231 @@ +setup: + - skip: + version: " - 8.4.99" + reason: metric params only on time series indexes introduced in 8.5.0 + + - do: + indices.create: + index: test_time_series + body: + settings: + index: + number_of_replicas: 0 + number_of_shards: 2 + mode: time_series + routing_path: [ metricset, k8s.pod.uid ] + time_series: + start_time: 2021-04-28T00:00:00Z + end_time: 2021-04-29T00:00:00Z + mappings: + properties: + "@timestamp": + type: date + metricset: + type: keyword + time_series_dimension: true + k8s: + properties: + pod: + properties: + availability_zone: + type: short + time_series_dimension: true + uid: + type: keyword + time_series_dimension: true + name: + type: keyword + ip: + type: ip + time_series_dimension: true + network: + properties: + tx: + type: long + time_series_metric: counter + rx: + type: long + time_series_metric: gauge + + - do: + indices.create: + index: test_non_time_series + body: + settings: + index: + number_of_replicas: 0 + number_of_shards: 2 + mappings: + properties: + "@timestamp": + type: date + metricset: + type: keyword + time_series_dimension: true + k8s: + properties: + pod: + properties: + availability_zone: + type: short + time_series_dimension: true + uid: + type: keyword + time_series_dimension: true + name: + type: keyword + ip: + type: ip + time_series_dimension: true + network: + properties: + tx: + type: long + time_series_metric: counter + rx: + type: long + time_series_metric: gauge + +--- +field caps on time_series indices: + - skip: + version: " - 8.3.99" + reason: metric params only on time series indexes introduced in 8.4.0 + + - do: + field_caps: + index: test_time_series + fields: [ k8s.pod.uid, k8s.pod.network.rx, k8s.pod.network.tx, k8s.pod.ip, metricset, _tsid ] + + - match: { fields.k8s\.pod\.uid.keyword.type: keyword } + - match: { fields.k8s\.pod\.uid.keyword.searchable: true } + - match: { fields.k8s\.pod\.uid.keyword.aggregatable: true } + - match: { fields.k8s\.pod\.uid.keyword.time_series_dimension: true } + - is_false: fields.k8s\.pod\.uid.keyword.indices + - is_false: fields.k8s\.pod\.uid.keyword.non_searchable_indices + - is_false: fields.k8s\.pod\.uid.keyword.non_aggregatable_indices + + - match: { fields.k8s\.pod\.network\.rx.long.type: long } + - match: { fields.k8s\.pod\.network\.rx.long.searchable: true } + - match: { fields.k8s\.pod\.network\.rx.long.aggregatable: true } + - match: { fields.k8s\.pod\.network\.rx.long.time_series_metric: gauge } + - is_false: fields.k8s\.pod\.network\.tx.long.metric_conflicts_indices + - is_false: fields.k8s\.pod\.network\.rx.long.indices + - is_false: fields.k8s\.pod\.network\.rx.long.non_searchable_indices + - is_false: fields.k8s\.pod\.network\.rx.long.non_aggregatable_indices + + + - match: { fields.k8s\.pod\.network\.tx.long.type: long } + - match: { fields.k8s\.pod\.network\.tx.long.searchable: true } + - match: { fields.k8s\.pod\.network\.tx.long.aggregatable: true } + - match: { fields.k8s\.pod\.network\.tx.long.time_series_metric: counter } + - is_false: fields.k8s\.pod\.network\.tx.long.metric_conflicts_indices + - is_false: fields.k8s\.pod\.network\.tx.long.indices + - is_false: fields.k8s\.pod\.network\.tx.long.non_searchable_indices + - is_false: fields.k8s\.pod\.network\.tx.long.non_aggregatable_indices + + - match: { fields.k8s\.pod\.ip.ip.type: ip } + - match: { fields.k8s\.pod\.ip.ip.searchable: true } + - match: { fields.k8s\.pod\.ip.ip.aggregatable: true } + - is_false: fields.k8s\.pod\.ip.ip.indices + - is_false: fields.k8s\.pod\.ip.ip.non_searchable_indices + - is_false: fields.k8s\.pod\.ip.ip.non_aggregatable_indices + + - match: { fields.metricset.keyword.type: keyword } + - match: { fields.metricset.keyword.searchable: true } + - match: { fields.metricset.keyword.aggregatable: true } + - match: { fields.metricset.keyword.time_series_dimension: true } + - is_false: fields.metricset.keyword.non_dimension_indices + - is_false: fields.metricset.keyword.indices + - is_false: fields.metricset.keyword.non_searchable_indices + - is_false: fields.metricset.keyword.non_aggregatable_indices + + - match: { fields._tsid._tsid.metadata_field: true } + - match: { fields._tsid._tsid.searchable: false } + - match: { fields._tsid._tsid.aggregatable: true } + - is_false: fields._tsid._tsid.indices + - is_false: fields._tsid._tsid.non_searchable_indices + - is_false: fields._tsid._tsid.non_aggregatable_indices + + +--- +field caps on standard indices: + - skip: + version: " - 8.3.99" + reason: metric params only on time series indexes introduced in 8.4.0 + + - do: + field_caps: + index: test_non_time_series + fields: [ _tsid, metricset, k8s.pod.network.rx, k8s.pod.network.tx, k8s.pod.network.rx ] + + - match: { fields.metricset.keyword.type: keyword } + - match: { fields.metricset.keyword.searchable: true } + - match: { fields.metricset.keyword.aggregatable: true } + - is_false: fields.metricset.keyword.time_series_dimension + - is_false: fields.metricset.keyword.non_dimension_indices + - is_false: fields.metricset.keyword.indices + - is_false: fields.metricset.keyword.non_searchable_indices + - is_false: fields.metricset.keyword.non_aggregatable_indices + + - is_false: fields._tsid # _tsid metadata field must not exist in non-time-series indices + + - match: { fields.k8s\.pod\.network\.rx.long.type: long } + - match: { fields.k8s\.pod\.network\.rx.long.searchable: true } + - match: { fields.k8s\.pod\.network\.rx.long.aggregatable: true } + - is_false: fields.k8s\.pod\.network\.rx.long.time_series_metric + - is_false: fields.k8s\.pod\.network\.rx.long.metric_conflicts_indices + - is_false: fields.k8s\.pod\.network\.rx.long.indices + - is_false: fields.k8s\.pod\.network\.rx.long.non_searchable_indices + - is_false: fields.k8s\.pod\.network\.rx.long.non_aggregatable_indices + - is_false: fields.k8s\.pod\.network\.rx.gauge + + - match: { fields.k8s\.pod\.network\.tx.long.type: long } + - match: { fields.k8s\.pod\.network\.tx.long.searchable: true } + - match: { fields.k8s\.pod\.network\.tx.long.aggregatable: true } + - is_false: fields.k8s\.pod\.network\.tx.long.time_series_metric + - is_false: fields.k8s\.pod\.network\.tx.long.metric_conflicts_indices + - is_false: fields.k8s\.pod\.network\.tx.long.indices + - is_false: fields.k8s\.pod\.network\.tx.long.non_searchable_indices + - is_false: fields.k8s\.pod\.network\.tx.long.non_aggregatable_indices + - is_false: fields.k8s\.pod\.network\.tx.counter + + +--- +field caps on mixed indices: + - skip: + version: " - 8.3.99" + reason: metric params only on time series indexes introduced in 8.4.0 + + - do: + field_caps: + index: test_* + fields: [ metricset, k8s.pod.availability_zone, k8s.pod.network.tx, k8s.pod.network.rx ] + + - match: { fields.metricset.keyword.type: keyword } + - match: { fields.metricset.keyword.searchable: true } + - match: { fields.metricset.keyword.aggregatable: true } + - is_false: fields.metricset.keyword.time_series_dimension + - match: { fields.metricset.keyword.non_dimension_indices: [ "test_non_time_series" ] } + - is_false: fields.metricset.keyword.indices + - is_false: fields.metricset.keyword.non_searchable_indices + - is_false: fields.metricset.keyword.non_aggregatable_indices + + - match: { fields.k8s\.pod\.network\.rx.long.type: long } + - match: { fields.k8s\.pod\.network\.rx.long.searchable: true } + - match: { fields.k8s\.pod\.network\.rx.long.aggregatable: true } + - match: { fields.k8s\.pod\.network\.rx.long.metric_conflicts_indices: [ "test_non_time_series", "test_time_series" ] } + - is_false: fields.k8s\.pod\.network\.rx.long.time_series_metric + - is_false: fields.k8s\.pod\.network\.rx.long.non_searchable_indices + - is_false: fields.k8s\.pod\.network\.rx.long.non_aggregatable_indices + - is_false: fields.k8s\.pod\.network\.rx.long.indices + + - match: { fields.k8s\.pod\.network\.tx.long.type: long } + - match: { fields.k8s\.pod\.network\.tx.long.searchable: true } + - match: { fields.k8s\.pod\.network\.tx.long.aggregatable: true } + - match: { fields.k8s\.pod\.network\.tx.long.metric_conflicts_indices: [ "test_non_time_series", "test_time_series" ] } + - is_false: fields.k8s\.pod\.network\.tx.long.time_series_metric + - is_false: fields.k8s\.pod\.network\.tx.long.non_searchable_indices + - is_false: fields.k8s\.pod\.network\.tx.long.non_aggregatable_indices + - is_false: fields.k8s\.pod\.network\.tx.long.indices + diff --git a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/tsdb/40_search.yml b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/tsdb/40_search.yml index 51e6125558da3..48f650a05d6f9 100644 --- a/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/tsdb/40_search.yml +++ b/rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/tsdb/40_search.yml @@ -304,45 +304,6 @@ aggregate a tag: term: _tsid: wont't work ---- -field capabilities: - - skip: - version: " - 8.1.99" - reason: tsdb indexing changed in 8.2.0 - - - do: - field_caps: - index: test - fields: [k8s.pod.uid, k8s.pod.network.rx, k8s.pod.ip, metricset, _tsid] - - - match: {fields.k8s\.pod\.uid.keyword.searchable: true} - - match: {fields.k8s\.pod\.uid.keyword.aggregatable: true} - - match: {fields.k8s\.pod\.uid.keyword.time_series_dimension: true} - - is_false: fields.k8s\.pod\.uid.keyword.indices - - is_false: fields.k8s\.pod\.uid.keyword.non_searchable_indices - - is_false: fields.k8s\.pod\.uid.keyword.non_aggregatable_indices - - match: {fields.k8s\.pod\.network\.rx.long.searchable: true} - - match: {fields.k8s\.pod\.network\.rx.long.aggregatable: true} - - is_false: fields.k8s\.pod\.network\.rx.long.indices - - is_false: fields.k8s\.pod\.network\.rx.long.non_searchable_indices - - is_false: fields.k8s\.pod\.network\.rx.long.non_aggregatable_indices - - match: {fields.k8s\.pod\.ip.ip.searchable: true} - - match: {fields.k8s\.pod\.ip.ip.aggregatable: true} - - is_false: fields.k8s\.pod\.ip.ip.indices - - is_false: fields.k8s\.pod\.ip.ip.non_searchable_indices - - is_false: fields.k8s\.pod\.ip.ip.non_aggregatable_indices - - match: {fields.metricset.keyword.searchable: true} - - match: {fields.metricset.keyword.aggregatable: true} - - match: {fields.metricset.keyword.time_series_dimension: true} - - is_false: fields.metricset.keyword.indices - - is_false: fields.metricset.keyword.non_searchable_indices - - is_false: fields.metricset.keyword.non_aggregatable_indices - - match: {fields._tsid._tsid.metadata_field: true} - - match: {fields._tsid._tsid.searchable: false} - - match: {fields._tsid._tsid.aggregatable: true} - - is_false: fields._tsid._tsid.indices - - is_false: fields._tsid._tsid.non_searchable_indices - - is_false: fields._tsid._tsid.non_aggregatable_indices --- sort by tsid: diff --git a/server/src/internalClusterTest/java/org/elasticsearch/search/fieldcaps/FieldCapabilitiesIT.java b/server/src/internalClusterTest/java/org/elasticsearch/search/fieldcaps/FieldCapabilitiesIT.java index a52940ae9a413..f54c5b529caaa 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/search/fieldcaps/FieldCapabilitiesIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/search/fieldcaps/FieldCapabilitiesIT.java @@ -24,7 +24,9 @@ import org.elasticsearch.common.breaker.CircuitBreakingException; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.index.IndexMode; import org.elasticsearch.index.IndexService; +import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.mapper.DocumentParserContext; import org.elasticsearch.index.mapper.KeywordFieldMapper; import org.elasticsearch.index.mapper.MetadataFieldMapper; @@ -119,7 +121,14 @@ public void setUp() throws Exception { .endObject() .endObject() .endObject(); - assertAcked(prepareCreate("old_index").setMapping(oldIndexMapping)); + + Settings settings = Settings.builder() + .put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES) + .putList(IndexMetadata.INDEX_ROUTING_PATH.getKey(), List.of("some_dimension")) + .put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "2006-01-08T23:40:53.384Z") + .put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "2106-01-08T23:40:53.384Z") + .build(); + assertAcked(prepareCreate("old_index").setSettings(settings).setMapping(oldIndexMapping)); XContentBuilder newIndexMapping = XContentFactory.jsonBuilder() .startObject() diff --git a/server/src/internalClusterTest/java/org/elasticsearch/timeseries/support/TimeSeriesMetricsIT.java b/server/src/internalClusterTest/java/org/elasticsearch/timeseries/support/TimeSeriesMetricsIT.java index 9fa91ac09ef4d..34861d4240da0 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/timeseries/support/TimeSeriesMetricsIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/timeseries/support/TimeSeriesMetricsIT.java @@ -12,12 +12,14 @@ import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.support.ListenableActionFuture; +import org.elasticsearch.cluster.metadata.IndexMetadata; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.time.DateFormatter; import org.elasticsearch.common.util.Maps; import org.elasticsearch.core.CheckedConsumer; import org.elasticsearch.core.TimeValue; import org.elasticsearch.core.Tuple; +import org.elasticsearch.index.IndexMode; import org.elasticsearch.index.IndexSettings; import org.elasticsearch.index.mapper.DateFieldMapper; import org.elasticsearch.search.aggregations.MultiBucketConsumerService; @@ -29,6 +31,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -80,7 +83,9 @@ public void assertSmallSimple(Object d1, Object d2, CheckedConsumer> gen) throws I expectedLatest = expectedLatest.entry(dimensions, List.of(Map.entry(max, value))); expectedValues = expectedValues.entry(dimensions, expectedValuesForTimeSeries); } - indexRandom(true, docs); + indexRandom(true, false, docs); assertMap(latest(iterationSize, TimeValue.timeValueMillis(maxMillis - minMillis), maxMillis), expectedLatest); assertMap( range( @@ -328,7 +334,7 @@ public void testManySteps() throws InterruptedException, ExecutionException, IOE expectedValues.add(Map.entry(timestamp, v)); docs.add(client().prepareIndex("tsdb").setSource(Map.of("@timestamp", timestamp, "dim", "dim", "v", v))); } - indexRandom(true, docs); + indexRandom(true, false, docs); assertMap( range( iterationBuckets, @@ -356,10 +362,11 @@ private void createTsdbIndex(String... keywordDimensions) throws IOException { for (String d : keywordDimensions) { mapping.startObject(d).field("type", "keyword").field("time_series_dimension", true).endObject(); } - }); + }, Arrays.asList(keywordDimensions)); } - private void createTsdbIndex(CheckedConsumer dimensionMapping) throws IOException { + private void createTsdbIndex(CheckedConsumer dimensionMapping, List routingDims) + throws IOException { XContentBuilder mapping = JsonXContent.contentBuilder(); mapping.startObject().startObject("properties"); mapping.startObject("@timestamp").field("type", "date").endObject(); @@ -367,7 +374,14 @@ private void createTsdbIndex(CheckedConsumer dimen mapping.startObject("m").field("type", "double").field("time_series_metric", "gauge").endObject(); dimensionMapping.accept(mapping); mapping.endObject().endObject(); - client().admin().indices().prepareCreate("tsdb").setMapping(mapping).get(); + + Settings settings = Settings.builder() + .put(IndexSettings.MODE.getKey(), IndexMode.TIME_SERIES) + .putList(IndexMetadata.INDEX_ROUTING_PATH.getKey(), routingDims) + .put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "2000-01-08T23:40:53.384Z") + .put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "2106-01-08T23:40:53.384Z") + .build(); + client().admin().indices().prepareCreate("tsdb").setSettings(settings).setMapping(mapping).get(); } private Map>, List>> latest( diff --git a/server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesFetcher.java b/server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesFetcher.java index 08486b6a4aca3..fdac89eec7a4e 100644 --- a/server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesFetcher.java +++ b/server/src/main/java/org/elasticsearch/action/fieldcaps/FieldCapabilitiesFetcher.java @@ -110,18 +110,23 @@ static Map retrieveFieldCaps( boolean includeParentObjects = checkIncludeParents(filters); Predicate filter = buildFilter(indexFieldfilter, filters, types, context); + boolean isTimeSeriesIndex = context.getIndexSettings().getTimestampBounds() != null; Map responseMap = new HashMap<>(); for (String field : fieldNames) { MappedFieldType ft = context.getFieldType(field); if (filter.test(ft)) { IndexFieldCapabilities fieldCap = new IndexFieldCapabilities( field, - ft.familyTypeName(), + // This is a nasty hack so that we expose aggregate_metric_double field, + // when the index is a time series index and the field is marked as metric. + // This code should be reverted once PR https://github.com/elastic/elasticsearch/pull/87849 + // is merged. + isTimeSeriesIndex && ft.getMetricType() != null ? ft.typeName() : ft.familyTypeName(), context.isMetadataField(field), ft.isSearchable(), ft.isAggregatable(), - ft.isDimension(), - ft.getMetricType(), + isTimeSeriesIndex ? ft.isDimension() : false, + isTimeSeriesIndex ? ft.getMetricType() : null, ft.meta() ); responseMap.put(field, fieldCap); diff --git a/server/src/main/java/org/elasticsearch/action/fieldcaps/IndexFieldCapabilities.java b/server/src/main/java/org/elasticsearch/action/fieldcaps/IndexFieldCapabilities.java index 674a8e7da8456..383f5f2a0d4f2 100644 --- a/server/src/main/java/org/elasticsearch/action/fieldcaps/IndexFieldCapabilities.java +++ b/server/src/main/java/org/elasticsearch/action/fieldcaps/IndexFieldCapabilities.java @@ -52,7 +52,6 @@ public class IndexFieldCapabilities implements Writeable { TimeSeriesParams.MetricType metricType, Map meta ) { - this.name = name; this.type = type; this.isMetadatafield = isMetadatafield; diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/aggregate-metrics/110_field_caps.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/aggregate-metrics/110_field_caps.yml new file mode 100644 index 0000000000000..29fc5226c4cda --- /dev/null +++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/aggregate-metrics/110_field_caps.yml @@ -0,0 +1,159 @@ +setup: + - skip: + version: " - 8.4.99" + reason: metric params only on time series indices introduced in 8.5.0 + + - do: + indices.create: + index: test_rollup + body: + settings: + index: + number_of_replicas: 0 + number_of_shards: 2 + mode: time_series + routing_path: [ metricset, k8s.pod.uid ] + time_series: + start_time: 2021-04-28T00:00:00Z + end_time: 2021-04-29T00:00:00Z + mappings: + properties: + "@timestamp": + type: date + metricset: + type: keyword + time_series_dimension: true + metric: + type: aggregate_metric_double + metrics: [ min, max, sum, value_count ] + default_metric: max + time_series_metric: gauge + + - do: + indices.create: + index: test_time_series + body: + settings: + index: + number_of_replicas: 0 + number_of_shards: 2 + mode: time_series + routing_path: [ metricset, k8s.pod.uid ] + time_series: + start_time: 2021-04-28T00:00:00Z + end_time: 2021-04-29T00:00:00Z + mappings: + properties: + "@timestamp": + type: date + metricset: + type: keyword + time_series_dimension: true + metric: + type: double + time_series_metric: gauge + + - do: + indices.create: + index: test_non_time_series + body: + settings: + index: + number_of_replicas: 0 + number_of_shards: 2 + mappings: + properties: + "@timestamp": + type: date + metricset: + type: keyword + time_series_dimension: true + metric: + type: double + time_series_metric: gauge + + +--- +# Test field_caps on a rollup index +field caps on rollup indices: + - skip: + version: " - 8.4.99" + reason: metric params only on time series indices introduced in 8.5.0 + + - do: + field_caps: + index: test_rollup + fields: [ metric ] + + - match: { fields.metric.aggregate_metric_double.type: aggregate_metric_double } + - match: { fields.metric.aggregate_metric_double.searchable: true } + - match: { fields.metric.aggregate_metric_double.aggregatable: true } + - match: { fields.metric.aggregate_metric_double.time_series_metric: gauge } + - is_false: fields.metric.aggregate_metric_double.indices + - is_false: fields.metric.aggregate_metric_double.non_searchable_indices + - is_false: fields.metric.aggregate_metric_double.non_aggregatable_indices + - is_false: fields.metric.aggregate_metric_double.metric_conflicts_indices + - is_false: fields.metric.double + + +--- +# Test field_caps on time-series index (mix of raw and rollup indices) +field caps on time series indices: + - skip: + version: " - 8.4.99" + reason: metric params only on time series indices introduced in 8.5.0 + + - do: + field_caps: + index: [ test_time_series, test_rollup ] + fields: [ metric ] + + - match: { fields.metric.double.type: double } + - match: { fields.metric.double.searchable: true } + - match: { fields.metric.double.aggregatable: true } + - match: { fields.metric.double.time_series_metric: gauge } + - match: { fields.metric.double.indices: [ "test_time_series" ] } + - is_false: fields.metric.double.non_searchable_indices + - is_false: fields.metric.double.non_aggregatable_indices + - is_false: fields.metric.double.metric_conflicts_indices + + - match: { fields.metric.aggregate_metric_double.type: aggregate_metric_double } + - match: { fields.metric.aggregate_metric_double.searchable: true } + - match: { fields.metric.aggregate_metric_double.aggregatable: true } + - match: { fields.metric.aggregate_metric_double.time_series_metric: gauge } + - match: { fields.metric.aggregate_metric_double.indices: [ "test_rollup" ] } + + - is_false: fields.metric.aggregate_metric_double.non_searchable_indices + - is_false: fields.metric.aggregate_metric_double.non_aggregatable_indices + - is_false: fields.metric.aggregate_metric_double.metric_conflicts_indices + +--- +# Test field_caps on mixed standard and time-series (mix of raw and rollup) indices +field caps on all indices: + - skip: + version: " - 8.4.99" + reason: metric params only on time series indices introduced in 8.5.0 + + - do: + field_caps: + index: [ test_time_series, test_rollup, test_non_time_series ] + fields: [ metric ] + + - match: { fields.metric.double.type: double } + - match: { fields.metric.double.searchable: true } + - match: { fields.metric.double.aggregatable: true } + - match: { fields.metric.double.indices: [ "test_non_time_series", "test_time_series" ] } + - match: { fields.metric.double.metric_conflicts_indices: [ "test_non_time_series", "test_time_series" ] } + - is_false: fields.metric.double.non_searchable_indices + - is_false: fields.metric.double.non_aggregatable_indices + - is_false: fields.metric.double.time_series_metric + + - match: { fields.metric.aggregate_metric_double.type: aggregate_metric_double } + - match: { fields.metric.aggregate_metric_double.searchable: true } + - match: { fields.metric.aggregate_metric_double.aggregatable: true } + - match: { fields.metric.aggregate_metric_double.time_series_metric: gauge } + - match: { fields.metric.aggregate_metric_double.indices: [ "test_rollup" ] } + + - is_false: fields.metric.aggregate_metric_double.non_searchable_indices + - is_false: fields.metric.aggregate_metric_double.non_aggregatable_indices + - is_false: fields.metric.aggregate_metric_double.metric_conflicts_indices