Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

Conteggio dei documenti con query di aggregazione

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

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, di nuovo alla tua app, risparmiando sia le letture dei documenti fatturati che i byte trasferiti, rispetto all'esecuzione della query completa.

Le query di aggregazione si basano sulla configurazione dell'indice esistente che le tue query utilizzano già e scalano proporzionalmente in base al numero di voci dell'indice scansionate. Ciò significa che le aggregazioni di set di dati di piccole e medie dimensioni vengono eseguite entro 20-40 ms, anche se la latenza aumenta con il numero di elementi conteggiati.

Utilizza l'aggregazione count()

Fai riferimento ai dati di esempio che abbiamo configurato in Ottenere i dati.

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

Versione 9 web

const coll = collection(db, "cities");
const snapshot = await getCountFromServer(coll);
console.log('count: ', snapshot.data().count);
Swift
Nota:questo prodotto non è disponibile per i 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);
}
Objective-C
Nota:questo prodotto non è disponibile per i 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
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);
      

L'aggregazione count() prende in considerazione eventuali filtri nella query ed eventuali clausole limit. Ad esempio, la seguente aggregazione restituisce il conteggio del numero di città in cui state è uguale a CA.

Versione 9 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
Nota:questo prodotto non è disponibile per i 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);
}
Objective-C
Nota:questo prodotto non è disponibile per i 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
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);
      

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

Limitazioni

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

  • Al momento, le query di aggregazione di count() sono supportate solo tramite la risposta diretta del server. Le query vengono pubblicate solo dal backend Firestore, ignorando la cache locale e gli aggiornamenti presenti nel buffer. Questo comportamento è identico a quello delle operazioni eseguite all'interno delle transazioni di Firestore. Al momento non puoi utilizzare le query count() con listener in tempo reale e query offline.

  • Se l'aggregazione di count() non può risolversi 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 il termine di 60 secondi, una possibile soluzione è utilizzare i contatori per set di dati di grandi dimensioni.

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

  • L'aggiunta di una clausola OrderBy alla query limita il numero alle entità in cui esiste la proprietà di ordinamento.

Prezzi

I prezzi di count() dipendono dal numero di voci di indice corrispondenti alla query. Ti viene addebitato un numero ridotto di letture per un numero elevato di voci corrispondenti.

Visualizza informazioni sui prezzi più dettagliate.