Multiple Non-Nested Aggregations Multiple Non-Nested Aggregations elasticsearch elasticsearch

Multiple Non-Nested Aggregations


ElasticSearch has broadly 3 types of aggregations.

Bucket - Allows you to form "buckets" of different types. Terms (on not_analyzed string fields), time intervals (date_histogram aggregations if your data has a "timestamp" type of column), geographical shapes (geo hash aggregations if your data has longitude/latitude).

Metric - Sum, Average, Min, Max and numerical aggregations applied within buckets or outside buckets (at top level)

Pipeline - This is experimental. Feed output of one aggregation to another.

You can have multiple bucket aggregations on the same level (either top level "aggs" element or nested "aggs" inside other bucket aggregation). You can also nest bucket aggregations inside each other.

For metric aggregations, you can have them on the top level "aggs" element or inside another bucket aggregation.

In your example, if A, B and C are of String type and not_analyzed fields. You can do bucket aggregations like.

{  "size": 0,  "aggs": {    "one": {      "terms": {        "field": "A"      },      "aggs": {        "two": {          "terms": {            "field": "B"          }        }      }    },    "aggs": {      "three": {        "terms": {          "field": "C"        }      }    }  }}

"one" and "three" are term aggregations on the top level. "two" is nested inside "one".

If, additionally you had some numeric fields in your document. Say for example D and E. You want to compute sum of D's within each bucket of A and each bucket of B, sum of E within each bucket of B. Also sum of D within each bucket of C. You can do all of them simultaneously in one query, in single pass...

{  "size": 0,  "aggs": {    "one": {      "terms": {        "field": "A"      },      "aggs": {        "sumOfDWithinA": {          "sum": {            "field": "D"          }        },        "two": {          "terms": {            "field": "B"          },          "aggs": {            "sumOfDWithinB": {              "sum": {                "field": "D"              }            },            "sumOfEWithinB": {              "sum": {                "field": "E"              }            }          }        }      }    },    "aggs": {      "three": {        "terms": {          "field": "C"        },        "aggs": {          "sumOfDWithinC": {            "sum": {              "field": "D"            }          }        }      }    }  }}


so I have found that terms aggregation does not support collecting terms from multiple fields in the same document. Also that there are two approaches that can be used to perform a terms agg across multiple fields: script, and copy_to field while mapping.