Una consulta de agregación procesa los datos de varias entidades indexadas para devolver un único valor de resumen. Firestore en modo Datastore admite las siguientes consultas de agregación:
count()
sum()
avg()
Las consultas de agregación simplifican el código de tu aplicación y cuestan menos que obtener cada entidad para procesarla. Lee esta página para saber cómo usar las consultas de agregación.
Agregación de count()
Usa la agregación count()
para devolver el número total de entidades indexadas que coinciden con una consulta determinada. Por ejemplo, esta agregación count()
devuelve el número total de entidades de un tipo.
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 admite una forma simplificada de las consultas count()
:
SELECT COUNT(*) AS total FROM tasks
En este ejemplo se usa un alias opcional de total
.
El formulario simplificado solo admite cláusulas FROM
y WHERE
. Consulta la referencia de GQL para obtener más información.
La agregación count()
tiene en cuenta los filtros de la consulta y las cláusulas limit
. Por ejemplo, la siguiente agregación devuelve el número de entidades que coinciden con los filtros especificados.
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 admite una forma simplificada de las consultas count()
:
SELECT COUNT(*) AS total FROM tasks WHERE is_done = false AND tag = 'house'
En este ejemplo se usa un alias opcional de total
.
El formulario simplificado solo admite cláusulas FROM
y WHERE
. Consulta la referencia de GQL para obtener más información.
En este ejemplo se muestra cómo contar hasta un valor determinado. Por ejemplo, puedes usarlo para detener el recuento en un número determinado e informar a los usuarios de que han superado ese número.
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 admite una forma simplificada de las consultas count_up_to()
:
SELECT COUNT_UP_TO(1000) AS total FROM tasks WHERE is_done = false AND tag = 'house'
En este ejemplo se usa un alias opcional de total
.
El formulario simplificado solo admite cláusulas FROM
y WHERE
. Consulta la referencia de GQL para obtener más información.
Agregación de sum()
Usa la agregación sum()
para devolver la suma total de los valores numéricos que coincidan con una consulta determinada. Por ejemplo, la siguiente sum()
agregación devuelve la suma total de los valores numéricos de la propiedad dada de
las entidades del tipo dado:
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 admite una forma simplificada de las consultas sum()
:
SELECT SUM(hours) AS total_hours FROM tasks
En este ejemplo se usa un alias opcional de total_hours
.
El formulario simplificado solo admite cláusulas FROM
y WHERE
. Consulta la referencia de GQL para obtener más información.
La agregación sum()
tiene en cuenta los filtros de la consulta y las cláusulas limit
. Por ejemplo, la siguiente agregación devuelve la suma de la propiedad especificada con un valor numérico en las entidades que coinciden con los filtros proporcionados.
Java
Python
Esta consulta requiere un índice como el siguiente:
- 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 admite una forma simplificada de las consultas sum()
:
SELECT SUM(hours) AS total_hours FROM tasks WHERE is_done = false AND tag = 'house'
En este ejemplo se usa un alias opcional de total_hours
.
El formulario simplificado solo admite cláusulas FROM
y WHERE
. Consulta la referencia de GQL para obtener más información.
Agregación de avg()
Usa la agregación avg()
para devolver la media de los valores numéricos que coincidan con una consulta determinada. Por ejemplo, la siguiente agregación avg()
devuelve la media aritmética
de la propiedad especificada a partir de los valores de propiedad numérica de las entidades
que coinciden con la consulta:
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 admite una forma simplificada de las consultas avg()
:
SELECT AVG(hours) as avg_hours
En este ejemplo se usa un alias opcional de avg_hours
.
El formulario simplificado solo admite cláusulas FROM
y WHERE
. Consulta la referencia de GQL para obtener más información.
La agregación avg()
tiene en cuenta los filtros de la consulta y las cláusulas limit
. Por ejemplo, la siguiente agregación devuelve la media aritmética de la propiedad especificada a partir de los valores de propiedad numéricos de las entidades que coinciden con los filtros de la consulta.
Java
Python
Esta consulta requiere un índice como el siguiente:
- 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 admite una forma simplificada de las consultas avg()
:
SELECT AVG(hours) as avg_hours FROM tasks WHERE is_done = false AND tag = 'house'
En este ejemplo se usa un alias opcional de avg_hours
.
El formulario simplificado solo admite cláusulas FROM
y WHERE
. Consulta la referencia de GQL para obtener más información.
Calcular varias agregaciones en una consulta
Puedes combinar varias agregaciones en una sola canalización de agregación. De esta forma, se puede reducir el número de lecturas de índice necesarias. Si la consulta incluye agregaciones en varios campos, requiere un índice compuesto y cada cálculo de agregación incluye solo las entidades que contienen todos los campos utilizados por cada agregación.
En el siguiente ejemplo se realizan varias agregaciones en una sola consulta de agregación:
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 admite una forma simplificada para las consultas de agregación:
SELECT SUM(hours) AS total_hours, COUNT(*) AS total_tasks FROM tasks WHERE is_done = false AND tag = 'house'
En este ejemplo se usan los alias opcionales total_hours
y total_tasks
.
El formulario simplificado solo admite cláusulas FROM
y WHERE
. Consulta la referencia de GQL para obtener más información.
Las consultas con varias agregaciones solo incluyen las entidades que contienen todas las propiedades de cada agregación. Esto puede dar lugar a resultados diferentes que si se realiza cada agregación por separado.
Comportamiento y limitaciones
Cuando trabajes con consultas de agregación, ten en cuenta el siguiente comportamiento y las limitaciones:
- La consulta que proporciones a la agregación debe cumplir las restricciones de las consultas.
Si una consulta de agregación no se puede resolver en un plazo de 60 segundos, devuelve un error
DEADLINE_EXCEEDED
. El rendimiento depende de la configuración del índice y del tamaño del conjunto de datos.Si la operación no se puede completar en el plazo de 60 segundos, una posible solución alternativa es usar cursores para combinar varias agregaciones.
Las consultas de agregación leen entradas de índice e incluyen solo propiedades indexadas en el cálculo.
Al añadir una cláusula
OrderBy
a la consulta, la agregación se limita a las entidades en las que existe la propiedad de ordenación.En GQL, la forma simplificada no admite las cláusulas
ORDER BY
,LIMIT
niOFFSET
.En una consulta de proyección, solo puede agregar datos de las propiedades de la proyección. Por ejemplo, en la consulta de GQL
SELECT a, b FROM k WHERE c = 1
, solo puede agregar datos dea
ob
.Una agregación
count()
no elimina las entidades duplicadas con propiedades de array. Cada valor de la matriz que coincida con la consulta añade una unidad al recuento.En las agregaciones
sum()
yavg()
, se ignoran los valores no numéricos. Las agregacionessum()
yavg()
solo tienen en cuenta los valores de números enteros, los valores de números de coma flotante y las marcas de tiempo. Las marcas de tiempo se convierten en valores enteros de microsegundos para lassum()
,avg()
y proyecciones.Cuando se combinan varias agregaciones en una sola consulta, ten en cuenta que
sum()
yavg()
ignoran los valores no numéricos, mientras quecount()
los incluye.Si combina agregaciones que se encuentran en propiedades diferentes, el cálculo solo incluirá las entidades que contengan todas esas propiedades. Esto puede dar lugar a resultados diferentes que si se realiza cada agregación por separado.
Precios
El precio de las consultas de agregación count()
, sum()
y avg()
depende del número de entradas de índice analizadas durante la operación. Se te cobra una lectura de entidad por cada 1000 entradas de índice coincidentes. Las entradas de índice posteriores
cuyo coste coincida con las unidades de lectura adicionales. Hay un coste mínimo de una unidad de lectura por cada consulta. Para obtener información sobre los precios, consulta la página Precios de Firestore en el modo de Datastore.
Si combina varias agregaciones en una sola consulta, la consulta usa el mismo índice para cada agregación y realiza un solo análisis de los datos. De esta forma, se puede reducir el número de lecturas y análisis de índices facturados en comparación con la realización de cada agregación por separado. Sin embargo, las consultas con varias agregaciones solo incluyen las entidades que contienen todas esas propiedades. Esto puede dar lugar a resultados diferentes a los que se obtendrían si se realizara cada agregación por separado.
Siguientes pasos
- Consulta información sobre las consultas.
- Consulta las prácticas recomendadas de Firestore en el modo de Datastore.