Bucket selector aggregation #
A parent pipeline aggregation filtering the bucket list itself: a
script predicate per bucket — buckets whose script evaluates false
are dropped from the response. It is the HAVING clause of the
aggregation world: the predicate sees computed metrics, not
documents.
"big_days": {
"bucket_selector": {
"buckets_path": { "r": "revenue" },
"script": "params.r > 150"
}
}
How it works #
bucket_selector is declared inside the multi-bucket aggregation
it decorates, next to the metrics it consumes. After the buckets are
built, the engine resolves each named path against every bucket,
evaluates the script once as a boolean, and removes the buckets
that fail from the owning aggregation’s response. The selector
itself never appears in the output — it is a filter, not a metric.
Details verified against the engine:
buckets_pathfollows the same rules asbucket_script: a map of variable names to sibling metric paths, a.valuesuffix,"_count"for document counts, or a plain string binding_value. Variables are reachable asparams.ror barer, and arrive as floats.- A gap (a named metric missing in that bucket) drops the bucket
under the default
skippolicy; any other setting keeps it. - A script that fails at runtime keeps the bucket — a selector error never silently empties the response.
- Truthiness of the result: a boolean is taken as-is; a number is
true when non-zero; anything else (a string, an array) defaults to
keep. Prefer explicit comparisons —
params.r > 150says what you mean. - Filtering happens on the finished bucket list, so a selector can
reference any sibling metric of the same bucket — including a
pipeline declared earlier in the same
aggsobject. - A second, engine-specific placement also works: declaring
bucket_selectornext to the bucket aggregation, with fullparent>metricpaths, returns the kept buckets as a standalone array instead of filtering the parent in place.
Examples #
Only the days whose single sale exceeded 150 survive; per_day
comes back with just those buckets and no big_days entry anywhere.
Compound predicates work too — let per = params.r / params.n; per > 50 && params.r > 1500 combines a derived ratio with a floor on the
total (see
pipeline scripts).
Use cases #
- Threshold pruning — keep only buckets above a revenue, error or latency threshold, so the response a dashboard polls is already the interesting subset.
- Breach isolation — over an SLA metric per bucket, select the breached ones; the empty result is itself the good news.
- Noise-free comparisons — drop buckets with too little data
(
params.n < 5) before feeding the survivors to sibling pipelines or a client chart. - Top-tier focus — over customer-tier buckets, keep only the tiers a report covers.
Parameters for bucket_selector
#
buckets_path
(Required, object) Map of script variable names to sibling metric paths.script
(Required, string) Keep predicate overparams.<name>(or the bare<name>) — see pipeline scripts.gap_policy
(Optional, string)skip(default) drops buckets with missing metrics; any other setting keeps them.
Related #
bucket_script— the same machinery producing a metric instead of a filterbucket_sort— reordering and pagination of the bucket list (not yet active in this engine)- pipeline scripts — the script language reference