Bei einer Aggregationsabfrage werden die Daten aus mehreren indexierten Entitäten verarbeitet, um einen einzelnen zusammenfassenden Wert zurückzugeben. Firestore im Datastore-Modus unterstützt die folgenden Aggregationsabfragen:
count()
sum()
avg()
Aggregationsabfragen vereinfachen den Anwendungscode und kosten weniger als das Abrufen jeder Entität zur Verarbeitung. Auf dieser Seite erfahren Sie, wie Sie Aggregationsabfragen verwenden.
count()
Aggregation
Mit der count()
-Aggregation können Sie die Gesamtzahl der indexierten Entitäten zurückgeben, die einer bestimmten Abfrage entsprechen. Mit dieser count()
-Aggregation wird beispielsweise die Gesamtzahl der Entitäten eines Typs 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 der optionale Alias 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 in der Abfrage und alle limit
-Klauseln berücksichtigt. Die folgende Aggregation gibt beispielsweise die Anzahl der Entitäten zurück, die den angegebenen Filtern entsprechen.
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 der optionale Alias 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 bis zu einem bestimmten Wert gezählt wird. 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 der optionale Alias total
verwendet.
Die vereinfachte Form unterstützt nur FROM
- und WHERE
-Klauseln. Weitere Informationen finden Sie in der GQL-Referenz.
sum()
Aggregation
Mit der Aggregation sum()
können Sie die Gesamtsumme der numerischen Werte zurückgeben, die einer bestimmten Abfrage entsprechen. 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 der optionale Alias 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 in der 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 der optionale Alias 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 Aggregation avg()
können Sie den Durchschnitt der numerischen Werte zurückgeben, die einer bestimmten Anfrage entsprechen. Die folgende avg()
-Aggregation gibt beispielsweise das arithmetische Mittel der angegebenen Eigenschaft aus den numerischen Eigenschaftswerten von Entitäten zurück, die der Abfrage entsprechen:
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 der optionale Alias 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 in der Abfrage und alle limit
-Klauseln berücksichtigt. Die folgende Aggregation gibt beispielsweise das arithmetische Mittel 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 der optionale Alias 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 einzelnen 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. Jede Aggregationsberechnung umfasst nur die Einheiten, die alle Felder enthalten, die von den einzelnen Aggregationen verwendet werden.
Im folgenden Beispiel werden mehrere Aggregationen in einer einzelnen 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 Aggregationsabfragen:
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 Aliase 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 Attribute in jeder Aggregation enthalten. Das kann zu anderen Ergebnissen führen, als wenn Sie jede Aggregation separat durchführen.
Verhalten und Einschränkungen
Beachten Sie bei der Arbeit mit Aggregationsabfragen das folgende Verhalten und die folgenden Einschränkungen:
- Die Abfrage, die Sie für die Aggregation angeben, muss den Einschränkungen für Abfragen entsprechen.
Wenn eine Aggregationsabfrage nicht innerhalb von 60 Sekunden aufgelöst werden kann, wird ein
DEADLINE_EXCEEDED
-Fehler zurückgegeben. Die Leistung hängt von der Indexkonfiguration und der Größe des Datasets ab.Wenn der Vorgang nicht innerhalb der 60-Sekunden-Frist abgeschlossen werden kann, können Sie als Workaround Cursor verwenden, um mehrere Aggregationen zusammenzuführen.
Bei Aggregationsabfragen werden Indexeinträge gelesen und nur indexierte Eigenschaften in die Berechnung einbezogen.
Wenn Sie der Abfrage eine
OrderBy
-Klausel hinzufügen, wird die Aggregation auf die Einheiten beschränkt, für die die Sortierungsproperty vorhanden ist.In GQL werden in der vereinfachten Form die Klauseln
ORDER BY
,LIMIT
undOFFSET
nicht 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
aggregieren.Bei einer
count()
-Aggregation werden Entitäten mit Array-Properties nicht dedupliziert. Für jeden Arraywert, der der Abfrage entspricht, wird die Anzahl um eins erhöht.Bei
sum()
- undavg()
-Aggregationen werden nicht numerische Werte ignoriert. Bei der Aggregation vonsum()
undavg()
werden nur Ganzzahl-, Gleitkommazahl- und Zeitstempelwerte berücksichtigt. Zeitstempel werden fürsum()
,avg()
und Prognosen in Ganzzahlenwerte in Mikrosekunden umgewandelt.Wenn Sie mehrere Aggregationen in einer einzelnen Abfrage kombinieren, werden nicht numerische Werte bei
sum()
undavg()
ignoriert, beicount()
jedoch berücksichtigt.Wenn Sie Aggregationen für verschiedene Properties kombinieren, werden bei der Berechnung nur die Entitäten berücksichtigt, die alle diese Properties enthalten. Das kann zu anderen Ergebnissen führen, als wenn Sie jede Aggregation separat durchführen.
Preise
Die Preise für die Aggregationsabfragen count()
, sum()
und avg()
hängen von der Anzahl der Indexeinträge ab, die während des Vorgangs gescannt werden. Für bis zu 1.000 übereinstimmende Indexeinträge wird Ihnen ein Entitätslesevorgang in Rechnung gestellt. Für nachfolgende Indexeinträge, die übereinstimmen, fallen zusätzliche Leseeinheiten an. Für jede Abfrage fallen mindestens Kosten für eine Leseeinheit an. Preisinformationen finden Sie unter Preise für Firestore im Datastore-Modus.
Wenn Sie mehrere Aggregationen in einer einzelnen Abfrage kombinieren, wird für jede Aggregation derselbe Index verwendet und es wird nur ein Scan der Daten durchgeführt. Dadurch kann die Anzahl der Indexscans und Lesezugriffe reduziert werden, die im Vergleich zur separaten Ausführung jeder Aggregation in Rechnung gestellt werden. Abfragen mit mehreren Aggregationen enthalten jedoch nur die Entitäten, die alle diese Properties enthalten. Das kann zu anderen Ergebnissen führen, als wenn Sie jede Aggregation separat durchführen.
Nächste Schritte
- Weitere Informationen zu Abfragen
- Best Practices für Firestore im Datastore-Modus