Organiza tus páginas con colecciones Guarda y categoriza el contenido según tus preferencias.

Cómo contar documentos con consultas de agregación

Una consulta de agregación procesa los datos de varias entradas de índice para mostrar un solo valor de resumen.

Firestore admite la consulta de agregación count(). count() te permite determinar la cantidad de documentos en una colección o consulta. El servidor calcula el recuento y transmite solo el resultado, un único número entero, a tu app, lo que ahorra en operaciones de lectura de documentos facturados y bytes transferidos, en comparación con la ejecución de la consulta completa.

Las consultas de agregación se basan en la configuración de índices existente que tus consultas ya utilizan, y escalan proporcionalmente a la cantidad de entradas de índice analizadas. Esto significa que las agregaciones de conjuntos de datos pequeños y medianos tienen un rendimiento de 20 a 40 ms, aunque la latencia aumenta con la cantidad de elementos que se cuentan.

Usa la agregación count()

Consulta los datos de ejemplo que configuramos en Cómo obtener datos.

La siguiente agregación count() muestra la cantidad total de ciudades en la colección cities.

Web versión 9

const coll = collection(db, "cities");
const snapshot = await getCountFromServer(coll);
console.log('count: ', snapshot.data().count);
    
Swift
let collection = db.collection("cities")
let countQuery = collection.count
do {
  let snapshot = try await countQuery.getAggregation(source: .server)
  print(snapshot.count)
} catch {
  print(error);
}
      
Objective‑C
FIRCollectionReference* collection = [db collectionWithPath:@"cities"];
[collection.count
  aggregationWithSource:FIRAggregateSourceServer
  completion:^(FIRAggregateQuerySnapshot *snapshot, NSError *error) {
    if (error == nil) {
        NSLog(@"Cities count: %@", snapshot.count);
    } else {
        NSLog(@"Error fetching count: %@", error);
    }
  }
];
      
Java
Android
CollectionReference collection = db.collection("cities");
AggregateQuery countQuery = collection.count();
countQuery.get(AggregateSource.SERVER).addOnCompleteListener(task -> {
  if (task.isSuccessful()) {
    AggregateQuerySnapshot snapshot = task.getResult();
    Log.d(TAG, "Count: " + snapshot.getCount());
  } else {
    Log.d(TAG, "Count failed: ", task.getException());
  }
});
      
Kotlin+KTX
Android
val collection = db.collection("cities")
val countQuery = collection.count()
countQuery.get(AggregateSource.SERVER).addOnCompleteListener { task ->
  if (task.isSuccessful) {
    val snapshot = task.result
    Log.d(TAG, "Count: ${snapshot.count}")
  } else {
    Log.d(TAG, "Count failed: ", task.getException())
  }
}
      
Java
CollectionReference collection = db.collection("cities");
AggregateQuerySnapshot snapshot = collection.count().get().get();
System.out.println("Count: " + snapshot.getCount());
      
Node.js
const collectionRef = db.collection('cities');
const snapshot = await collectionRef.count().get();
console.log(snapshot.data().count);
      

La agregación count() toma en cuenta cualquier filtro en la consulta y cualquier cláusula limit. Por ejemplo, la siguiente agregación muestra un recuento de la cantidad de ciudades en las que state es igual a CA.

Web versión 9

const coll = collection(db, "cities");
const query_ = query(coll, where('state', '==', 'CA'));
const snapshot = await getCountFromServer(query_);
console.log('count: ', snapshot.data().count);
    
Swift
let collection = db.collection("cities")
let query = collection.whereField("state", isEqualTo: "CA")
let countQuery = query.count
do {
  let snapshot = try await countQuery.getAggregation(source: .server)
  print(snapshot.count)
} catch {
  print(error);
}
      
Objective‑C
FIRCollectionReference* collection = [db collectionWithPath:@"cities"];
FIRQuery* query = [collection queryWhereField:@"state" isEqualTo:@"CA"];
[query.count
  aggregationWithSource:FIRAggregateSourceServer
  completion:^(FIRAggregateQuerySnapshot *snapshot, NSError *error) {
    if (error == nil) {
        NSLog(@"Cities count: %@", snapshot.count);
    } else {
        NSLog(@"Error fetching count: %@", error);
    }
  }
];
      
Java
Android
CollectionReference collection = db.collection("cities");
Query query = collection.whereEqualTo("state", "CA");
AggregateQuery countQuery = query.count();
countQuery.get(AggregateSource.SERVER).addOnCompleteListener(task -> {
  if (task.isSuccessful()) {
    AggregateQuerySnapshot snapshot = task.getResult();
    Log.d(TAG, "Count: " + snapshot.getCount());
  } else {
    Log.d(TAG, "Count failed: ", task.getException());
  }
});
      
Kotlin+KTX
Android
val collection = db.collection("cities")
val query = collection.whereEqualTo("state", "CA")
val countQuery = query.count()
countQuery.get(AggregateSource.SERVER).addOnCompleteListener { task ->
  if (task.isSuccessful) {
    val snapshot = task.result
    Log.d(TAG, "Count: ${snapshot.count}")
  } else {
    Log.d(TAG, "Count failed: ", task.getException())
  }
}
      
Java
CollectionReference collection = db.collection("cities");
Query query = collection.whereEqualTo("state", "CA");
AggregateQuerySnapshot snapshot = query.count().get().get();
System.out.println("Count: " + snapshot.getCount());
      
Node.js
const collectionRef = db.collection('cities');
const query = collectionRef.where('state', '==', 'CA');
const snapshot = await query.count().get();
console.log(snapshot.data().count);
      

Las reglas de seguridad de Firestore funcionan de la misma manera en las consultas de agregación count() que en las consultas normales que muestran documentos. En otras palabras, si solo tus reglas permiten que los clientes ejecuten determinadas consultas de colecciones o grupos de colecciones, también pueden realizar la agregación count() en esas consultas. Obtén más información sobre cómo interactúan las reglas de seguridad de Firestore con las consultas.

Limitaciones

Ten en cuenta las siguientes limitaciones en la consulta de agregación count():

  • En la actualidad, las consultas de agregación count() solo se admiten a través de la respuesta directa del servidor. El backend de Firestore entrega solo las consultas, y omite la caché local y las actualizaciones almacenadas en búfer. Este comportamiento es idéntico a las operaciones realizadas dentro de las transacciones de Firestore. Por el momento, no puedes usar consultas count() con objetos de escucha en tiempo real ni consultas sin conexión.

  • Si una agregación count() no se puede resolver en 60 segundos, muestra un error DEADLINE_EXCEEDED. El rendimiento depende de la configuración de tu índice y del tamaño del conjunto de datos.

    Si la operación no se puede completar dentro del plazo de 60 segundos, una solución alternativa es usar contadores para conjuntos de datos grandes.

  • La agregación count() lee desde las entradas de índice y cuenta solo los campos indexados.

  • Agregar una cláusula OrderBy a la consulta limita el recuento de las entidades en las que existe la propiedad de ordenamiento.

Precios

El precio de count() depende de la cantidad de entradas de índice que coincidan con la consulta. Se te cobra una pequeña cantidad de lecturas por una gran cantidad de entradas coincidentes.

Consulta la información de precios más detallada.