Filters aggregation

Filters aggregation #

A multi-bucket aggregation where each bucket is defined by a named filter — all filters run over the same document set, giving per-filter counts (and nested sub-aggregations) side by side. It is the aggregation form of a KPI panel: one request, several named slices.

How it works #

The filters object maps bucket names to query clauses. Every matching document is tested against EVERY filter independently, so buckets may overlap — a document counts toward each filter it satisfies, and toward none when it satisfies none. Bucket counts therefore do not sum to the hit total in general.

Two request shapes are accepted:

{ "filters": { "filters": { "error": {…}, "warn": {…} } } }   // named
{ "filters": { "filters": [ {…}, {…} ] } }                    // array

An anonymous array produces the same buckets keyed "0", "1", … by position. In the response, buckets are listed sorted by bucket name (for the array form that is the declaration order).

Each clause takes the same condition forms as filter: term/match (equality, shorthand {"type": "hat"} or normalized {"field": …, "value": …}), terms (any-of), range (gte/gt/ lte/lt) and match_all. Multi-valued fields match when any element equals the wanted value.

Examples #

Named filters over the logs levels — when every filter is a term on one field, the SQL side collapses to a single GROUP BY:

POST /logs/_search
{
  "aggs": {
    "messages": {
      "filters": {
        "filters": {
          "errors":   { "match": { "field": "level", "query": "error" } },
          "warnings": { "match": { "field": "level", "query": "warn" } }
        }
      }
    }
  }
}

An anonymous array of filters is also accepted; its buckets are keyed "0", "1", …

Use cases #

  • Level mix in one request. The example above returns error: 25 / warn: 25 / info: 100 — the health-check triad without three separate queries.
  • Multi-dimension segment panels. Customer tiers (gold: 4 / silver: 8 / bronze: 8) or sale statuses side by side, each with its own nested avg/sum.
  • Overlapping slices a GROUP BY cannot express. Buckets like “price >= 20”, “type is hat”, and “status is pending” in one aggregation — orthogonal cuts, not one dimension.
  • Top documents per slice. Nest top_hits under each named filter for a per-segment sample of documents.

Parameters for filters #

  • filters
    (Required, object or array) Named filter definitions — a map from bucket name to query clause, or an array of query clauses (keys become "0", "1", …).
  • aggs
    (Optional, object) Nested sub-aggregations, computed per bucket.
  • filter — the single-filter version
  • terms — one bucket per value of a field (the non-overlapping GROUP BY)
  • top_hits — sample documents per bucket
Calendar October 6, 2026
Edit Edit this page