汇总查询会处理多个已编入索引的实体中的数据, 返回单个摘要值。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()
聚合不会删除具有数组属性的重复实体。 每个与查询匹配的数组值都会在计数中加一。对于
sum()
和avg()
聚合,系统会忽略非数字值。sum()
和avg()
聚合只考虑整数值, 浮点数值和时间戳。时间戳为 转换为sum()
、avg()
、 和预测。在单个查询中组合多项聚合时,请注意,
sum()
和avg()
会忽略非数字值,而count()
会包含非数字值。如果合并针对不同媒体资源的汇总,计算结果会 仅包括包含所有这些属性的实体。这可能会导致 可以对不同结果产生不同的影响。
价格
count()
、sum()
和 avg()
聚合查询的价格取决于
操作期间扫描的索引条目数。您结算了一
实体读取(最多匹配 1,000 个索引条目)。后续索引条目
匹配费用额外读取单元。一个读取单元有最低费用
。价格
相关信息,请参阅 Datastore 模式 Firestore 价格。
如果您在单个查询中合并多项汇总,该查询将使用相同的 索引,并对数据执行单次扫描。 这有助于减少 与单独执行每次汇总相比,扫描和读取计费。 但是,包含多项汇总的查询仅包含 包含所有这些属性这可能会导致单独执行每次聚合时得到不同的结果。
后续步骤
- 了解查询。
- 了解 Datastore 模式 Firestore 的最佳实践。