Bei einer Aggregationsabfrage werden die Daten aus mehreren indexierten Entitäten verarbeitet, um einen einzelnen zusammengefassten Wert zurückzugeben. Firestore im Datastore-Modus unterstützt die folgenden Aggregationsanfragen:
count()
sum()
avg()
Aggregationsabfragen vereinfachen Ihren Anwendungscode und sind kostengünstiger als das Abrufen jeder Entität zur Verarbeitung. Auf dieser Seite erfahren Sie, wie Sie Aggregationsanfragen verwenden.
count()
Aggregation
Mit der count()
-Aggregation können Sie die Gesamtzahl der indexierten Entitäten zurückgeben, die mit einer bestimmten Abfrage übereinstimmen. Mit dieser count()
-Aggregation wird beispielsweise die Gesamtzahl der Entitäten einer Art zurückgegeben.
Java
Python
Go
aggregationCountQuery := datastore.NewQuery("Task"). NewAggregationQuery(). WithCount("total_tasks") countResults, err := client.RunAggregationQuery(ctx, aggregationCountQuery) count := countResults["total_tasks"] countValue := count.(*datastorepb.Value) fmt.Printf("Number of results from query: %d\n", countValue.GetIntegerValue())
GQL
AGGREGATE COUNT(*) AS total OVER ( SELECT * AS total FROM tasks )
GQL unterstützt eine vereinfachte Form von count()
-Abfragen:
SELECT COUNT(*) AS total FROM tasks
In diesem Beispiel wird ein optionaler Alias von total
verwendet.
Die vereinfachte Form unterstützt nur FROM
- und WHERE
-Klauseln. Weitere Informationen finden Sie in der GQL-Referenz.
Bei der count()
-Aggregation werden alle Filter für die Abfrage und alle limit
-Klauseln berücksichtigt. Die folgende Aggregation gibt beispielsweise die Anzahl der Entitäten zurück, die mit den angegebenen Filtern übereinstimmen.
Java
Python
Go
aggregationCountQuery := datastore.NewQuery("Task"). FilterField("done", "=", true). NewAggregationQuery(). WithCount("total_tasks_done") countResults, err := client.RunAggregationQuery(ctx, aggregationCountQuery) count := countResults["total_tasks_done"] countValue := count.(*datastorepb.Value) fmt.Printf("Number of results from query: %d\n", countValue.GetIntegerValue())
GQL
AGGREGATE COUNT(*) OVER ( SELECT * FROM tasks WHERE is_done = false AND tag = 'house')
GQL unterstützt eine vereinfachte Form von count()
-Abfragen:
SELECT COUNT(*) AS total FROM tasks WHERE is_done = false AND tag = 'house'
In diesem Beispiel wird ein optionaler Alias von total
verwendet.
Die vereinfachte Form unterstützt nur FROM
- und WHERE
-Klauseln. Weitere Informationen finden Sie in der GQL-Referenz.
In diesem Beispiel wird gezeigt, wie Sie bis zu einem bestimmten Wert zählen. So können Sie beispielsweise die Zählung bei einer bestimmten Zahl beenden und Nutzer darüber informieren, dass sie diese Zahl überschritten haben.
Java
Python
Go
aggregationCountQuery := datastore.NewQuery("Task"). Limit(2). NewAggregationQuery(). WithCount("at_least") countResults, err := client.RunAggregationQuery(ctx, aggregationCountQuery) count := countResults["at_least"] countValue := count.(*datastorepb.Value) fmt.Printf("We have at least %d tasks\n", countValue.GetIntegerValue())
GQL
AGGREGATE COUNT_UP_TO(1000) OVER ( SELECT * FROM tasks WHERE is_done = false)
GQL unterstützt eine vereinfachte Form von count_up_to()
-Abfragen:
SELECT COUNT_UP_TO(1000) AS total FROM tasks WHERE is_done = false AND tag = 'house'
In diesem Beispiel wird ein optionaler Alias von total
verwendet.
Die vereinfachte Form unterstützt nur FROM
- und WHERE
-Klauseln. Weitere Informationen finden Sie in der GQL-Referenz.
sum()
Aggregation
Mit der sum()
-Aggregation können Sie die Gesamtsumme der numerischen Werte zurückgeben, die mit einer bestimmten Abfrage übereinstimmen. Die folgende sum()
-Aggregation gibt beispielsweise die Gesamtsumme der numerischen Werte der angegebenen Property von Entitäten der angegebenen Art zurück:
Java
Python
Go
aggregationSumQuery := datastore.NewQuery("Task"). NewAggregationQuery(). WithSum("hours", "total_hours") sumResults, err := client.RunAggregationQuery(ctx, aggregationSumQuery) sum := sumResults["total_hours"] sumValue := sum.(*datastorepb.Value) fmt.Printf("Sum of results from query: %d\n", sumValue.GetIntegerValue())
GQL
AGGREGATE SUM(hours) AS total_hours OVER ( SELECT * FROM tasks )
GQL unterstützt eine vereinfachte Form von sum()
-Abfragen:
SELECT SUM(hours) AS total_hours FROM tasks
In diesem Beispiel wird ein optionaler Alias von total_hours
verwendet.
Die vereinfachte Form unterstützt nur FROM
- und WHERE
-Klauseln. Weitere Informationen finden Sie in der GQL-Referenz.
Bei der sum()
-Aggregation werden alle Filter für die Abfrage und alle limit
-Klauseln berücksichtigt. Die folgende Aggregation gibt beispielsweise die Summe des angegebenen Attributs mit einem numerischen Wert in Entitäten zurück, die den angegebenen Filtern entsprechen.
Java
Python
Für diese Abfrage ist ein Index wie der folgende erforderlich:
- kind: Task properties: - name: done - name: hours
Go
aggregationSumQuery := datastore.NewQuery("Task"). FilterField("done", "=", false). FilterField("tag", "=", "house"). NewAggregationQuery(). WithSum("hours", "total_hours") sumResults, err := client.RunAggregationQuery(ctx, aggregationSumQuery) sum := sumResults["total_hours"] sumValue := sum.(*datastorepb.Value) fmt.Printf("Sum of results from query: %d\n", sumValue.GetIntegerValue())
GQL
AGGREGATE SUM(hours) AS total_hours OVER ( SELECT * FROM tasks WHERE is_done = false AND tag = 'house' )
GQL unterstützt eine vereinfachte Form von sum()
-Abfragen:
SELECT SUM(hours) AS total_hours FROM tasks WHERE is_done = false AND tag = 'house'
In diesem Beispiel wird ein optionaler Alias von total_hours
verwendet.
Die vereinfachte Form unterstützt nur FROM
- und WHERE
-Klauseln. Weitere Informationen finden Sie in der GQL-Referenz.
avg()
Aggregation
Mit der avg()
-Aggregation können Sie den Durchschnitt der numerischen Werte zurückgeben, die mit einer bestimmten Abfrage übereinstimmen. Die folgende avg()
-Aggregation gibt beispielsweise den arithmetischen Mittelwert der angegebenen Property aus den numerischen Property-Werten von Entitäten zurück, die mit der Abfrage übereinstimmen:
Java
Python
Go
aggregationAvgQuery := datastore.NewQuery("Task"). NewAggregationQuery(). WithAvg("hours", "avg_hours") avgResults, err := client.RunAggregationQuery(ctx, aggregationAvgQuery) avg := avgResults["avg_hours"] avgValue := avg.(*datastorepb.Value) fmt.Printf("average hours: %f\n", avgValue.GetDoubleValue())
GQL
AGGREGATE AVG(hours) as avg_hours OVER ( SELECT * FROM tasks )
GQL unterstützt eine vereinfachte Form von avg()
-Abfragen:
SELECT AVG(hours) as avg_hours
In diesem Beispiel wird ein optionaler Alias von avg_hours
verwendet.
Die vereinfachte Form unterstützt nur FROM
- und WHERE
-Klauseln. Weitere Informationen finden Sie in der GQL-Referenz.
Bei der avg()
-Aggregation werden alle Filter für die Abfrage und alle limit
-Klauseln berücksichtigt. Die folgende Aggregation gibt beispielsweise den arithmetischen Mittelwert der angegebenen Property aus den numerischen Property-Werten von Entitäten zurück, die den Abfragefiltern entsprechen.
Java
Python
Für diese Abfrage ist ein Index wie der folgende erforderlich:
- kind: Task properties: - name: done - name: hours
Go
aggregationAvgQuery := datastore.NewQuery("Task"). FilterField("done", "=", false). FilterField("tag", "=", "house"). NewAggregationQuery(). WithAvg("hours", "avg_hours") avgResults, err := client.RunAggregationQuery(ctx, aggregationAvgQuery) avg := avgResults["avg_hours"] avgValue := avg.(*datastorepb.Value) fmt.Printf("average hours: %f\n", avgValue.GetDoubleValue())
GQL
AGGREGATE AVG(hours) as avg_hours OVER ( SELECT * FROM tasks WHERE is_done = false AND tag = 'house' )
GQL unterstützt eine vereinfachte Form von avg()
-Abfragen:
SELECT AVG(hours) as avg_hours FROM tasks WHERE is_done = false AND tag = 'house'
In diesem Beispiel wird ein optionaler Alias von avg_hours
verwendet.
Die vereinfachte Form unterstützt nur FROM
- und WHERE
-Klauseln. Weitere Informationen finden Sie in der GQL-Referenz.
Mehrere Aggregationen in einer Abfrage berechnen
Sie können mehrere Aggregationen in einer einzigen Aggregationspipeline kombinieren. Dadurch kann die Anzahl der erforderlichen Indexlesevorgänge reduziert werden. Wenn die Abfrage Aggregationen für mehrere Felder enthält, ist ein zusammengesetzter Index erforderlich. Bei jeder Aggregationsberechnung werden nur die Entitäten berücksichtigt, die alle Felder enthalten, die für die jeweilige Aggregation verwendet werden.
Im folgenden Beispiel werden mehrere Aggregationen in einer einzigen Aggregationsabfrage ausgeführt:
Java
Python
Go
aggregationQuery := datastore.NewQuery("Task"). NewAggregationQuery(). WithCount("total_tasks"). WithSum("hours", "total_hours"). WithAvg("hours", "avg_hours") Results, err := client.RunAggregationQuery(ctx, aggregationQuery) fmt.Printf("Number of results from query: %d\n", Results["total_tasks"].(*datastorepb.Value).GetIntegerValue()) fmt.Printf("Sum of results from query: %d\n", Results["total_hours"].(*datastorepb.Value).GetIntegerValue()) fmt.Printf("Avg of results from query: %f\n", Results["avg_hours"].(*datastorepb.Value).GetDoubleValue())
GQL
AGGREGATE SUM(hours) AS total_hours, COUNT(*) AS total_tasks OVER ( SELECT * FROM tasks WHERE is_done = false AND tag = 'house' )
GQL unterstützt eine vereinfachte Form für Aggregationsanfragen:
SELECT SUM(hours) AS total_hours, COUNT(*) AS total_tasks FROM tasks WHERE is_done = false AND tag = 'house'
In diesem Beispiel werden die optionalen Aliasse total_hours
und total_tasks
verwendet.
Die vereinfachte Form unterstützt nur FROM
- und WHERE
-Klauseln. Weitere Informationen finden Sie in der GQL-Referenz.
Abfragen mit mehreren Aggregationen enthalten nur die Entitäten, die alle Properties in jeder Aggregation enthalten. Dies kann zu unterschiedlichen Ergebnissen führen, wenn die einzelnen Aggregationen separat ausgeführt werden.
Verhalten und Einschränkungen
Beachten Sie bei der Arbeit mit Aggregationsanfragen Folgendes:
- Die für die Aggregation angegebene Abfrage muss die Beschränkungen für Abfragen erfüllen.
Wenn eine Aggregationsanfrage nicht innerhalb von 60 Sekunden aufgelöst werden kann, wird der Fehler
DEADLINE_EXCEEDED
zurückgegeben. Die Leistung hängt von der Indexkonfiguration und der Größe des Datensatzes ab.Wenn der Vorgang nicht innerhalb der 60 Sekunden abgeschlossen werden kann, können Sie mehrere Aggregationen mithilfe von Cursorn zusammenführen.
Aggregationsanfragen werden aus Indexeinträgen gelesen und enthalten nur indexierte Properties in der Berechnung.
Wenn Sie der Abfrage eine
OrderBy
-Klausel hinzufügen, wird die Aggregation auf die Entitäten beschränkt, in denen die Sortiereigenschaft vorhanden ist.In GQL werden in der vereinfachten Form keine
ORDER BY
-,LIMIT
- oderOFFSET
-Klauseln unterstützt.In einer Projektionsabfrage können Sie Daten nur aus den Properties in der Projektion aggregieren. In der GQL-Abfrage
SELECT a, b FROM k WHERE c = 1
können Sie beispielsweise nur Daten ausa
oderb
zusammenfassen.Bei einer
count()
-Aggregation werden keine Entitäten mit Array-Properties dedupliziert. Für jeden Arraywert, der mit der Abfrage übereinstimmt, wird die Anzahl um eins erhöht.Bei
sum()
- undavg()
-Aggregationen werden nicht numerische Werte ignoriert. Bei dersum()
- undavg()
-Aggregation werden nur Ganzzahlen, Gleitkommazahlen und Zeitstempel berücksichtigt. Zeitstempel werden fürsum()
-,avg()
- und Projektionen in Ganzzahlen in Mikrosekunden umgewandelt.Wenn Sie mehrere Aggregationen in einer einzigen Abfrage kombinieren, beachten Sie, dass bei
sum()
undavg()
nicht numerische Werte ignoriert werden, währendcount()
nicht numerische Werte berücksichtigt.Wenn Sie Aggregationen aus verschiedenen Properties kombinieren, werden bei der Berechnung nur die Entitäten berücksichtigt, die alle diese Properties enthalten. Dies kann zu anderen Ergebnissen führen, als wenn jede Aggregation separat durchgeführt wird.
Preise
Die Preise für count()
-, sum()
- und avg()
-Aggregationsanfragen richten sich nach der Anzahl der Indexeinträge, die während des Vorgangs gescannt werden. Ihnen wird ein Entitätslesevorgang für bis zu 1.000 Indexeinträge in Rechnung gestellt. Für nachfolgende Indexeinträge, die übereinstimmten, wurden zusätzliche Leseeinheiten berechnet. Für jede Abfrage wird eine Mindestgebühr von einer Leseeinheit in Rechnung gestellt. Preisinformationen finden Sie unter Preise für Firestore im Datastore-Modus.
Wenn Sie mehrere Aggregationen in einer einzigen Abfrage kombinieren, wird für jede Aggregation derselbe Index verwendet und es wird nur ein einziger Scan der Daten ausgeführt. So lässt sich die Anzahl der in Rechnung gestellten Indexscans und Lesevorgänge im Vergleich zur separaten Ausführung jeder Aggregation reduzieren. Abfragen mit mehreren Aggregationen enthalten jedoch nur die Entitäten, die alle diese Properties enthalten. Dies kann zu anderen Ergebnissen führen als bei einer separaten Ausführung der einzelnen Aggregationen.
Nächste Schritte
- Weitere Informationen zu Abfragen
- Best Practices für Firestore im Datastore-Modus