Overview
This article introduces Elasticsearch aggregation analysis function, including complete usage of Metrics Aggregations and Bucket Aggregations.
Aggregation Syntax
"aggregations" : {
"<aggregation_name>" : {
"<aggregation_type>" : {
<aggregation_body>
}
[,"aggregations" : { [<sub_aggregation>]+ } ]?
}
}
Note: aggregations can be abbreviated as aggs
1. Metrics Aggregations
1. Basic Statistics Types
| Type | Description |
|---|---|
| avg | Calculate average |
| sum | Calculate sum |
| min | Minimum |
| max | Maximum |
| value_count | Count |
| cardinality | Distinct count |
| stats | Return min/max/avg/count/sum |
| extended_stats | Extended statistics (including standard deviation, etc.) |
2. Example: Query Max Value
POST /book/_search
{
"size": 0,
"aggs": {
"max_price": {
"max": {
"field": "price"
}
}
}
}
3. Example: Conditional Query Count
POST /book/_count
{
"query": {
"range": {
"price" : {
"gt": 100
}
}
}
}
4. Example: Count Documents with Values
POST /book/_search
{
"size": 0,
"aggs": {
"book_nums": {
"value_count": {
"field": "price"
}
}
}
}
5. Example: Distinct Count
POST /book/_search?size=0
{
"aggs": {
"price_count": {
"cardinality": {
"field": "price"
}
}
}
}
6. Example: Stats Statistics
POST /book/_search?size=0
{
"aggs": {
"price_stats": {
"stats": {
"field": "price"
}
}
}
}
7. Example: Extended Stats
POST /book/_search?size=0
{
"aggs": {
"price_stats": {
"extended_stats": {
"field": "price"
}
}
}
}
Returns: Sum of squares, variance, standard deviation, average ± 2 standard deviation range
8. Example: Percentiles
POST /book/_search?size=0
{
"aggs": {
"price_percents": {
"percentiles": {
"field": "price",
"percents" : [75, 99, 99.9]
}
}
}
}
9. Example: Percentile Ranks
POST /book/_search?size=0
{
"aggs": {
"gge_perc_rank": {
"percentile_ranks": {
"field": "price",
"values": [100, 200]
}
}
}
}
2. Bucket Aggregations
1. Common Bucket Aggregation Types
| Type | Description |
|---|---|
| terms | Group by field value (similar to GROUP BY) |
| range | Group by numeric range |
| date_histogram | Group by time interval |
| histogram | Group by numeric interval |
| filter | Group by condition |
| filters | Multi-condition grouping |
| geo_distance | Group by geographic location distance |
2. Example: Range Group + Nested Aggregation
POST /book/_search
{
"size": 0,
"aggs": {
"group_by_price": {
"range": {
"field": "price",
"ranges": [
{"from": 0, "to": 200},
{"from": 200, "to": 400},
{"from": 400, "to": 1000}
]
},
"aggs": {
"average_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
3. Example: Implement HAVING Effect (bucket_selector)
POST /book/_search
{
"size": 0,
"aggs": {
"group_by_price": {
"range": {
"field": "price",
"ranges": [
{"from": 0, "to": 200},
{"from": 200, "to": 400},
{"from": 400, "to": 1000}
]
},
"aggs": {
"average_price": {
"avg": {
"field": "price"
}
},
"having": {
"bucket_selector": {
"buckets_path": {
"avg_price": "average_price"
},
"script": {
"source": "params.avg_price >= 200"
}
}
}
}
}
}
}
3. Common Error Quick Reference
| Symptom | Root Cause | Solution |
|---|---|---|
| Fielddata is disabled on text fields | Aggregate on text field | Use .keyword field |
| Aggregation result empty | Field doesn’t exist or is null | Use exists query to confirm, supplement data |
| cardinality deviation large | precision_threshold low | Increase parameter value |
| too_many_buckets_exception | Too many buckets | Limit size, increase shard_size |
Summary
Reasonably combining Metrics Aggregations and Bucket Aggregations can complete statistics, grouping, filtering and HAVING-like logic in one query, applicable to log analysis, report statistics, operations dashboard and other scenarios.