集約クエリは、複数のインデックス エンティティのデータを処理して、1 つのサマリー値を返します。Datastore モードの Firestore では、次の集約クエリがサポートされています。
count()
sum()
avg()
集計クエリは、アプリケーション コードを簡素化し、処理のために各エンティティを取得する場合よりもコストを削減します。このページでは、集約クエリの使用方法について説明します。
count()
集計
count()
集計を使用して、特定のクエリに一致するインデックス付きエンティティの合計数を返します。たとえば、この count()
集計は、1 種類のエンティティの合計数を返します。
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 リファレンスをご覧ください。
クエリ内の複数の集計を計算する
複数の集計を 1 つの集計パイプラインに組み合わせることができます。これにより、必要なインデックスの読み取り数を減らすことができます。クエリに複数の項目の集計が含まれている場合、クエリには複合インデックスが必要です。各集計計算には、各集計で使用されるすべてのフィールドを含むエンティティのみが含まれます。
次の例では、1 つの集計クエリで複数の集計を行います。
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()
、projections のマイクロ秒整数値に変換されます。複数の集計を 1 つのクエリに結合する場合、
sum()
とavg()
は数値以外の値を無視し、count()
には数値以外の値が含まれることに注意してください。異なるプロパティの集計を組み合わせる場合、計算には、それらのすべてのプロパティを含むエンティティのみが含まれます。このため、各集計を個別に実行した場合と結果が異なる可能性があります。
料金
count()
、sum()
、avg()
の集計クエリの料金は、オペレーション中にスキャンされたインデックス エントリの数によって異なります。最大 1,000 件のインデックス エントリに対して 1 件のエンティティ読み取りが課金されます。それ以降のインデックス エントリについては、追加の読み取りユニットが課金されます。クエリごとに 1 件の読み取りユニットという最小コストがかかります。料金については、Datastore モードの Firestore の料金をご覧ください。
複数の集計を 1 つのクエリで組み合わせると、クエリは各集計に同じインデックスを使用し、データに対して 1 回のスキャンを実行します。これにより、各集計を個別に実行する場合と比較して、課金対象となるインデックス スキャンと読み取りの数が軽減されます。ただし、複数の集計を含むクエリには、これらのプロパティをすべて含むエンティティのみが含まれます。このため、各集計を個別に実行した場合と結果が異なる可能性があります。
次のステップ
- クエリについて学習する。
- Datastore モードの Firestore のベスト プラクティスについて学習する。