Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Como contar documentos com consultas de agregação

Uma consulta de agregação processa os dados de várias entradas de índice para retornar um único valor de resumo.

O Firestore oferece suporte à consulta de agregação count(). A consulta count() permite determinar o número de documentos em uma coleção ou consulta. O servidor calcula a contagem e transmite apenas o resultado, um número inteiro, de volta ao app, economizando leituras de documentos faturados e bytes transferido, em comparação a uma consulta completa.

As consultas de agregação dependem da configuração de índice atual que suas consultas já usam e são escalonadas proporcionalmente ao número de entradas de índice verificadas. Isso significa que as agregações de conjuntos de dados pequenos e médios são realizadas em 20 a 40 ms, embora a latência aumente com o número de itens contados.

Usar a agregação count()

Consulte os dados de exemplo que configuramos em Como receber dados.

A agregação count() a seguir retorna o número total de cidades na coleção cities.

Versão 9 para a Web

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);
      

A agregação count() considera todos os filtros na consulta e todas as cláusulas limit. Por exemplo, a agregação a seguir retorna uma contagem do número de cidades em que state é CA.

Versão 9 para a Web

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);
      

As regras de segurança do Firestore funcionam da mesma forma em consultas de agregação count() que em consultas normais que retornam documentos. Em outras palavras, se e somente se as regras permitirem que os clientes executem determinadas consultas de coleta ou grupo de coleções, os clientes também poderão executar a agregação count() nessas consultas. Saiba mais sobre como as regras de segurança do Firestore interagem com consultas.

Limitações

Observe as seguintes limitações na consulta de agregação count():

  • No momento, as consultas de agregação count() só são suportadas pela resposta direta do servidor. As consultas são exibidas apenas pelo back-end do Firestore, pulando o cache local e todas as atualizações em buffer. Esse comportamento é idêntico às operações realizadas nas transações do Firestore. No momento, não é possível usar consultas count() com listeners em tempo real e consultas off-line.

  • Se uma agregação count() não puder ser resolvida em até 60 segundos, ela retornará um erro DEADLINE_EXCEEDED. O desempenho depende da configuração do índice e do tamanho do conjunto de dados.

    Se a operação não puder ser concluída dentro do prazo de 60 segundos, uma alternativa possível é usar contadores para conjuntos grandes de dados.

  • A agregação count() lê as entradas de índice e conta apenas os campos indexados.

  • Adicionar uma cláusula OrderBy à consulta limita a contagem às entidades em que a propriedade de ordenação existe.

Preços

O preço de count() depende do número de entradas de índice correspondentes à consulta. Você receberá a cobrança de um pequeno número de leituras por um grande número de entradas correspondentes.

Veja informações mais detalhadas sobre preços.