2015-05-05 17:07:32 -04:00
---
layout: doc_page
---
# Post-Aggregations
Post-aggregations are specifications of processing that should happen on aggregated values as they come out of Druid. If you include a post aggregation as part of a query, make sure to include all aggregators the post-aggregator requires.
There are several post-aggregators available.
### Arithmetic post-aggregator
The arithmetic post-aggregator applies the provided function to the given
fields from left to right. The fields can be aggregators or other post aggregators.
Supported functions are `+` , `-` , `*` , `/` , and `quotient` .
**Note**:
* `/` division always returns `0` if dividing by`0`, regardless of the numerator.
* `quotient` division behaves like regular floating point division
Arithmetic post-aggregators may also specify an `ordering` , which defines the order
of resulting values when sorting results (this can be useful for topN queries for instance):
- If no ordering (or `null` ) is specified, the default floating point ordering is used.
- `numericFirst` ordering always returns finite values first, followed by `NaN` , and infinite values last.
The grammar for an arithmetic post aggregation is:
```json
postAggregation : {
"type" : "arithmetic",
"name" : < output_name > ,
"fn" : < arithmetic_function > ,
"fields": [< post_aggregator > , < post_aggregator > , ...],
"ordering" : < null ( default ) , or " numericFirst " >
}
```
2017-08-31 14:45:49 -04:00
### Field accessor post-aggregators
2015-05-05 17:07:32 -04:00
2017-08-31 14:45:49 -04:00
These post-aggregators return the value produced by the specified [aggregator ](../querying/aggregations.html ).
2015-05-05 17:07:32 -04:00
`fieldName` refers to the output name of the aggregator given in the [aggregations ](../querying/aggregations.html ) portion of the query.
2017-08-31 14:45:49 -04:00
For complex aggregators, like "cardinality" and "hyperUnique", the `type` of the post-aggregator determines what
the post-aggregator will return. Use type "fieldAccess" to return the raw aggregation object, or use type
"finalizingFieldAccess" to return a finalized value, such as an estimated cardinality.
2015-05-05 17:07:32 -04:00
```json
2015-08-03 04:26:48 -04:00
{ "type" : "fieldAccess", "name": < output_name > , "fieldName" : < aggregator_name > }
2015-05-05 17:07:32 -04:00
```
2017-08-31 14:45:49 -04:00
or
```json
{ "type" : "finalizingFieldAccess", "name": < output_name > , "fieldName" : < aggregator_name > }
```
2015-05-05 17:07:32 -04:00
### Constant post-aggregator
The constant post-aggregator always returns the specified value.
```json
{ "type" : "constant", "name" : < output_name > , "value" : < numerical_value > }
```
2016-12-07 20:58:23 -05:00
### Greatest / Least post-aggregators
`doubleGreatest` and `longGreatest` computes the maximum of all fields and Double.NEGATIVE_INFINITY.
`doubleLeast` and `longLeast` computes the minimum of all fields and Double.POSITIVE_INFINITY.
The difference between the `doubleMax` aggregator and the `doubleGreatest` post-aggregator is that `doubleMax` returns the highest value of
all rows for one specific column while `doubleGreatest` returns the highest value of multiple columns in one row. These are similar to the
SQL [MAX ](https://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_max ) and
[GREATEST ](shttp://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_greatest ) functions.
Example:
```json
{
"type" : "doubleGreatest",
"name" : < output_name > ,
"fields": [< post_aggregator > , < post_aggregator > , ...]
}
```
2015-05-05 17:07:32 -04:00
### JavaScript post-aggregator
Applies the provided JavaScript function to the given fields. Fields are passed as arguments to the JavaScript function in the given order.
```json
postAggregation : {
"type": "javascript",
"name": < output_name > ,
"fieldNames" : [< aggregator_name > , < aggregator_name > , ...],
"function": < javascript function >
}
```
Example JavaScript aggregator:
```json
{
"type": "javascript",
"name": "absPercent",
"fieldNames": ["delta", "total"],
"function": "function(delta, total) { return 100 * Math.abs(delta) / total; }"
}
```
2016-09-13 16:46:55 -04:00
< div class = "note info" >
2017-02-13 18:11:18 -05:00
JavaScript-based functionality is disabled by default. Please refer to the Druid < a href = "../development/javascript.html" > JavaScript programming guide< / a > for guidelines about using Druid's JavaScript functionality, including instructions on how to enable it.
2016-09-13 16:46:55 -04:00
< / div >
2015-05-05 17:07:32 -04:00
### HyperUnique Cardinality post-aggregator
The hyperUniqueCardinality post aggregator is used to wrap a hyperUnique object such that it can be used in post aggregations.
```json
2017-08-28 17:52:11 -04:00
{
"type" : "hyperUniqueCardinality",
"name": < output name > ,
"fieldName" : < the name field value of the hyperUnique aggregator >
}
2015-05-05 17:07:32 -04:00
```
It can be used in a sample calculation as so:
```json
"aggregations" : [{
{"type" : "count", "name" : "rows"},
{"type" : "hyperUnique", "name" : "unique_users", "fieldName" : "uniques"}
}],
2015-07-02 14:37:23 -04:00
"postAggregations" : [{
2015-05-05 17:07:32 -04:00
"type" : "arithmetic",
"name" : "average_users_per_row",
"fn" : "/",
"fields" : [
{ "type" : "hyperUniqueCardinality", "fieldName" : "unique_users" },
{ "type" : "fieldAccess", "name" : "rows", "fieldName" : "rows" }
]
2015-07-02 14:37:23 -04:00
}]
2015-05-05 17:07:32 -04:00
```
2017-08-28 17:52:11 -04:00
This post-aggregator will inherit the rounding behavior of the aggregator it references. Note that this inheritance
is only effective if you directly reference an aggregator. Going through another post-aggregator, for example, will
cause the user-specified rounding behavior to get lost and default to "no rounding".
2016-02-04 14:53:09 -05:00
## Example Usage
2015-05-05 17:07:32 -04:00
In this example, let’ s calculate a simple percentage using post aggregators. Let’ s imagine our data set has a metric called "total".
The format of the query JSON is as follows:
```json
{
...
"aggregations" : [
{ "type" : "count", "name" : "rows" },
{ "type" : "doubleSum", "name" : "tot", "fieldName" : "total" }
],
2015-07-02 14:37:23 -04:00
"postAggregations" : [{
2015-05-05 17:07:32 -04:00
"type" : "arithmetic",
"name" : "average",
"fn" : "*",
"fields" : [
{ "type" : "arithmetic",
"name" : "div",
"fn" : "/",
"fields" : [
{ "type" : "fieldAccess", "name" : "tot", "fieldName" : "tot" },
{ "type" : "fieldAccess", "name" : "rows", "fieldName" : "rows" }
]
},
{ "type" : "constant", "name": "const", "value" : 100 }
]
2015-07-02 14:37:23 -04:00
}]
2015-05-05 17:07:32 -04:00
...
}
```