von derivative bis moving_fn und cumulative_sum
Pipeline-Aggregationen rechnen nicht über einzelne Dokumente, sondern über die Ergebnisse anderer Aggregationen. Damit werden Trends, gleitende Durchschnitte und kumulierte Summen direkt in der Query berechnet, statt sie fehleranfällig im Anwendungscode nachzubilden. Wer Sibling- und Parent-Pipelines verwechselt, bekommt Aggregationsfehler oder falsch verschachtelte Ergebnisse.
Inhaltsverzeichnis
- 1. Warum Pipeline-Aggregationen ein eigenes Konzept sind
- 2. Sibling- vs Parent-Pipeline-Aggregationen
- 3. derivative: Veränderung zwischen Buckets berechnen
- 4. moving_fn: gleitende Fenster und eigene Skripte
- 5. cumulative_sum: laufende Summen über die Zeit
- 6. Sibling-Pipelines: max_bucket, min_bucket, stats_bucket
- 7. bucket_selector und bucket_sort für Filterung nach der Aggregation
- 8. Performance und Grenzen von Pipeline-Aggregationen
- 9. Typische Fehler und Debugging
- 10. Zusammenfassung
- 11. FAQ
1. Warum Pipeline-Aggregationen ein eigenes Konzept sind
Normale Aggregationen in Elasticsearch, sogenannte Bucket- und Metrik-Aggregationen, rechnen direkt über die Dokumente eines Index. Eine Pipeline-Aggregation dagegen nimmt nicht Dokumente, sondern die Ausgabe einer bereits berechneten Aggregation als Eingabe. Statt "Summe der Bestellungen pro Tag" berechnet eine Pipeline-Aggregation zum Beispiel "Veränderung der Tagessumme gegenüber dem Vortag", indem sie auf die Ergebnisse der date_histogram Aggregation aufsetzt. Dieses zweistufige Modell erlaubt es, aus einfachen Bucket-Werten komplexe Trend- und Verlaufsberechnungen abzuleiten, ohne die Rohdaten ein zweites Mal abzufragen.
Der Vorteil gegenüber einer clientseitigen Nachbearbeitung ist doppelt: Erstens spart die serverseitige Berechnung einer Pipeline-Aggregation Netzwerk-Traffic, weil nur das fertige Ergebnis übertragen wird. Zweitens garantiert sie Konsistenz, weil Ableitung, gleitender Durchschnitt oder kumulierte Summe exakt auf denselben Buckets rechnen, die auch im Diagramm angezeigt werden. Wer stattdessen im Frontend nachträglich Differenzen berechnet, riskiert Rundungsfehler oder Inkonsistenzen bei fehlenden Buckets.
Die folgenden Abschnitte erklären die wichtigsten Pipeline-Aggregationen im Detail: derivative für Veränderungsraten, moving_fn für gleitende Fenster, cumulative_sum für laufende Summen sowie Sibling-Pipelines wie max_bucket und stats_bucket. Jede Pipeline-Aggregation wird mit echter Query-Syntax gezeigt, wie sie gegen einen produktiven Cluster läuft.
2. Sibling- vs Parent-Pipeline-Aggregationen
Elasticsearch unterscheidet zwei Kategorien von Pipeline-Aggregationen, die sich in ihrer Position in der Aggregations-Hierarchie und in ihrer Ausgabestruktur unterscheiden. Eine Parent-Pipeline-Aggregation wird als Geschwister-Aggregation innerhalb der Buckets einer Bucket-Aggregation definiert und fügt jedem einzelnen Bucket einen neuen berechneten Wert hinzu. derivative, cumulative_sum und moving_fn sind Parent-Pipelines: Sie erweitern jedes Bucket eines date_histogram um ein zusätzliches Feld, ohne die Anzahl der Buckets zu verändern.
Eine Sibling-Pipeline-Aggregation dagegen wird auf derselben Ebene wie die Bucket-Aggregation definiert, nicht innerhalb ihrer Buckets, und fasst alle Buckets zu einem einzigen Ergebnis zusammen. max_bucket findet zum Beispiel das Bucket mit dem höchsten Wert über die gesamte Zeitreihe und gibt dessen Schlüssel und Wert als einzelnes Ergebnis zurück, unabhängig davon, wie viele Buckets die zugrunde liegende Aggregation erzeugt hat. stats_bucket liefert min, max, avg, sum und count über alle Buckets hinweg in einem einzigen kompakten Objekt.
Der praktische Unterschied zeigt sich in der JSON-Struktur der Antwort: Bei einer Parent-Pipeline-Aggregation erscheint der neue Wert in jedem einzelnen Bucket-Objekt der ursprünglichen Aggregation. Bei einer Sibling-Pipeline-Aggregation erscheint das Ergebnis als eigenständiges Aggregations-Objekt auf derselben Verschachtelungsebene wie die Quellaggregation. Diese Unterscheidung ist keine Formalität, sondern bestimmt direkt, wo im buckets_path referenziert und wo im Response geparst werden muss.
3. derivative: Veränderung zwischen Buckets berechnen
Die derivative Pipeline-Aggregation berechnet die Differenz zwischen dem Wert eines Buckets und dem Wert des vorhergehenden Buckets. Das ist der direkte Weg, um aus einer Zeitreihe "Umsatz pro Tag" eine zweite Zeitreihe "Veränderung zum Vortag" abzuleiten, ohne die Berechnung im Client zu duplizieren. Der Parameter buckets_path zeigt dabei per Pfadnotation auf die Metrik-Aggregation, deren Werte als Eingabe dienen, etwa "daily_revenue" innerhalb desselben date_histogram Buckets.
Für Wachstumsraten statt absoluter Differenzen kombiniert man diese Pipeline-Aggregation häufig mit einer zweiten derivative-Stufe, die auf das Ergebnis der ersten derivative aufsetzt und damit die zweite Ableitung berechnet, also die Beschleunigung des Wachstums. Diese Verkettung mehrerer Pipeline-Aggregationen ist ein zentrales Merkmal des Modells: Jede Pipeline-Aggregation kann selbst wieder als Eingabe für eine weitere Pipeline-Aggregation dienen, solange der buckets_path korrekt auf den Namen der vorherigen Stufe verweist.
GET /orders/_search
{
"size": 0,
"aggs": {
"sales_per_day": {
"date_histogram": {
"field": "order_date",
"calendar_interval": "day",
"min_doc_count": 0
},
"aggs": {
"daily_revenue": { "sum": { "field": "grand_total" } },
"revenue_change": {
"derivative": {
"buckets_path": "daily_revenue"
}
}
}
}
}
}
4. moving_fn: gleitende Fenster und eigene Skripte
moving_fn ist die flexibelste Pipeline-Aggregation für gleitende Fenster, weil sie ein Painless-Skript entgegennimmt, das frei über die Werte eines konfigurierbaren Fensters aus vorhergehenden Buckets rechnet. Der Parameter window legt fest, wie viele Buckets in die Berechnung einfließen, shift verschiebt das Fenster relativ zum aktuellen Bucket. Für einen klassischen gleitenden 7-Tage-Durchschnitt liefert Elasticsearch die Hilfsfunktion MovingFunctions.unweightedAvg, die über die im Fenster verfügbaren Werte mittelt.
Der Vorteil gegenüber einer einfachen avg-Metrik über einen größeren Bucket ist die Glättung ohne Informationsverlust: Ein gleitender Durchschnitt zeigt weiterhin tägliche Datenpunkte, glättet aber kurzfristiges Rauschen wie Wochenend-Einbrüche im E-Commerce, während die Tagesauflösung der zugrunde liegenden date_histogram Aggregation erhalten bleibt. moving_fn eignet sich zusätzlich für komplexere Berechnungen wie gleitende Standardabweichung oder gleitendes Maximum, weil das Painless-Skript beliebige Logik über das übergebene values-Array ausführen kann.
GET /orders/_search
{
"size": 0,
"aggs": {
"sales_per_day": {
"date_histogram": {
"field": "order_date",
"calendar_interval": "day",
"min_doc_count": 0
},
"aggs": {
"daily_revenue": { "sum": { "field": "grand_total" } },
"revenue_7d_moving_avg": {
"moving_fn": {
"buckets_path": "daily_revenue",
"window": 7,
"script": "MovingFunctions.unweightedAvg(values)"
}
}
}
}
}
}
5. cumulative_sum: laufende Summen über die Zeit
cumulative_sum addiert den Wert jedes Buckets zur Summe aller vorhergehenden Buckets und liefert damit eine laufende Gesamtsumme, wie sie für Fortschrittsanzeigen und Jahresziel-Verfolgung typisch ist. Anders als sum, das nur den einzelnen Bucket-Wert liefert, wächst der Wert dieser Pipeline-Aggregation monoton mit jedem weiteren Zeitraum an. Für ein Sales-Dashboard mit Jahresziel bedeutet das: cumulative_sum zeigt direkt, wie sich der kumulierte Umsatz im Jahresverlauf einer Zielgeraden annähert, ohne dass diese Berechnung im Frontend nachgebaut werden muss.
Eine Besonderheit von cumulative_sum ist, dass die Kumulation über alle zurückgegebenen Buckets läuft, nicht nur über den sichtbaren Ausschnitt eines Dashboards. Wird der Zeitraum der zugrunde liegenden date_histogram Aggregation eingeschränkt, beginnt die kumulierte Summe wieder bei null am ersten Bucket dieses eingeschränkten Zeitraums. Für ein korrektes Jahresziel-Diagramm muss der abgefragte Zeitraum deshalb immer beim gewünschten Startpunkt der Kumulation beginnen, etwa dem ersten Januar, und nicht willkürlich später einsetzen.
GET /orders/_search
{
"size": 0,
"query": {
"range": { "order_date": { "gte": "2026-01-01", "lte": "2026-12-31" } }
},
"aggs": {
"sales_per_month": {
"date_histogram": {
"field": "order_date",
"calendar_interval": "month",
"min_doc_count": 0
},
"aggs": {
"monthly_revenue": { "sum": { "field": "grand_total" } },
"cumulative_revenue": {
"cumulative_sum": {
"buckets_path": "monthly_revenue"
}
}
}
}
}
}
6. Sibling-Pipelines: max_bucket, min_bucket, stats_bucket
Während derivative, moving_fn und cumulative_sum jedes Bucket einzeln erweitern, fassen Sibling-Pipeline-Aggregationen alle Buckets zu einer einzigen Kennzahl zusammen. max_bucket identifiziert den umsatzstärksten Tag in einer Zeitreihe und liefert sowohl dessen Bucket-Schlüssel als auch den Wert, ohne dass eine separate Sortierung oder ein zusätzlicher Query-Durchlauf nötig wäre. min_bucket funktioniert spiegelbildlich für den schwächsten Zeitraum.
stats_bucket ist die kompakteste dieser Pipeline-Aggregationen, weil sie count, min, max, avg und sum in einem einzigen Aufruf über alle Buckets berechnet. Das ist besonders nützlich für Übersichtskarten in Dashboards, die neben der detaillierten Zeitreihe zusätzliche Kennzahlen wie "bester Tag", "schwächster Tag" und "Durchschnitt über den Zeitraum" anzeigen sollen, ohne eine separate Aggregation über dieselben Rohdaten laufen zu lassen. percentiles_bucket ergänzt diese Familie um Perzentilwerte über die Bucket-Ergebnisse hinweg, etwa den Median der Tagesumsätze.
GET /orders/_search
{
"size": 0,
"aggs": {
"sales_per_day": {
"date_histogram": {
"field": "order_date",
"calendar_interval": "day",
"min_doc_count": 0
},
"aggs": {
"daily_revenue": { "sum": { "field": "grand_total" } }
}
},
"best_day": {
"max_bucket": { "buckets_path": "sales_per_day>daily_revenue" }
},
"revenue_stats": {
"stats_bucket": { "buckets_path": "sales_per_day>daily_revenue" }
}
}
}
7. bucket_selector und bucket_sort für Filterung nach der Aggregation
bucket_selector ist eine besondere Pipeline-Aggregation, die keinen neuen Wert erzeugt, sondern Buckets nach ihrer Berechnung entfernt, wenn ein Painless-Skript false zurückgibt. Damit lässt sich zum Beispiel eine Zeitreihe nachträglich auf Tage mit Umsatz oberhalb eines Schwellwerts einschränken, ohne die Filterung in einer separaten Anfrage oder im Client nachzubauen. Das ist ein Vorteil gegenüber einem einfachen query-Filter, weil bucket_selector auf dem bereits aggregierten Wert filtert, nicht auf Feldern einzelner Dokumente.
bucket_sort ergänzt bucket_selector um eine Sortier- und Paginierungsfunktion für Buckets. Während eine normale Bucket-Aggregation standardmäßig nach ihrem eigenen Kriterium sortiert, etwa chronologisch bei date_histogram, erlaubt bucket_sort eine nachträgliche Sortierung nach dem Wert einer Sub-Aggregation, kombiniert mit from und size für Top-N-Auswertungen wie "die zehn umsatzstärksten Wochen des Jahres". Beide Pipeline-Aggregationen zusammen ersetzen viele Fälle, in denen früher eine zweite Query oder eine clientseitige Nachverarbeitung nötig war.
| Pipeline-Aggregation | Typ | Ergebnis | Typischer Einsatz |
|---|---|---|---|
| derivative | Parent | Wert pro Bucket erweitert | Veränderung zum Vortag |
| moving_fn | Parent | Wert pro Bucket erweitert | Gleitender 7-Tage-Durchschnitt |
| cumulative_sum | Parent | Wert pro Bucket erweitert | Laufende Jahressumme |
| max_bucket / min_bucket | Sibling | Einzelnes Gesamtergebnis | Bester und schwächster Tag |
| stats_bucket | Sibling | Einzelnes Gesamtergebnis | Kompakte Kennzahlen-Übersicht |
8. Performance und Grenzen von Pipeline-Aggregationen
Pipeline-Aggregationen sind rechnerisch günstig, weil sie ausschließlich über bereits berechnete Bucket-Werte laufen und keine zusätzlichen Dokumente scannen. Der Rechenaufwand einer Pipeline-Aggregation hängt fast ausschließlich von der Anzahl der Buckets ab, nicht von der Anzahl der zugrunde liegenden Dokumente. Ein derivative über tausend Tagesbuckets ist trivial schnell, selbst wenn jeder einzelne Bucket Milliarden Dokumente zusammenfasst.
Eine wichtige Grenze betrifft verschachtelte Bucket-Aggregationen: Pipeline-Aggregationen wie derivative oder moving_fn arbeiten nur innerhalb einer einzigen Bucket-Ebene, etwa entlang eines date_histogram. Sind die Buckets zusätzlich nach Kategorie in einer Terms-Aggregation aufgeteilt, muss die Pipeline-Aggregation innerhalb jeder Kategorie-Gruppe separat definiert werden, weil buckets_path relativ zur aktuellen Verschachtelungsebene aufgelöst wird. Ein direkter Vergleich von Trends über verschiedene Kategorie-Zweige hinweg ist mit Standard-Pipeline-Aggregationen nicht möglich und erfordert entweder mehrere Teilanfragen oder eine Nachverarbeitung im Client.
9. Typische Fehler und Debugging
Der häufigste Fehler bei Pipeline-Aggregationen ist ein falscher buckets_path. Der Pfad muss exakt dem Namen der Ziel-Aggregation entsprechen und bei Sibling-Pipelines die Syntax "aggregationsname>metrikname" verwenden, um durch eine Verschachtelungsebene zu navigieren. Ein Tippfehler im buckets_path führt nicht zu einem stillen Fehlschlag, sondern zu einem expliziten Fehler beim Ausführen der Query, was das Debugging in der Praxis erleichtert.
// WRONG: buckets_path points to a bucket aggregation, not a metric
{
"derivative": { "buckets_path": "sales_per_day" }
}
// RIGHT: buckets_path points to the metric inside each bucket
{
"derivative": { "buckets_path": "sales_per_day.daily_revenue" }
}
// WRONG: sibling pipeline path missing the ">" navigation
{
"max_bucket": { "buckets_path": "sales_per_day.daily_revenue" }
}
// RIGHT: sibling pipelines navigate with ">" through nesting levels
{
"max_bucket": { "buckets_path": "sales_per_day>daily_revenue" }
}
Ein zweiter häufiger Fehler betrifft die ersten Buckets einer Zeitreihe: derivative liefert für das allererste Bucket keinen Wert, weil kein Vorgänger-Bucket existiert, mit dem verglichen werden könnte. Clients, die dieses fehlende Feld nicht abfangen, brechen mit einem Null-Pointer-Fehler ab. Ähnlich verhält sich moving_fn am Anfang der Zeitreihe, solange das konfigurierte Fenster noch nicht vollständig mit Werten gefüllt ist. Beide Fälle sind kein Bug, sondern erwartetes Verhalten einer Pipeline-Aggregation, das im Frontend explizit behandelt werden muss.
Mironsoft
Elasticsearch- und OpenSearch-Beratung für Suche, Analytics und Dashboards
Trends direkt aus der Aggregation berechnen, statt im Client zu rechnen?
Wir setzen Pipeline-Aggregationen für Trendberechnung, gleitende Durchschnitte und kumulierte Kennzahlen um, sodass Umsatz-Trends, Wachstumsraten und Zieltracking direkt aus der Elasticsearch-Query kommen.
Trend-Dashboards
derivative und moving_fn für Wachstumsraten und geglättete Verläufe
Zieltracking
cumulative_sum für Jahresziele und laufende Fortschrittsanzeigen
Aggregations-Audit
Prüfung bestehender buckets_path-Konfigurationen auf Fehler und Grenzfälle
10. Zusammenfassung
Pipeline-Aggregationen erweitern das Elasticsearch-Aggregationsmodell um eine zweite Berechnungsebene, die nicht über Dokumente, sondern über die Ergebnisse anderer Aggregationen läuft. Parent-Pipelines wie derivative, moving_fn und cumulative_sum erweitern jedes einzelne Bucket um einen zusätzlichen berechneten Wert. Sibling-Pipelines wie max_bucket und stats_bucket fassen alle Buckets zu einem einzigen Gesamtergebnis zusammen. bucket_selector und bucket_sort ermöglichen Filterung und Top-N-Auswertung auf bereits aggregierten Werten.
Wer diese Bausteine korrekt kombiniert, verlagert Trendberechnung, Glättung und Zieltracking vollständig in die Query und vermeidet fehleranfällige Nachverarbeitung im Client. Der buckets_path ist dabei die zentrale Stellschraube: Für Parent-Pipelines zeigt er mit Punktnotation in die eigene Verschachtelungsebene, für Sibling-Pipelines navigiert er mit dem Pfeil-Operator durch eine zusätzliche Ebene. Wer diesen Unterschied verinnerlicht, vermeidet die häufigsten Konfigurationsfehler bei Pipeline-Aggregationen.
Pipeline-Aggregationen im Detail, das Wichtigste auf einen Blick
Parent-Pipelines
derivative, moving_fn und cumulative_sum erweitern jedes Bucket, ohne die Bucket-Anzahl zu verändern.
Sibling-Pipelines
max_bucket, min_bucket und stats_bucket fassen alle Buckets zu einem einzigen Ergebnis zusammen.
Filterung und Sortierung
bucket_selector und bucket_sort filtern und sortieren nach bereits aggregierten Werten, nicht nach Dokumentfeldern.
buckets_path
Punktnotation für Parent-Pipelines, Pfeil-Operator für Sibling-Pipelines. Der häufigste Fehler ist ein falscher Pfad.