Range aggregation
editRange aggregation
editA multi-bucket value source based aggregation that enables the user to define a set of ranges - each representing a bucket. During the aggregation process, the values extracted from each document will be checked against each bucket range and "bucket" the relevant/matching document.
Note that this aggregation includes the from
value and excludes the to
value for each range.
Example:
GET /_search { "aggs": { "price_ranges": { "range": { "field": "price", "ranges": [ { "to": 100.0 }, { "from": 100.0, "to": 200.0 }, { "from": 200.0 } ] } } } }
Response:
{ ... "aggregations": { "price_ranges": { "buckets": [ { "key": "*-100.0", "to": 100.0, "doc_count": 2 }, { "key": "100.0-200.0", "from": 100.0, "to": 200.0, "doc_count": 2 }, { "key": "200.0-*", "from": 200.0, "doc_count": 3 } ] } } }
Keyed Response
editSetting the keyed
flag to true
will associate a unique string key with each bucket and return the ranges as a hash rather than an array:
GET /_search { "aggs": { "price_ranges": { "range": { "field": "price", "keyed": true, "ranges": [ { "to": 100 }, { "from": 100, "to": 200 }, { "from": 200 } ] } } } }
Response:
{ ... "aggregations": { "price_ranges": { "buckets": { "*-100.0": { "to": 100.0, "doc_count": 2 }, "100.0-200.0": { "from": 100.0, "to": 200.0, "doc_count": 2 }, "200.0-*": { "from": 200.0, "doc_count": 3 } } } } }
It is also possible to customize the key for each range:
GET /_search { "aggs": { "price_ranges": { "range": { "field": "price", "keyed": true, "ranges": [ { "key": "cheap", "to": 100 }, { "key": "average", "from": 100, "to": 200 }, { "key": "expensive", "from": 200 } ] } } } }
Response:
{ ... "aggregations": { "price_ranges": { "buckets": { "cheap": { "to": 100.0, "doc_count": 2 }, "average": { "from": 100.0, "to": 200.0, "doc_count": 2 }, "expensive": { "from": 200.0, "doc_count": 3 } } } } }
Script
editIf the data in your documents doesn’t exactly match what you’d like to aggregate, use a runtime field. For example, if you need to apply a particular currency conversion rate:
GET /_search { "runtime_mappings": { "price.euros": { "type": "double", "script": { "source": """ emit(doc['price'].value * params.conversion_rate) """, "params": { "conversion_rate": 0.835526591 } } } }, "aggs": { "price_ranges": { "range": { "field": "price.euros", "ranges": [ { "to": 100 }, { "from": 100, "to": 200 }, { "from": 200 } ] } } } }
Sub Aggregations
editThe following example, not only "bucket" the documents to the different buckets but also computes statistics over the prices in each price range
GET /_search { "aggs": { "price_ranges": { "range": { "field": "price", "ranges": [ { "to": 100 }, { "from": 100, "to": 200 }, { "from": 200 } ] }, "aggs": { "price_stats": { "stats": { "field": "price" } } } } } }
Response:
{ ... "aggregations": { "price_ranges": { "buckets": [ { "key": "*-100.0", "to": 100.0, "doc_count": 2, "price_stats": { "count": 2, "min": 10.0, "max": 50.0, "avg": 30.0, "sum": 60.0 } }, { "key": "100.0-200.0", "from": 100.0, "to": 200.0, "doc_count": 2, "price_stats": { "count": 2, "min": 150.0, "max": 175.0, "avg": 162.5, "sum": 325.0 } }, { "key": "200.0-*", "from": 200.0, "doc_count": 3, "price_stats": { "count": 3, "min": 200.0, "max": 200.0, "avg": 200.0, "sum": 600.0 } } ] } } }