Catch up on highlights from Firebase at Google I/O 2023. Learn more

Conta documenti con query di aggregazione

Una query di aggregazione elabora i dati da più voci di indice per restituire un singolo valore di riepilogo.

Cloud Firestore supporta la query di aggregazione count() . count() consente di determinare il numero di documenti in una raccolta o query. Il server calcola il conteggio e trasmette solo il risultato, un singolo numero intero, alla tua app, risparmiando sia sulle letture dei documenti fatturati che sui byte trasferiti, rispetto all'esecuzione della query completa.

Le query di aggregazione si basano sulla configurazione dell'indice esistente già utilizzata dalle query e si adattano proporzionalmente al numero di voci di indice analizzate. Ciò significa che le aggregazioni di set di dati di piccole e medie dimensioni vengono eseguite entro 20-40 ms, sebbene la latenza aumenti con il numero di elementi contati.

Utilizzare l'aggregazione count()

Fai riferimento ai dati di esempio che abbiamo impostato in Recupero dati .

La seguente aggregazione count() restituisce il numero totale di città nella raccolta cities .

Web modular API

const coll = collection(db, "cities");
const snapshot = await getCountFromServer(coll);
console.log('count: ', snapshot.data().count);
Rapido
Nota: questo prodotto non è disponibile sui target watchOS e App Clip.
let query = db.collection("cities")
let countQuery = query.count
do {
    let snapshot = try await countQuery.getAggregation(source: .server)
    print(snapshot.count)
} catch {
    print(error)
}
Obiettivo-C
Nota: questo prodotto non è disponibile sui target watchOS e App Clip.
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

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

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())
    }
}

Dart

// Returns number of documents in users collection
db.collection("users").count().get().then(
      (res) => print(res.count),
      onError: (e) => print("Error completing: $e"),
    );
Giava
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);
      

L'aggregazione count() tiene conto di eventuali filtri sulla query e di eventuali clausole limit . Ad esempio, la seguente aggregazione restituisce un conteggio del numero di città in cui state è uguale a CA .

Web modular API

const coll = collection(db, "cities");
const q = query(coll, where("state", "==", "CA"));
const snapshot = await getCountFromServer(q);
console.log('count: ', snapshot.data().count);
Rapido
Nota: questo prodotto non è disponibile sui target watchOS e App Clip.
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)
}
Obiettivo-C
Nota: questo prodotto non è disponibile sui target watchOS e App Clip.
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

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

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())
    }
}

Dart

// This also works with collectionGroup queries.
db.collection("users").where("age", isGreaterThan: 10).count().get().then(
      (res) => print(res.count),
      onError: (e) => print("Error completing: $e"),
    );
Giava
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);
      

Le regole di sicurezza di Cloud Firestore funzionano allo stesso modo sulle query di aggregazione count() come sulle normali query che restituiscono documenti. In altre parole, se e solo se le tue regole consentono ai client di eseguire determinate query di raccolte o gruppi di raccolte, i client possono anche eseguire l'aggregazione count() su tali query. Scopri di più su come le regole di sicurezza di Cloud Firestore interagiscono con le query .

Limitazioni

Tieni presente le seguenti limitazioni sulla query di aggregazione count() :

  • Le query di aggregazione count() sono attualmente supportate solo tramite risposta diretta del server. Le query vengono servite solo dal back-end di Cloud Firestore, saltando la cache locale ed eventuali aggiornamenti bufferizzati. Questo comportamento è identico alle operazioni eseguite all'interno delle transazioni di Cloud Firestore . Al momento non è possibile utilizzare le query count() con i listener in tempo reale e le query offline.

  • Se un'aggregazione count() non può essere risolta entro 60 secondi, restituisce un errore DEADLINE_EXCEEDED . Le prestazioni dipendono dalla configurazione dell'indice e dalle dimensioni del set di dati.

    Se l'operazione non può essere completata entro la scadenza dei 60 secondi, una possibile soluzione consiste nell'utilizzare contatori per insiemi di dati di grandi dimensioni.

  • L'aggregazione count() legge dalle voci di indice e conta solo i campi indicizzati.

  • L'aggiunta di una clausola OrderBy alla query limita il conteggio ai documenti in cui esiste il campo di ordinamento.

Prezzi

Il prezzo per count() dipende dal numero di voci di indice corrispondenti alla query. Ti viene addebitato un piccolo numero di letture per un numero elevato di voci corrispondenti.

Visualizza informazioni più dettagliate sui prezzi .