Scripted metric aggregation #
A metrics aggregation whose result is computed by your own scripts, in four phases, running on Pizza’s sandboxed script engine (see the script language reference).
How it works #
One state map per segment, folded once at the end:
| Phase | Runs | Scope |
|---|---|---|
init_script | once per segment | state, params |
map_script | once per document | state, doc, params |
combine_script | once per segment | state, params |
reduce_script | once, at the end | states, params |
state is a map you own — initialize it in init_script, accumulate into
it in map_script. combine_script folds one segment’s state into a
single value (a script that ends in a statement returns the state itself,
the default when combine_script is omitted). reduce_script receives
all combined values as the states array; if it is omitted, a single
state passes through unchanged and several come back as an array — the
parts, rather than a wrong merge. Builds without the scripting feature
return null for the whole aggregation.
Document fields are reachable in the doc-values shape:
doc.price.value— the first value ofpricefor the current documentdoc.price.values— all values (multi-value fields)doc['price'].value— the bracket spelling- a field the document doesn’t have has no entry —
doc.missing.valueerrors
Example: total and average order value #
Total revenue, order count and average order value in one pass
(120 docs, total 6750, average 56.25 on the sample data):
Example: filtered sum with params #
Only hat orders count; params carries the filter value (all four
phases see params). On the sample data: 1800 over 30 orders.
Use cases #
- One pass, several metrics — total, count and average in a single sweep, or any bundle of dependent numbers a plain metric agg cannot produce together.
- Filtered accumulation — count or sum only the rows a
paramsvalue selects (thehatrevenue above), without a wrappingfilterbucket. - Custom metrics — medians-of-groups, per-key tallies
(
state.by_type[x] += 1), or any shape amapplus areducecan hold, when no built-in agg fits. - Multi-state reductions — collect a list per segment and merge
the lists in
reduce_script, the pattern for top-N-by-group inside a script.
Parameters #
| Name | Type | Description |
|---|---|---|
init_script | string | Sets up the initial state. Optional. |
map_script | string | Executed per document. Optional (a doc-count-only agg needs none). |
combine_script | string | Folds a segment’s state to one value. Defaults to the state. |
reduce_script | string | Folds the states array to the result. See below. |
params | object | Extra variables visible in every phase as params.<name>. |
Notes and limits #
- Language: scripts are Rhai, not Painless. Everything in
the language reference applies — in
particular there is no
?:ternary and strings use double quotes (doc['x']single-quoted refs are rewritten for you).state.listarrays work withpush:state.items.push(doc.price.value)mutates the state, not a copy. - Distributed: under fan-out each shard returns its combined values;
the coordinator runs
reduce_scriptover them in shard-arrival order; areduce_scriptthat is not order-independent (non-commutative) is the script author’s problem. - Cost:
map_scriptruns once per matched document at roughly two microseconds per document. Keep it small; asumagg withfieldis always faster than a scripted sum. - Errors in any phase abort the aggregation and come back as
{"error": "<phase>: <message>"}rather than a wrong number. - The single-value metric aggs (
sum,avg, …) also accept a per-docscriptas their value source — see scripted value sources. Usescripted_metricwhen one script must see the whole bucket shape (filters, multi-state reductions), the plain metric script when one expression per doc is enough.
Related #
- Pipeline scripts — the Rhai language
reference: syntax,
doc/paramsbindings, and the limits of the sandbox. - Scripted value sources — the
cheaper per-document script form on
sum,avg,min,max,value_countandcardinality. bucket_script— a script over bucket metrics (after the aggregation), wherescripted_metricscripts run per document (during it).