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 é compatível com a 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
Observação: esse produto não está disponível para destinos watchOS e de clipes de apps.
let query = db.collection("cities")
let countQuery = query.count
do {
    let snapshot = try await countQuery.getAggregation(source: .server)
    print(snapshot.count)
} catch {
    print(error);
}
Objective-C
Observação: este produto não está disponível para watchOS e destinos de clipes de apps.
FIRCollectionReference *query = [self.db collectionWithPath:@"cities"];
[query.count aggregationWithSource:FIRAggregateSourceServer
                        completion:^(FIRAggregateQuerySnapshot *snapshot,
                                     NSError *error) {
    if (error != nil) {
        NSLog(@"Error fetching count: %@", error);
    } else {
        NSLog(@"Cities count: %@", snapshot.count);
    }
}];
Java
Android
Query query = db.collection("cities");
AggregateQuery countQuery = query.count();
countQuery.get(AggregateSource.SERVER).addOnCompleteListener(new OnCompleteListener<AggregateQuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<AggregateQuerySnapshot> task) {
        if (task.isSuccessful()) {
            // Count fetched successfully
            AggregateQuerySnapshot snapshot = task.getResult();
            Log.d(TAG, "Count: " + snapshot.getCount());
        } else {
            Log.d(TAG, "Count failed: ", task.getException());
        }
    }
});
Kotlin+KTX
Android
val query = db.collection("cities")
val countQuery = query.count()
countQuery.get(AggregateSource.SERVER).addOnCompleteListener { task ->
    if (task.isSuccessful) {
        // Count fetched successfully
        val snapshot = task.result
        Log.d(TAG, "Count: ${snapshot.count}")
    } else {
        Log.d(TAG, "Count failed: ", task.getException())
    }
}
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());
  }
});
      
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 q = query(coll, where("state", "==", "CA"));
const snapshot = await getCountFromServer(q);
console.log('count: ', snapshot.data().count);
Swift
Observação: esse produto não está disponível para destinos watchOS e de clipes de apps.
let query = db.collection("cities").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
Observação: este produto não está disponível para watchOS e destinos de clipes de apps.
FIRQuery *query =
    [[self.db collectionWithPath:@"cities"]
                 queryWhereField:@"state"
                       isEqualTo:@"CA"];
[query.count aggregationWithSource:FIRAggregateSourceServer
                        completion:^(FIRAggregateQuerySnapshot *snapshot,
                                      NSError *error) {
    if (error != nil) {
        NSLog(@"Error fetching count: %@", error);
    } else {
        NSLog(@"Cities count: %@", snapshot.count);
    }
}];
Java
Android
Query query = db.collection("cities").whereEqualTo("state", "CA");
AggregateQuery countQuery = query.count();
countQuery.get(AggregateSource.SERVER).addOnCompleteListener(new OnCompleteListener<AggregateQuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<AggregateQuerySnapshot> task) {
        if (task.isSuccessful()) {
            // Count fetched successfully
            AggregateQuerySnapshot snapshot = task.getResult();
            Log.d(TAG, "Count: " + snapshot.getCount());
        } else {
            Log.d(TAG, "Count failed: ", task.getException());
        }
    }
});
Kotlin+KTX
Android
val query = db.collection("cities").whereEqualTo("state", "CA")
val countQuery = query.count()
countQuery.get(AggregateSource.SERVER).addOnCompleteListener { task ->
    if (task.isSuccessful) {
        // Count fetched successfully
        val snapshot = task.result
        Log.d(TAG, "Count: ${snapshot.count}")
    } else {
        Log.d(TAG, "Count failed: ", task.getException())
    }
}
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());
  }
});
      
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 maneira em consultas de agregação count() e 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 de grupo de coleções, os clientes também podem 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 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ê vai receber a cobrança de um pequeno número de leituras por um grande número de entradas correspondentes.

Veja informações detalhadas sobre preços.