diff --git a/core/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java b/core/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java index 856f878592d..8913fc637bb 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/search/RestMultiSearchAction.java @@ -39,7 +39,9 @@ import org.elasticsearch.rest.action.RestToXContentListener; import org.elasticsearch.search.builder.SearchSourceBuilder; import java.io.IOException; +import java.util.Collections; import java.util.Map; +import java.util.Set; import java.util.function.BiConsumer; import static org.elasticsearch.common.xcontent.support.XContentMapValues.nodeBooleanValue; @@ -50,6 +52,8 @@ import static org.elasticsearch.rest.RestRequest.Method.POST; public class RestMultiSearchAction extends BaseRestHandler { + private static final Set RESPONSE_PARAMS = Collections.singleton("typed_keys"); + private final boolean allowExplicitIndex; public RestMultiSearchAction(Settings settings, RestController controller) { @@ -199,4 +203,9 @@ public class RestMultiSearchAction extends BaseRestHandler { } return -1; } + + @Override + protected Set responseParams() { + return RESPONSE_PARAMS; + } } diff --git a/core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java b/core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java index 983f1b6dd55..fe2522f31d4 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/search/RestSearchAction.java @@ -44,6 +44,8 @@ import org.elasticsearch.search.suggest.term.TermSuggestionBuilder.SuggestMode; import java.io.IOException; import java.util.Arrays; +import java.util.Collections; +import java.util.Set; import static org.elasticsearch.common.unit.TimeValue.parseTimeValue; import static org.elasticsearch.rest.RestRequest.Method.GET; @@ -51,6 +53,9 @@ import static org.elasticsearch.rest.RestRequest.Method.POST; import static org.elasticsearch.search.suggest.SuggestBuilders.termSuggestion; public class RestSearchAction extends BaseRestHandler { + + private static final Set RESPONSE_PARAMS = Collections.singleton("typed_keys"); + public RestSearchAction(Settings settings, RestController controller) { super(settings); controller.registerHandler(GET, "/_search", this); @@ -219,4 +224,9 @@ public class RestSearchAction extends BaseRestHandler { .suggestMode(SuggestMode.resolve(suggestMode)))); } } + + @Override + protected Set responseParams() { + return RESPONSE_PARAMS; + } } diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/InternalAggregation.java b/core/src/main/java/org/elasticsearch/search/aggregations/InternalAggregation.java index 752b3497a92..6dfd6fcc79f 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/InternalAggregation.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/InternalAggregation.java @@ -38,6 +38,10 @@ import java.util.Objects; * An internal implementation of {@link Aggregation}. Serves as a base class for all aggregation implementations. */ public abstract class InternalAggregation implements Aggregation, ToXContent, NamedWriteable { + + /** Delimiter used when prefixing aggregation names with their type using the typed_keys parameter **/ + public static final String TYPED_KEYS_DELIMITER = "#"; + public static class ReduceContext { private final BigArrays bigArrays; @@ -149,8 +153,19 @@ public abstract class InternalAggregation implements Aggregation, ToXContent, Na return pipelineAggregators; } + /** + * Returns a string representing the type of the aggregation. This type is added to + * the aggregation name in the response, so that it can later be used by REST clients + * to determine the internal type of the aggregation. + */ + protected String getType() { + return getWriteableName(); + } + @Override public final XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + // Concatenates the type and the name of the aggregation (ex: top_hits#foo) + String name = params.paramAsBoolean("typed_keys", false) ? String.join(TYPED_KEYS_DELIMITER, getType(), getName()) : getName(); builder.startObject(name); if (this.metaData != null) { builder.field(CommonFields.META); diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSampler.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSampler.java index 224de07e93d..e4473f9a517 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSampler.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/sampler/InternalSampler.java @@ -45,6 +45,11 @@ public class InternalSampler extends InternalSingleBucketAggregation implements return NAME; } + @Override + protected String getType() { + return "sampler"; + } + @Override protected InternalSingleBucketAggregation newAggregation(String name, long docCount, InternalAggregations subAggregations) { diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/UnmappedSignificantTerms.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/UnmappedSignificantTerms.java index 1a1094e62b4..e0b38140c43 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/UnmappedSignificantTerms.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/significant/UnmappedSignificantTerms.java @@ -75,6 +75,11 @@ public class UnmappedSignificantTerms extends InternalSignificantTerms buckets) { return new UnmappedSignificantTerms(name, requiredSize, minDocCount, pipelineAggregators(), metaData); diff --git a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/UnmappedTerms.java b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/UnmappedTerms.java index c3d1a8937c4..2613fc4159a 100644 --- a/core/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/UnmappedTerms.java +++ b/core/src/main/java/org/elasticsearch/search/aggregations/bucket/terms/UnmappedTerms.java @@ -71,6 +71,11 @@ public class UnmappedTerms extends InternalTerms buckets) { return new UnmappedTerms(name, order, requiredSize, minDocCount, pipelineAggregators(), metaData); diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SignificantTermsSignificanceScoreIT.java b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SignificantTermsSignificanceScoreIT.java index 4a8c88b3093..7fc20908e81 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SignificantTermsSignificanceScoreIT.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/bucket/SignificantTermsSignificanceScoreIT.java @@ -23,6 +23,7 @@ import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentType; @@ -268,7 +269,7 @@ public class SignificantTermsSignificanceScoreIT extends ESIntegTestCase { XContentBuilder responseBuilder = XContentFactory.jsonBuilder(); responseBuilder.startObject(); - classes.toXContent(responseBuilder, null); + classes.toXContent(responseBuilder, ToXContent.EMPTY_PARAMS); responseBuilder.endObject(); String result = "{\"class\":{\"doc_count_error_upper_bound\":0,\"sum_other_doc_count\":0," diff --git a/docs/reference/aggregations/misc.asciidoc b/docs/reference/aggregations/misc.asciidoc index 7210daf1417..a3d9f61671a 100644 --- a/docs/reference/aggregations/misc.asciidoc +++ b/docs/reference/aggregations/misc.asciidoc @@ -82,3 +82,89 @@ Then that piece of metadata will be returned in place for our `titles` terms agg } -------------------------------------------------- // TESTRESPONSE[s/\.\.\./"took": "$body.took", "timed_out": false, "_shards": "$body._shards", "hits": "$body.hits"/] + + +[[returning-aggregation-type]] +== Returning the type of the aggregation + +Sometimes you need to know the exact type of an aggregation in order to parse its results. The `typed_keys` parameter + can be used to change the aggregation's name in the response so that it will be prefixed by its internal type. + +Considering the following <> named +`tweets_over_time` which has a sub <> named + `top_users`: + +[source,js] +-------------------------------------------------- +GET /twitter/tweet/_search?typed_keys +{ + "aggregations": { + "tweets_over_time": { + "date_histogram": { + "field": "date", + "interval": "year" + }, + "aggregations": { + "top_users": { + "top_hits": { + "size": 1 + } + } + } + } + } +} +-------------------------------------------------- +// CONSOLE +// TEST[setup:twitter] + +In the response, the aggregations names will be changed to respectively `date_histogram:tweets_over_time` and +`top_hits:top_users`, reflecting the internal types of each aggregation: + +[source,js] +-------------------------------------------------- +{ + "aggregations": { + "date_histogram#tweets_over_time": { <1> + "buckets" : [ + { + "key_as_string" : "2009-01-01T00:00:00.000Z", + "key" : 1230768000000, + "doc_count" : 5, + "top_hits#top_users" : { <2> + "hits" : { + "total" : 5, + "max_score" : 1.0, + "hits" : [ + { + "_index": "twitter", + "_type": "tweet", + "_id": "0", + "_score": 1.0, + "_source": { + "date": "2009-11-15T14:12:12", + "message": "trying out Elasticsearch", + "user": "kimchy", + "likes": 0 + } + } + ] + } + } + } + ] + } + }, + ... +} +-------------------------------------------------- +// TESTRESPONSE[s/\.\.\./"took": "$body.took", "timed_out": false, "_shards": "$body._shards", "hits": "$body.hits"/] + +<1> The name `tweets_over_time` now contains the `date_histogram` prefix. +<2> The name `top_users` now contains the `top_hits` prefix. + +NOTE: For some aggregations, it is possible that the returned type is not the same as the one provided with the +request. This is the case for Terms, Significant Terms and Percentiles aggregations, where the returned type +also contains information about the type of the targeted field: `lterms` (for a terms aggregation on a Long field), + `sigsterms` (for a significant terms aggregation on a String field), `tdigest_percentiles` (for a percentile + aggregation based on the TDigest algorithm). diff --git a/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/RestMultiSearchTemplateAction.java b/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/RestMultiSearchTemplateAction.java index 30b18edb71b..835eea7fbf5 100644 --- a/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/RestMultiSearchTemplateAction.java +++ b/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/RestMultiSearchTemplateAction.java @@ -30,12 +30,16 @@ import org.elasticsearch.rest.action.RestToXContentListener; import org.elasticsearch.rest.action.search.RestMultiSearchAction; import java.io.IOException; +import java.util.Collections; +import java.util.Set; import static org.elasticsearch.rest.RestRequest.Method.GET; import static org.elasticsearch.rest.RestRequest.Method.POST; public class RestMultiSearchTemplateAction extends BaseRestHandler { + private static final Set RESPONSE_PARAMS = Collections.singleton("typed_keys"); + private final boolean allowExplicitIndex; public RestMultiSearchTemplateAction(Settings settings, RestController controller) { @@ -86,4 +90,9 @@ public class RestMultiSearchTemplateAction extends BaseRestHandler { public boolean supportsContentStream() { return true; } + + @Override + protected Set responseParams() { + return RESPONSE_PARAMS; + } } diff --git a/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/RestSearchTemplateAction.java b/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/RestSearchTemplateAction.java index bb263dd5a26..f1c1b15b2fa 100644 --- a/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/RestSearchTemplateAction.java +++ b/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/RestSearchTemplateAction.java @@ -37,12 +37,16 @@ import org.elasticsearch.rest.action.search.RestSearchAction; import org.elasticsearch.script.ScriptType; import java.io.IOException; +import java.util.Collections; +import java.util.Set; import static org.elasticsearch.rest.RestRequest.Method.GET; import static org.elasticsearch.rest.RestRequest.Method.POST; public class RestSearchTemplateAction extends BaseRestHandler { + private static final Set RESPONSE_PARAMS = Collections.singleton("typed_keys"); + private static final ObjectParser PARSER; static { PARSER = new ObjectParser<>("search_template"); @@ -107,4 +111,9 @@ public class RestSearchTemplateAction extends BaseRestHandler { public static SearchTemplateRequest parse(XContentParser parser) throws IOException { return PARSER.parse(parser, new SearchTemplateRequest(), null); } + + @Override + protected Set responseParams() { + return RESPONSE_PARAMS; + } } diff --git a/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/60_typed_keys.yaml b/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/60_typed_keys.yaml new file mode 100644 index 00000000000..df9a42f87d5 --- /dev/null +++ b/modules/lang-mustache/src/test/resources/rest-api-spec/test/lang_mustache/60_typed_keys.yaml @@ -0,0 +1,119 @@ +setup: + - do: + indices.put_template: + name: index_template + body: + index_patterns: test-* + settings: + number_of_replicas: 0 + mappings: + user: + properties: + ip: + type: ip + integer: + type: integer + float: + type: float + name: + type: keyword + + - do: + bulk: + refresh: true + body: + - '{"index": {"_index": "test-0", "_type": "user"}}' + - '{"ip": "10.0.0.1", "integer": 38, "float": 12.5713, "name": "Ruth", "bool": true}' + - '{"index": {"_index": "test-0", "_type": "user"}}' + - '{"ip": "10.0.0.2", "integer": 42, "float": 15.3393, "name": "Jackie", "surname": "Bowling", "bool": false}' + - '{"index": {"_index": "test-1", "_type": "user"}}' + - '{"ip": "10.0.0.3", "integer": 29, "float": 19.0517, "name": "Stephanie", "bool": true}' + - '{"index": {"_index": "test-1", "_type": "user"}}' + - '{"ip": "10.0.0.4", "integer": 19, "float": 19.3717, "surname": "Hamilton", "bool": true}' + - '{"index": {"_index": "test-2", "_type": "user"}}' + - '{"ip": "10.0.0.5", "integer": 0, "float": 17.3349, "name": "Natalie", "bool": false}' + +--- +"Search template with typed_keys parameter": + + - do: + put_template: + id: template_1 + body: + template: + query: + match: + bool: "{{bool_value}}" + aggs: + test_missing: + missing: + field: "{{missing_field}}" + + - match: { acknowledged: true } + + - do: + search_template: + index: test-* + typed_keys: true + body: + id: template_1 + params: + bool_value: true + missing_field: name + + - match: { hits.total: 3 } + - match: { aggregations.missing#test_missing.doc_count: 1 } + +--- +"Multisearch template with typed_keys parameter": + + - do: + put_template: + id: registered_template + body: + template: + query: + range: + integer: + gte: "{{starting_value}}" + aggs: + test_histogram: + histogram: + field: "{{histo.field}}" + interval: "{{histo.interval}}" + + - match: { acknowledged: true } + + - do: + msearch_template: + typed_keys: true + body: + - index: test-* + - inline: + query: + match: + name: "{{name_value}}" + aggs: + test_global: + global: {} + aggs: + test_ip_range: + ip_range: + field: "{{ip_field}}" + ranges: + to: "10.0.0.6" + params: + name_value: "Stephanie" + ip_field: "ip" + - index: test-0,test-1 + - id: registered_template + params: + starting_value: 30 + histo: + field: float + interval: 5 + - match: { responses.0.hits.total: 1 } + - match: { responses.0.aggregations.global#test_global.doc_count: 5 } + - match: { responses.0.aggregations.global#test_global.ip_range#test_ip_range.buckets.0.doc_count: 5 } + - match: { responses.1.hits.total: 2 } + - match: { responses.1.aggregations.histogram#test_histogram.buckets.0.doc_count: 1 } diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/msearch.json b/rest-api-spec/src/main/resources/rest-api-spec/api/msearch.json index 0344702ecfe..87d5604cff1 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/msearch.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/msearch.json @@ -24,6 +24,10 @@ "max_concurrent_searches" : { "type" : "number", "description" : "Controls the maximum number of concurrent searches the multi search api will execute" + }, + "typed_keys": { + "type" : "boolean", + "description" : "Specify whether aggregation names should be prefixed by their respective types in the response" } } }, diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/msearch_template.json b/rest-api-spec/src/main/resources/rest-api-spec/api/msearch_template.json index 57e0e189668..b6254f4a5dd 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/msearch_template.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/msearch_template.json @@ -20,6 +20,10 @@ "type" : "enum", "options" : ["query_then_fetch", "query_and_fetch", "dfs_query_then_fetch", "dfs_query_and_fetch"], "description" : "Search operation type" + }, + "typed_keys": { + "type" : "boolean", + "description" : "Specify whether aggregation names should be prefixed by their respective types in the response" } } }, diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/search.json b/rest-api-spec/src/main/resources/rest-api-spec/api/search.json index 2cf359ede16..1807d252364 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/search.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/search.json @@ -147,6 +147,10 @@ "type" : "boolean", "description": "Whether to calculate and return scores even if they are not used for sorting" }, + "typed_keys": { + "type" : "boolean", + "description" : "Specify whether aggregation names should be prefixed by their respective types in the response" + }, "version": { "type" : "boolean", "description" : "Specify whether to return document version as part of a hit" diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/search_template.json b/rest-api-spec/src/main/resources/rest-api-spec/api/search_template.json index b9339b55332..904027623b6 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/search_template.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/search_template.json @@ -54,6 +54,10 @@ "profile": { "type" : "boolean", "description" : "Specify whether to profile the query execution" + }, + "typed_keys": { + "type" : "boolean", + "description" : "Specify whether aggregation names should be prefixed by their respective types in the response" } } }, diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/msearch/20_typed_keys.yaml b/rest-api-spec/src/main/resources/rest-api-spec/test/msearch/20_typed_keys.yaml new file mode 100644 index 00000000000..7f0fad201fc --- /dev/null +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/msearch/20_typed_keys.yaml @@ -0,0 +1,83 @@ +setup: + - skip: + version: " - 5.3.99" + reason: typed_keys parameter was added in 5.4.0 + + - do: + indices.put_template: + name: index_template + body: + index_patterns: test-* + settings: + number_of_replicas: 0 + mappings: + user: + properties: + index_start_at: + type: integer + integer: + type: integer + float: + type: float + name: + type: keyword + + - do: + bulk: + refresh: true + body: + - '{"index": {"_index": "test-0", "_type": "user"}}' + - '{"row": 1, "index_start_at": 56, "integer": 38, "float": 12.5713, "name": "Ruth", "bool": true}' + - '{"index": {"_index": "test-0", "_type": "user"}}' + - '{"row": 2, "index_start_at": 57, "integer": 42, "float": 15.3393, "name": "Jackie", "surname": "Bowling", "bool": false}' + - '{"index": {"_index": "test-1", "_type": "user"}}' + - '{"row": 3, "index_start_at": 58, "integer": 29, "float": 19.0517, "name": "Stephanie", "bool": true}' + - '{"index": {"_index": "test-1", "_type": "user"}}' + - '{"row": 4, "index_start_at": 59, "integer": 19, "float": 19.3717, "surname": "Hamilton", "bool": true}' + - '{"index": {"_index": "test-2", "_type": "user"}}' + - '{"row": 5, "index_start_at": 60, "integer": 0, "float": 17.3349, "name": "Natalie", "bool": false}' + +--- +"Multisearch test with typed_keys parameter": + - do: + msearch: + typed_keys: true + body: + - index: test-* + - {query: {match: {bool: true} }, size: 0, aggs: {test_filter: {filter: {range:{integer: {gte: 20} } } } } } + - index: test-1 + - {query: {match_all: {} }, size: 0, aggs: {test_range: {range: {field: float, ranges: [ {to: 19.2499999}, {from: 19.25} ] } } } } + - index: test-* + - {query: {bool: {filter: {range: {row: {lt: 5}}} } }, size: 0, aggs: {test_percentiles: {percentiles: {field: float} } } } + + - match: { responses.0.hits.total: 3 } + - match: { responses.0.aggregations.filter#test_filter.doc_count : 2 } + - match: { responses.1.hits.total: 2 } + - match: { responses.1.aggregations.range#test_range.buckets.0.key : "*-19.2499999" } + - match: { responses.1.aggregations.range#test_range.buckets.0.doc_count : 1 } + - match: { responses.1.aggregations.range#test_range.buckets.1.key : "19.25-*" } + - match: { responses.1.aggregations.range#test_range.buckets.1.doc_count : 1 } + - match: { responses.2.hits.total: 4 } + - is_true: responses.2.aggregations.tdigest_percentiles#test_percentiles.values + +--- +"Multisearch test with typed_keys parameter for sampler and significant terms": + - do: + msearch: + typed_keys: true + body: + - index: test-* + - {query: {match_all: {} }, size: 0, aggs: {test_sampler: {sampler: {shard_size: 200}, aggs: {test_significant_terms: {significant_terms: {field: name} } } } } } + - index: test-* + - {query: {match_all: {} }, size: 0, aggs: {test_umterms: {terms: {field: surname} } } } + - index: test-* + - {query: {match_all: {} }, size: 0, aggs: {test_sterms: {terms: {field: name}, aggs: {test_umsignificant_terms: {significant_terms: {field: surname} } } } } } + + - match: { responses.0.hits.total: 5 } + - match: { responses.0.aggregations.sampler#test_sampler.doc_count : 5 } + - match: { responses.0.aggregations.sampler#test_sampler.sigsterms#test_significant_terms.doc_count : 5 } + - match: { responses.1.hits.total: 1 } + - match: { responses.1.aggregations.sterms#test_umterms.doc_count_error_upper_bound : 0 } + - match: { responses.2.hits.total: 1 } + - match: { responses.2.aggregations.sterms#test_sterms.doc_count_error_upper_bound : 0 } + - is_true: responses.2.aggregations.sterms#test_sterms.buckets.0.sigsterms#test_umsignificant_terms diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/80_typed_keys.yaml b/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/80_typed_keys.yaml new file mode 100644 index 00000000000..9ea856c856e --- /dev/null +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/search.aggregation/80_typed_keys.yaml @@ -0,0 +1,226 @@ +setup: + - skip: + version: " - 5.3.99" + reason: typed_keys parameter was added in 5.4.0 + + - do: + indices.create: + index: test + body: + settings: + number_of_replicas: 0 + mappings: + test: + properties: + name: + type: keyword + num: + type: integer + created: + type: date + + - do: + bulk: + refresh: true + index: test + type: test + body: + - '{"index": {}}' + - '{"name": "one", "num": 1, "created": "2010-03-12T01:07:45"}' + - '{"index": {}}' + - '{"name": "two", "num": 2, "created": "2010-03-12T04:11:00"}' + - '{"index": {}}' + - '{"name": "three", "num": 3, "created": "2010-04-27T03:43:34"}' + +--- +"Test typed keys parameter for avg aggregation": + - do: + search: + typed_keys: true + body: + size: 0 + aggregations: + test_avg: + avg: + field: num + - is_true: aggregations.avg#test_avg + +--- +"Test typed keys parameter for cardinality aggregation": + - do: + search: + typed_keys: true + body: + size: 0 + aggregations: + test_cardinality: + cardinality: + field: name + - is_true: aggregations.cardinality#test_cardinality + +--- +"Test typed keys parameter for extended_stats aggregation": + - do: + search: + typed_keys: true + body: + size: 0 + aggregations: + test_extended_stats: + extended_stats: + field: num + - is_true: aggregations.extended_stats#test_extended_stats + +--- +"Test typed keys parameter for max aggregation": + - do: + search: + typed_keys: true + body: + size: 0 + aggregations: + test_max: + max: + field: num + - is_true: aggregations.max#test_max + +--- +"Test typed keys parameter for min aggregation": + - do: + search: + typed_keys: true + body: + size: 0 + aggregations: + test_min: + min: + field: num + - is_true: aggregations.min#test_min + +--- +"Test typed keys parameter for percentiles aggregation": + - do: + search: + typed_keys: true + body: + size: 0 + aggregations: + test_percentiles: + percentiles: + field: num + - is_true: aggregations.tdigest_percentiles#test_percentiles + +--- +"Test typed keys parameter for percentile_ranks aggregation": + - do: + search: + typed_keys: true + body: + size: 0 + aggregations: + test_percentile_ranks: + percentile_ranks: + field: num + values: [0,10] + - is_true: aggregations.tdigest_percentile_ranks#test_percentile_ranks + +--- +"Test typed keys parameter for stats aggregation": + - do: + search: + typed_keys: true + body: + size: 0 + aggregations: + test_stats: + stats: + field: num + - is_true: aggregations.stats#test_stats + +--- +"Test typed keys parameter for sum aggregation": + - do: + search: + typed_keys: true + body: + size: 0 + aggregations: + test_sum: + sum: + field: num + - is_true: aggregations.sum#test_sum + +--- +"Test typed keys parameter for terms and top_hits aggregation": + - do: + search: + typed_keys: true + body: + size: 0 + aggregations: + test_terms: + terms: + field: name + aggs: + test_top_hits: + top_hits: + sort: num + - is_true: aggregations.sterms#test_terms + - is_true: aggregations.sterms#test_terms.buckets.0.top_hits#test_top_hits + - is_true: aggregations.sterms#test_terms.buckets.1.top_hits#test_top_hits + - is_true: aggregations.sterms#test_terms.buckets.2.top_hits#test_top_hits + +--- +"Test typed keys parameter for terms aggregation": + - do: + search: + typed_keys: true + body: + size: 0 + aggregations: + test_terms: + terms: + field: num + - is_true: aggregations.lterms#test_terms + +--- +"Test typed keys parameter for value_count aggregation": + - do: + search: + typed_keys: true + body: + size: 0 + aggregations: + test_value_count: + value_count: + field: num + - is_true: aggregations.value_count#test_value_count + +--- +"Test typed keys parameter for date_histogram aggregation and max_bucket pipeline aggregation": + - do: + search: + typed_keys: true + body: + size: 0 + aggregations: + test_created_histogram: + date_histogram: + field: created + interval: month + aggregations: + test_sum: + sum: + field: num + test_moving_avg: + moving_avg: + buckets_path: "test_sum" + test_max_bucket: + max_bucket: + buckets_path: "test_created_histogram>test_sum" + + - is_true: aggregations.date_histogram#test_created_histogram + - is_true: aggregations.date_histogram#test_created_histogram.buckets.0.sum#test_sum + - is_true: aggregations.date_histogram#test_created_histogram.buckets.1.sum#test_sum + - is_true: aggregations.date_histogram#test_created_histogram.buckets.1.simple_value#test_moving_avg + - is_true: aggregations.bucket_metric_value#test_max_bucket