Filter aggregation #
A single-bucket aggregation that narrows the documents a nested
aggregation runs on, with a query acting as the filter condition.
Where the request’s query scopes everything, filter carves out one
named sub-scope inside the aggregation tree — the aggregation
equivalent of a WHERE clause.
How it works #
Every matching document is tested against the condition; those that
pass form the bucket. The response is a single-bucket object carrying
the filtered doc_count plus any nested aggregation results:
"hat_sales": { "doc_count": 30, "total": { "value": 900.0 } }
The condition is any one query clause in map form, and both the shorthand and Pizza’s normalized spelling are accepted:
term/match— equality:{"term": {"type": "hat"}}or{"term": {"field": "type", "value": "hat"}}terms— any-of:{"terms": {"type": ["hat", "mug"]}}range— numeric boundsgte/gt/lte/lt, e.g.{"range": {"price": {"gte": 20}}}match_all— matches everything (the full parent scope)
Multi-valued fields match when ANY of their elements satisfies the
equality. Conditions compose with the outer query: the filter only ever
narrows the set it inherits, never widens it (for an escape from the
query scope see
global).
Examples #
Total amount of hat sales only — a WHERE scope on the SQL side:
POST /sales/_search
{
"aggs": {
"t_shirts": {
"filter": { "term": { "field": "type", "value": "t-shirt" } },
"aggs": {
"avg_price": { "avg": { "field": "price" } }
}
}
}
}
Use cases #
- Scoped metrics. “Revenue for hats only” (
SUM(amount) WHERE type = 'hat') without a second request or a query that hides the other documents from sibling aggregations. - KPI fractions. A
match_allfilter as denominator next to a narrowed filter as numerator — error rate, delivered share, gold-tier share — all inside one aggregation tree. - Conditional averages. Average
priceover arange-filtered slice (price >= 20) while the outer request still sees every sale. - Side-by-side scopes. Several filters at once — that shape is
filters.
Parameters for filter
#
<filter query>
(Required, query) The filter condition — any single query clause in the map form, e.g.{"term": {...}}.aggs
(Required, object) Nested sub-aggregations, computed over only the matching documents.
For multiple named filters in one aggregation, see filters.
Related #
filters— many named filters side by sideglobal— the opposite move: escape the query scopemissing— scope to documents LACKING a field- Term-level queries — the clause forms accepted as conditions