匯總查詢會處理多個已建立索引的實體資料,並傳回單一摘要值。Datastore 模式的 Firestore 支援下列匯總查詢:
count()
sum()
avg()
匯總查詢可簡化應用程式碼,且費用比擷取每個實體進行處理更低。請參閱本頁,瞭解如何使用匯總查詢。
count()
匯總
使用 count()
匯總,傳回符合特定查詢的已建立索引實體總數。舉例來說,這個 count()
彙整會傳回某個種類的實體總數。
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 支援簡化的 count()
查詢形式:
SELECT COUNT(*) AS total FROM tasks
本範例使用選用別名 total
。
簡化版表單僅支援 FROM
和 WHERE
條款。詳情請參閱 GQL 參考資料。
count()
匯總會考量查詢中的所有篩選條件和 limit
子句。舉例來說,下列匯總會傳回符合指定篩選條件的實體數量。
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 支援簡化的 count()
查詢形式:
SELECT COUNT(*) AS total FROM tasks WHERE is_done = false AND tag = 'house'
本範例使用選用別名 total
。
簡化表單僅支援 FROM
和 WHERE
子句。詳情請參閱 GQL 參考資料。
這個範例說明如何計數至特定值。舉例來說,您可以使用這項功能在達到特定數字時停止計數,並通知使用者已超過該數字。
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 支援簡化的 count_up_to()
查詢形式:
SELECT COUNT_UP_TO(1000) AS total FROM tasks WHERE is_done = false AND tag = 'house'
本範例使用選用別名 total
。
簡化表單僅支援 FROM
和 WHERE
子句。詳情請參閱 GQL 參考資料。
sum()
匯總
使用 sum()
匯總,傳回符合指定查詢的數值總和。舉例來說,下列 sum()
匯總會傳回指定種類實體中,指定屬性的數值總和:
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 支援簡化的 sum()
查詢形式:
SELECT SUM(hours) AS total_hours FROM tasks
本範例使用選用別名 total_hours
。
簡化版表單僅支援 FROM
和 WHERE
條款。詳情請參閱 GQL 參考資料。
sum()
匯總會考量查詢中的所有篩選條件和 limit
子句。舉例來說,下列匯總會傳回符合指定篩選條件的實體中,具有數值的指定屬性總和。
Java
Python
這項查詢需要索引,例如:
- 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 支援簡化的 sum()
查詢形式:
SELECT SUM(hours) AS total_hours FROM tasks WHERE is_done = false AND tag = 'house'
本範例使用選用別名 total_hours
。
簡化版表單僅支援 FROM
和 WHERE
條款。詳情請參閱 GQL 參考資料。
avg()
匯總
使用 avg()
匯總,傳回符合指定查詢的數值平均值。舉例來說,下列 avg()
匯總會傳回查詢相符實體數值屬性值的算術平均值:
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 支援簡化的 avg()
查詢形式:
SELECT AVG(hours) as avg_hours
本範例使用選用別名 avg_hours
。
簡化版表單僅支援 FROM
和 WHERE
條款。詳情請參閱 GQL 參考資料。
avg()
匯總會考量查詢中的所有篩選條件和 limit
子句。舉例來說,下列彙整會傳回符合查詢篩選條件的實體,並從數值屬性值中取得指定屬性的算術平均值。
Java
Python
這項查詢需要索引,例如:
- 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 支援簡化的 avg()
查詢形式:
SELECT AVG(hours) as avg_hours FROM tasks WHERE is_done = false AND tag = 'house'
本範例使用選用別名 avg_hours
。
簡化版表單僅支援 FROM
和 WHERE
條款。詳情請參閱 GQL 參考資料。
在查詢中計算多個匯總
您可以在單一匯總管道中合併多個匯總。這有助於減少所需的索引讀取次數。如果查詢包含多個欄位的匯總,查詢需要複合式索引,且每個匯總計算只會納入包含每個匯總所用所有欄位的實體。
以下範例會在單一匯總查詢中執行多項匯總作業:
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 支援簡化的匯總查詢形式:
SELECT SUM(hours) AS total_hours, COUNT(*) AS total_tasks FROM tasks WHERE is_done = false AND tag = 'house'
本範例使用 total_hours
和 total_tasks
的選用別名。
簡化版表單僅支援 FROM
和 WHERE
條款。詳情請參閱 GQL 參考資料。
如果查詢包含多項匯總作業,則只會納入包含各項匯總作業中所有屬性的實體。這可能會導致與個別執行每項匯總作業不同的結果。
行為和限制
使用匯總查詢時,請注意下列行為和限制:
- 您提供給匯總的查詢必須符合查詢限制。
如果匯總查詢無法在 60 秒內解決,系統會傳回
DEADLINE_EXCEEDED
錯誤。效能取決於索引設定和資料集大小。如果作業無法在 60 秒內完成,可能的解決方法是使用游標合併多個匯總。
匯總查詢會讀取索引項目,且計算作業只會納入已建立索引的屬性。
在查詢中新增
OrderBy
子句,可將彙整範圍限制在具有排序屬性的實體。在 GQL 中,簡化形式不支援
ORDER BY
、LIMIT
或OFFSET
子句。在投影查詢中,您只能匯總投影中的屬性資料。舉例來說,在 GQL 查詢
SELECT a, b FROM k WHERE c = 1
中,您只能彙整a
或b
的資料。count()
匯總不會移除具有陣列屬性的重複實體。 每有一個陣列值符合查詢條件,計數就會加 1。如果是
sum()
和avg()
匯總,系統會忽略非數值。sum()
和avg()
匯總只會考量整數值、浮點數值和時間戳記。時間戳記會轉換為sum()
、avg()
和投影的微秒整數值。在單一查詢中合併多個匯總時,請注意
sum()
和avg()
會忽略非數值,而count()
則會納入非數值。如果合併不同資源的匯總,計算時只會納入包含所有這些資源的實體。這可能會導致與個別執行每項匯總作業不同的結果。
定價
count()
、sum()
和 avg()
匯總查詢的價格取決於作業期間掃描的索引項目數量。如果查詢最多找出 1,000 個索引項目,系統會收取一次實體讀取費用。後續相符的索引項目會產生額外的讀取單位費用。每項查詢的最低費用為一個讀取單位。如需定價資訊,請參閱 Firestore (Datastore 模式) 定價。
如果您在單一查詢中合併多個匯總,查詢會針對每個匯總使用相同的索引,並對資料執行單一掃描。與分別執行每項彙整作業相比,這有助於減少索引掃描和讀取次數,進而降低費用。不過,如果查詢包含多項匯總作業,則只會納入包含所有這些屬性的實體。這可能會導致與個別執行每項匯總作業不同的結果。
後續步驟
- 瞭解查詢。
- 瞭解 Datastore 模式的 Firestore 最佳做法。