Bucket- vs. Metric-Aggregation richtig kombinieren
Wer Elasticsearch nur zum Volltextsuchen einsetzt, verschenkt den größten Teil seiner Analysefähigkeiten. Bucket-Aggregationen gruppieren Dokumente nach Feldwerten, Wertebereichen oder Zeitintervallen, während Metric-Aggregationen aus diesen Gruppen konkrete Kennzahlen wie Durchschnitt, Summe oder Minimum berechnen. Erst im Zusammenspiel beider Aggregationstypen entstehen die Dashboards, Facetten und Reports, die produktive Suchanwendungen von einfachen Volltextsuchen unterscheiden.
Inhaltsverzeichnis
- 1. Was Aggregationen in Elasticsearch leisten
- 2. Bucket-Aggregationen: Dokumente gruppieren
- 3. Metric-Aggregationen: Werte berechnen
- 4. Aggregationen verschachteln: Sub-Aggregationen
- 5. Die Terms Aggregation im Detail: size und order
- 6. Range- und Histogram-Aggregation für Verteilungen
- 7. Performance-Aspekte: doc_values und Filter-Kontext
- 8. Typische Fehler bei Bucket- und Metric-Kombination
- 9. Bucket- vs. Metric-Aggregation im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Was Aggregationen in Elasticsearch leisten
Eine Aggregation in Elasticsearch ist ein Analyse-Framework, das aus der aktuell abgefragten Dokumentenmenge zusammengefasste Daten berechnet, statt einzelne Treffer zurückzugeben. Wer aus einem relationalen Hintergrund kommt, kann sich Aggregationen als Kombination aus GROUP BY und Aggregatfunktionen wie COUNT, AVG oder SUM vorstellen, mit dem entscheidenden Unterschied, dass Elasticsearch das Ergebnis über verteilte Shards hinweg in nahezu Echtzeit berechnet, auch über Milliarden Dokumente. Aggregationen laufen im selben Request wie eine normale Suche und können zusätzlich zu Treffern zurückgegeben werden, was Filterung und Analyse in einer einzigen Anfrage vereint.
Die Elasticsearch-Dokumentation unterscheidet drei Kategorien von Aggregationen: Bucket-Aggregationen, Metric-Aggregationen und Pipeline-Aggregationen. Eine Bucket-Aggregation erzeugt einen oder mehrere Container, sogenannte Buckets, in die Dokumente anhand eines Kriteriums einsortiert werden, etwa nach dem Wert eines Feldes oder einem Wertebereich. Eine Metric-Aggregation berechnet dagegen einen numerischen Wert über eine Menge von Dokumenten, zum Beispiel den Durchschnittspreis oder die Gesamtsumme. Pipeline-Aggregationen verarbeiten die Ausgabe anderer Aggregationen weiter, etwa für gleitende Durchschnitte, bleiben in diesem Beitrag aber am Rand, weil der Fokus auf dem grundlegenden Zusammenspiel von Bucket- und Metric-Aggregation liegt.
2. Bucket-Aggregationen: Dokumente gruppieren
Eine Bucket-Aggregation beantwortet die Frage: In welche Gruppen zerfällt meine Dokumentenmenge? Die bekannteste Variante ist die Terms Aggregation, die für jeden eindeutigen Wert eines Feldes einen Bucket erzeugt und die Anzahl der zugehörigen Dokumente als doc_count mitliefert. Daneben gibt es die Range Aggregation für benutzerdefinierte Wertebereiche, die Histogram Aggregation für gleich große numerische Intervalle, die Date Histogram Aggregation für Zeitfenster und die Filters Aggregation für benannte, beliebig komplexe Filterkriterien. Jede Bucket-Aggregation liefert am Ende eine Liste von Buckets, wobei jeder Bucket mindestens einen Schlüssel und eine Dokumentanzahl enthält.
Der praktische Nutzen einer Bucket-Aggregation zeigt sich in Facetten-Navigation und Reporting: Eine Terms Aggregation auf dem Feld brand.keyword liefert in einem einzigen Request die Liste aller Marken im aktuellen Suchergebnis samt Trefferzahl, ohne dass die Anwendung selbst zählen muss. Wichtig ist dabei, dass Terms Aggregationen ausschließlich auf Feldern mit doc_values funktionieren, also typischerweise auf keyword-, numerischen oder Datumsfeldern, nicht auf analysierten text-Feldern ohne passendes Sub-Feld.
POST /products/_search
{
"size": 0,
"query": {
"match": { "category": "notebooks" }
},
"aggs": {
"brands": {
"terms": {
"field": "brand.keyword",
"size": 10
}
}
}
}
// Response excerpt:
// "aggregations": {
// "brands": {
// "doc_count_error_upper_bound": 0,
// "sum_other_doc_count": 12,
// "buckets": [
// { "key": "Dell", "doc_count": 340 },
// { "key": "Lenovo", "doc_count": 298 },
// { "key": "HP", "doc_count": 251 }
// ]
// }
// }
3. Metric-Aggregationen: Werte berechnen
Eine Metric-Aggregation reduziert eine Menge von Dokumenten auf einen oder mehrere numerische Werte. Single-value Metriken wie avg, sum, min, max und cardinality liefern genau einen Wert zurück. Multi-value Metriken wie stats und extended_stats liefern mehrere zusammenhängende Kennzahlen in einem Aufruf, etwa Minimum, Maximum, Durchschnitt, Summe und Dokumentanzahl gleichzeitig. Das spart in der Praxis mehrere Requests, weil stats genau die Werte liefert, die ein typisches Preisfilter-Widget benötigt.
Anders als Bucket-Aggregationen erzeugt eine Metric-Aggregation selbst keine neuen Buckets. Sie wird entweder auf der obersten Ebene einer Query ausgeführt und liefert dann eine einzige globale Kennzahl über alle Treffer, oder sie wird als Sub-Aggregation innerhalb eines Buckets platziert und liefert dann eine Kennzahl pro Bucket. Genau diese Verschachtelung ist der Kern produktiver Elasticsearch-Analysen und wird im nächsten Abschnitt vertieft.
POST /products/_search
{
"size": 0,
"aggs": {
"price_stats": {
"stats": { "field": "price" }
},
"unique_brands": {
"cardinality": { "field": "brand.keyword" }
}
}
}
// Response excerpt:
// "aggregations": {
// "price_stats": {
// "count": 4210, "min": 19.99, "max": 2499.00,
// "avg": 412.37, "sum": 1736078.70
// },
// "unique_brands": { "value": 47 }
// }
4. Aggregationen verschachteln: Sub-Aggregationen kombinieren
Der eigentliche Mehrwert entsteht, wenn eine Bucket-Aggregation und eine Metric-Aggregation ineinander verschachtelt werden. Jede Bucket-Aggregation akzeptiert einen eigenen aggs-Block, der beliebig tief weitere Bucket- oder Metric-Aggregationen enthalten kann. Damit lässt sich in einer einzigen Anfrage beantworten: Wie viele Produkte gibt es pro Marke, und wie hoch ist jeweils der Durchschnittspreis? Ohne Verschachtelung müsste die Anwendung für jede Marke einen eigenen Request mit einem Filter senden, was bei hunderten Marken nicht praktikabel ist.
Die Verschachtelungstiefe ist technisch nicht begrenzt, praktisch aber durch die Kombinatorik der Buckets beschränkt: Drei verschachtelte Terms Aggregationen mit jeweils size: 20 können im schlimmsten Fall 8000 Buckets erzeugen, jeder mit eigenen Sub-Metriken. Elasticsearch berechnet solche verschachtelten Bucket-Aggregationen und Metric-Aggregationen in einem einzigen Scan der relevanten Dokumente pro Shard, was deutlich effizienter ist als mehrere sequenzielle Requests, aber bei hoher Kardinalität und tiefer Verschachtelung dennoch signifikant Speicher und CPU auf den Datenknoten benötigt.
POST /products/_search
{
"size": 0,
"aggs": {
"by_brand": {
"terms": { "field": "brand.keyword", "size": 20 },
"aggs": {
"avg_price": { "avg": { "field": "price" } },
"by_category": {
"terms": { "field": "category.keyword", "size": 5 },
"aggs": {
"total_stock": { "sum": { "field": "stock_qty" } }
}
}
}
}
}
}
// Three-level nesting: brand -> category -> stock sum
// Each bucket carries its own metric sub-aggregation
5. Die Terms Aggregation im Detail: size und order
Der Parameter size bestimmt, wie viele Buckets die Terms Aggregation pro Shard-Zusammenführung zurückgibt, standardmäßig zehn. Wird size zu klein gewählt, gehen relevante, aber seltenere Werte verloren; wird er zu groß gewählt, steigt der Speicherverbrauch auf den Datenknoten spürbar an, weil jeder Shard intern mehr Kandidaten-Buckets vorhalten muss, bevor die finale Zusammenführung auf dem koordinierenden Knoten erfolgt. Das Feld sum_other_doc_count in der Antwort zeigt an, wie viele Dokumente in nicht zurückgegebenen Buckets liegen, ein wichtiger Hinweis darauf, ob size ausreichend groß gewählt wurde.
Der Parameter order steuert, nach welchem Kriterium Buckets sortiert werden, standardmäßig absteigend nach doc_count. Alternativ kann nach dem Bucket-Schlüssel selbst sortiert werden ({ "_key": "asc" }) oder, besonders nützlich in Kombination mit Sub-Aggregationen, nach dem Ergebnis einer verschachtelten Metric-Aggregation, etwa um die zehn Marken mit dem höchsten Durchschnittspreis zu finden. Genau an dieser Stelle wird die enge Kopplung von Bucket-Aggregation und Metric-Aggregation sichtbar: Die Metrik bestimmt nicht nur den Wert im Bucket, sondern kann auch die Auswahl der Buckets selbst steuern.
6. Range- und Histogram-Aggregation für Verteilungen
Während die Terms Aggregation für jeden diskreten Wert einen eigenen Bucket erzeugt, sind Range- und Histogram-Aggregation für kontinuierliche numerische Verteilungen gedacht. Die Range Aggregation definiert explizite, benannte Grenzen, etwa Preisklassen von 0 bis 50, 50 bis 200 und über 200 Euro, und ist damit die richtige Wahl für fachlich vorgegebene Kategorien, wie sie in Preisfilter-Widgets im E-Commerce üblich sind. Die Histogram Aggregation erzeugt dagegen automatisch gleich breite Intervalle basierend auf einem interval-Parameter und eignet sich besser für explorative Datenanalyse, bei der die sinnvollen Grenzen im Vorfeld nicht bekannt sind.
Beide Bucket-Aggregationen lassen sich, genau wie die Terms Aggregation, mit Metric-Aggregationen kombinieren. Eine Histogram Aggregation mit interval: 100 auf dem Preisfeld liefert Buckets für 0 bis 100, 100 bis 200 und so weiter; eine verschachtelte avg-Aggregation zeigt dann direkt, ob innerhalb jeder Preisspanne signifikante Unterschiede in einer anderen Kennzahl bestehen, etwa der durchschnittlichen Bewertungspunktzahl. Der Parameter min_doc_count: 0 erzwingt zusätzlich, dass auch leere Intervalle in der Antwort erscheinen, was für lückenlose Diagramme in Frontend-Visualisierungen wichtig ist.
POST /products/_search
{
"size": 0,
"aggs": {
"price_ranges": {
"range": {
"field": "price",
"ranges": [
{ "to": 50 },
{ "from": 50, "to": 200 },
{ "from": 200 }
]
},
"aggs": {
"avg_rating": { "avg": { "field": "rating" } }
}
},
"price_histogram": {
"histogram": {
"field": "price",
"interval": 100,
"min_doc_count": 0
}
}
}
}
// Range: named business buckets with own labels
// Histogram: fixed-width buckets, min_doc_count keeps empty ones
7. Performance-Aspekte: doc_values und Filter-Kontext
Aggregationen sind nur so schnell wie die Datenstruktur, auf der sie arbeiten. Elasticsearch berechnet Bucket- und Metric-Aggregationen auf Basis von doc_values, einer spaltenorientierten Datenstruktur, die beim Indexieren standardmäßig für alle Felder außer analysiertem text angelegt wird. Ohne doc_values müsste Elasticsearch für jede Aggregation den kompletten invertierten Index in eine In-Memory-Struktur namens Fielddata umwandeln, was Heap-Speicher belegt und bei großen Feldern zu Cluster-Instabilität führen kann. Deshalb sollte jedes Feld, auf dem regelmäßig aggregiert wird, als keyword oder numerischer Typ gemappt sein, nötigenfalls über ein keyword-Sub-Feld eines text-Feldes.
Ein zweiter Performance-Hebel ist der Filter-Kontext. Wird eine Aggregation innerhalb eines query-Blocks mit bool.filter statt bool.must eingeschränkt, entfällt die Relevanz-Berechnung (Scoring) für die zugrunde liegende Dokumentenmenge, und Elasticsearch kann den Filter-Cache nutzen. Da Aggregationen ohnehin keine Relevanz-Scores benötigen, sollte die filternde Query, auf der eine Bucket- oder Metric-Aggregation aufsetzt, praktisch immer im Filter-Kontext formuliert werden. Bei wiederkehrenden Aggregationsanfragen mit identischer Filterbasis, etwa auf einer Kategorieseite, reduziert das die Antwortzeit spürbar, weil der zugrunde liegende Dokumentensatz aus dem Cache kommt.
8. Typische Fehler bei Bucket- und Metric-Kombination
Der häufigste Fehler ist der Versuch, eine Terms Aggregation direkt auf einem analysierten text-Feld auszuführen. Da text-Felder standardmäßig keine doc_values besitzen, schlägt die Anfrage entweder mit einer Exception fehl oder aktiviert, falls Fielddata manuell eingeschaltet wurde, eine langsame und speicherintensive Berechnung. Die korrekte Lösung ist ein keyword-Multi-Field im Mapping, sodass sowohl Volltextsuche über brand als auch Aggregation über brand.keyword möglich sind.
// WRONG: mapping without keyword sub-field
PUT /products
{
"mappings": {
"properties": {
"brand": { "type": "text" }
}
}
}
// Aggregation on "brand" fails or falls back to slow fielddata
// RIGHT: multi-field mapping for search AND aggregation
PUT /products
{
"mappings": {
"properties": {
"brand": {
"type": "text",
"fields": {
"keyword": { "type": "keyword", "ignore_above": 256 }
}
}
}
}
}
// Search: match on "brand"
// Aggregate: terms on "brand.keyword"
Ein zweiter häufiger Fehler ist das Fehlen von "size": 0 auf oberster Ebene, wenn ausschließlich Aggregationsergebnisse benötigt werden. Ohne diesen Parameter liefert Elasticsearch zusätzlich zehn Treffer-Dokumente zurück, die Netzwerk-Bandbreite und Antwortzeit unnötig belasten. Ein dritter Fehler betrifft verschachtelte Metric-Aggregationen auf leeren Buckets: Wird avg auf einem Bucket mit null Dokumenten berechnet, liefert Elasticsearch null zurück, was im Frontend ohne explizite Prüfung zu Anzeigefehlern wie "NaN" oder leeren Diagrammbalken führt.
9. Bucket- vs. Metric-Aggregation im direkten Vergleich
Die folgende Übersicht fasst die zentralen Unterschiede zwischen Bucket-Aggregation und Metric-Aggregation zusammen und zeigt, wann welcher Aggregationstyp die richtige Wahl ist.
| Aspekt | Bucket-Aggregation | Metric-Aggregation |
|---|---|---|
| Zweck | Dokumente in Gruppen einteilen | Kennzahl über eine Dokumentmenge berechnen |
| Rückgabewert | Liste von Buckets mit Schlüssel und doc_count | Ein oder mehrere numerische Werte |
| Beispiele | terms, range, histogram, filters |
avg, sum, stats, cardinality |
| Verschachtelung | Kann eigene Sub-Aggregationen enthalten | Terminal, erzeugt keine weiteren Buckets |
| Performance-Treiber | Bucket-Anzahl, size-Parameter, Kardinalität | Feldtyp, doc_values-Verfügbarkeit |
| Typischer Einsatz | Facetten-Navigation, Reporting-Gruppierung | KPI-Widgets, Preisfilter-Grenzen |
In der Praxis stehen die beiden Aggregationstypen selten allein. Fast jede produktive Facetten-Navigation kombiniert eine Bucket-Aggregation für die Gruppierung mit einer oder mehreren Metric-Aggregationen für die Anreicherung jeder Gruppe. Wer diesen Zusammenhang verinnerlicht, liest jede Elasticsearch-Query strukturell schneller: Buckets beantworten "welche Gruppen gibt es", Metriken beantworten "wie sehen die Zahlen innerhalb dieser Gruppen aus".
Mironsoft
Elasticsearch- und OpenSearch-Architektur, Aggregationen und Suchperformance
Aggregationen, die auch bei Millionen Dokumenten schnell bleiben?
Wir analysieren bestehende Elasticsearch-Mappings und Aggregations-Queries, decken teure Bucket- und Metric-Kombinationen auf und bauen facettierte Suche, die auch unter Last stabil bleibt.
Mapping-Review
doc_values, keyword-Sub-Felder und Aggregations-Tauglichkeit prüfen
Query-Optimierung
Filter-Kontext, Verschachtelungstiefe und Bucket-Größen anpassen
Facetten-Konzept
Facettierte Navigation und KPI-Widgets auf Basis von Aggregationen entwerfen
10. Zusammenfassung
Bucket-Aggregation und Metric-Aggregation sind die beiden fundamentalen Bausteine der Elasticsearch-Analyse. Eine Bucket-Aggregation gruppiert Dokumente nach Feldwerten, Wertebereichen oder Zeitintervallen und liefert für jede Gruppe eine Dokumentanzahl. Eine Metric-Aggregation berechnet einen numerischen Wert über eine Dokumentmenge, entweder global oder innerhalb eines einzelnen Buckets. Erst die Verschachtelung beider Typen als Sub-Aggregation macht aus einfachen Zählungen echte Analysen: Durchschnittspreis pro Marke, Bewertungsdurchschnitt pro Preisspanne, Lagerbestand pro Kategorie.
Für stabile Performance gilt: Aggregations-Felder müssen doc_values besitzen, also als keyword oder numerisch gemappt sein, und die zugrunde liegende Query sollte im Filter-Kontext formuliert werden. Die Parameter size und order steuern, wie viele Buckets zurückkommen und in welcher Reihenfolge, wobei ein zu groß gewählter size-Wert bei hoher Kardinalität schnell zum Speicherproblem wird, ein Thema, das im nächsten Beitrag zur Terms-Aggregation-Performance vertieft wird.
Bucket- vs. Metric-Aggregation, das Wichtigste auf einen Blick
Bucket-Aggregation
Gruppiert Dokumente nach Kriterium, zum Beispiel terms, range oder histogram. Liefert Buckets mit Schlüssel und doc_count.
Metric-Aggregation
Berechnet Kennzahlen wie avg, sum oder stats, global oder innerhalb eines Buckets als Sub-Aggregation.
Mapping-Voraussetzung
Aggregations-Felder brauchen doc_values, also keyword- oder numerischen Typ statt reinem analysiertem text-Feld.
Performance
Filter-Kontext statt must-Query nutzen, size-Parameter bewusst wählen, Verschachtelungstiefe begrenzen.