Kueri agregasi memproses data dari beberapa entri indeks untuk menampilkan satu nilai ringkasan.
Cloud Firestore mendukung kueri agregasi berikut:
count()
sum()
average()
Cloud Firestore menghitung agregasi dan hanya mengirimkan hasilnya kembali ke aplikasi Anda. Dibandingkan dengan mengeksekusi kueri lengkap dan menghitung agregasi di aplikasi Anda, kueri agregasi menghemat pembacaan dokumen yang ditagihkan dan byte yang ditransfer.
Kueri agregasi bergantung pada konfigurasi indeks yang ada yang sudah digunakan kueri, dan diskalakan secara proporsional dengan jumlah entri indeks yang dipindai. Latensi meningkat seiring dengan jumlah item dalam agregasi.
Menggunakan agregasi count()
Kueri agregasi count()
memungkinkan Anda menentukan jumlah dokumen dalam koleksi atau kueri.
Lihat contoh data yang kami siapkan di Mendapatkan data.
Agregasi count()
berikut menampilkan jumlah total kota dalam
cities
koleksi.
API modular web
const coll = collection(db, "cities"); const snapshot = await getCountFromServer(coll); console.log('count: ', snapshot.data().count);
Swift
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
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"), );
Go
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);
Python
Agregasi count()
memperhitungkan semua filter pada kueri dan klausa limit
.
API modular 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
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
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"), );
Go
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);
Python
Menggunakan agregasi sum()
Gunakan agregasi sum()
untuk menampilkan jumlah total nilai numerik yang
cocok dengan kueri tertentu—misalnya:
API modular web
const coll = collection(firestore, 'cities'); const snapshot = await getAggregateFromServer(coll, { totalPopulation: sum('population') }); console.log('totalPopulation: ', snapshot.data().totalPopulation);
Java
collection = db.collection("cities"); snapshot = collection.aggregate(sum("population")).get().get(); System.out.println("Sum: " + snapshot.get(sum("population")));
Node.js
const coll = firestore.collection('cities'); const sumAggregateQuery = coll.aggregate({ totalPopulation: AggregateField.sum('population'), }); const snapshot = await sumAggregateQuery.get(); console.log('totalPopulation: ', snapshot.data().totalPopulation);
Agregasi sum()
memperhitungkan semua filter pada kueri dan klausa batas—misalnya:
API modular web
const coll = collection(firestore, 'cities'); const q = query(coll, where('capital', '==', true)); const snapshot = await getAggregateFromServer(q, { totalPopulation: sum('population') }); console.log('totalPopulation: ', snapshot.data().totalPopulation);
Java
collection = db.collection("cities"); query = collection.whereEqualTo("state", "CA"); snapshot = query.aggregate(sum("population")).get().get(); System.out.println("Sum: " + snapshot.get(sum("population")));
Node.js
const coll = firestore.collection('cities'); const q = coll.where("capital", "==", true); const sumAggregateQuery = q.aggregate({ totalPopulation: AggregateField.sum('population'), }); const snapshot = await sumAggregateQuery.get(); console.log('totalPopulation: ', snapshot.data().totalPopulation);
Menggunakan agregasi average()
Gunakan agregasi average()
untuk menampilkan rata-rata nilai numerik yang cocok dengan
kueri tertentu—misalnya:
API modular web
const coll = collection(firestore, 'cities'); const snapshot = await getAggregateFromServer(coll, { averagePopulation: average('population') }); console.log('averagePopulation: ', snapshot.data().averagePopulation);
Java
collection = db.collection("cities"); snapshot = collection.aggregate(average("population")).get().get(); System.out.println("Average: " + snapshot.get(average("population")));
Node.js
const coll = firestore.collection('cities'); const averageAggregateQuery = coll.aggregate({ averagePopulation: AggregateField.average('population'), }); const snapshot = await averageAggregateQuery.get(); console.log('averagePopulation: ', snapshot.data().averagePopulation);
Agregasi average()
memperhitungkan semua filter pada kueri dan klausa batas—misalnya:
API modular web
const coll = collection(firestore, 'cities'); const q = query(coll, where('capital', '==', true)); const snapshot = await getAggregateFromServer(q, { averagePopulation: average('population') }); console.log('averagePopulation: ', snapshot.data().averagePopulation);
Java
collection = db.collection("cities"); query = collection.whereEqualTo("state", "CA"); snapshot = query.aggregate(average("population")).get().get(); System.out.println("Average: " + snapshot.get(average("population")));
Node.js
const coll = firestore.collection('cities'); const q = coll.where("capital", "==", true); const averageAggregateQuery = q.aggregate({ averagePopulation: AggregateField.average('population'), }); const snapshot = await averageAggregateQuery.get(); console.log('averagePopulation: ', snapshot.data().averagePopulation);
Menghitung beberapa agregasi dalam kueri
Anda dapat menggabungkan beberapa agregasi dalam satu pipeline agregasi. Hal ini dapat mengurangi jumlah pembacaan indeks yang diperlukan. Jika kueri menyertakan agregasi di beberapa kolom, kueri mungkin memerlukan indeks komposit. Dalam hal ini, Cloud Firestore menyarankan indeks.
Contoh berikut melakukan beberapa agregasi dalam satu kueri agregasi:
API modular web
const coll = collection(firestore, 'cities'); const snapshot = await getAggregateFromServer(coll, { countOfDocs: count(), totalPopulation: sum('population'), averagePopulation: average('population') }); console.log('countOfDocs: ', snapshot.data().countOfDocs); console.log('totalPopulation: ', snapshot.data().totalPopulation); console.log('averagePopulation: ', snapshot.data().averagePopulation);
Java
collection = db.collection("cities"); query = collection.whereEqualTo("state", "CA"); AggregateQuery aggregateQuery = query.aggregate(count(), sum("population"), average("population")); snapshot = aggregateQuery.get().get(); System.out.println("Count: " + snapshot.getCount()); System.out.println("Sum: " + snapshot.get(sum("population"))); System.out.println("Average: " + snapshot.get(average("population")));
Node.js
const coll = firestore.collection('cities'); const aggregateQuery = coll.aggregate({ countOfDocs: AggregateField.count(), totalPopulation: AggregateField.sum('population'), averagePopulation: AggregateField.average('population') }); const snapshot = await aggregateQuery.get(); console.log('countOfDocs: ', snapshot.data().countOfDocs); console.log('totalPopulation: ', snapshot.data().totalPopulation); console.log('averagePopulation: ', snapshot.data().averagePopulation);
Kueri dengan beberapa agregasi hanya akan menyertakan dokumen yang berisi semua kolom dalam setiap agregasi. Hal ini dapat memberikan hasil yang berbeda jika melakukan setiap agregasi secara terpisah.
Aturan keamanan untuk kueri agregasi
Aturan Keamanan Cloud Firestore berfungsi sama pada kueri agregasi seperti pada kueri yang menampilkan dokumen. Dengan kata lain, jika dan hanya jika aturan Anda mengizinkan klien untuk mengeksekusi kueri koleksi atau grup koleksi tertentu, klien juga dapat melakukan agregasi pada kueri tersebut. Pelajari lebih lanjut cara Aturan Keamanan Cloud Firestore berinteraksi dengan kueri.
Perilaku dan batasan
Saat Anda bekerja dengan kueri agregasi, perhatikan perilaku dan batasan berikut:
Anda tidak dapat menggunakan kueri agregasi dengan pemroses real-time dan kueri offline. Kueri agregasi saat ini hanya didukung melalui respons server langsung. Kueri hanya ditayangkan oleh backend Cloud Firestore, serta melewati cache lokal dan update yang di buffer. Perilaku ini sama dengan operasi yang dilakukan di dalam transaksi Cloud Firestore.
Jika agregasi tidak dapat diselesaikan dalam waktu 60 detik, error
DEADLINE_EXCEEDED
akan ditampilkan. Performa bergantung pada konfigurasi indeks Anda dan ukuran set data.Jika operasi tidak dapat diselesaikan dalam batas waktu 60 detik, solusi yang memungkinkan adalah menggunakan penghitung untuk set data besar.
Kueri agregasi yang dibaca dari entri indeks dan hanya menyertakan kolom terindeks.
Menambahkan klausa
OrderBy
ke kueri agregasi akan membatasi agregasi pada dokumen tempat kolom pengurutan berada.Untuk agregasi
sum()
danaverage()
, nilai non-numerik akan diabaikan. Agregasisum()
danaverage()
hanya memperhitungkan nilai bilangan bulat dan nilai angka floating point.Saat menggabungkan beberapa agregasi dalam satu kueri, perhatikan bahwa
sum()
danaverage()
mengabaikan nilai non-numerik, sedangkancount()
menyertakan nilai non-numerik.Jika Anda menggabungkan agregasi yang berada di kolom berbeda, penghitungan hanya akan menyertakan dokumen yang berisi semua kolom tersebut.
Harga
Harga untuk kueri agregasi bergantung pada jumlah entri indeks yang cocok dengan kueri. Anda akan dikenai biaya dalam jumlah kecil untuk pembacaan dalam jumlah yang sesuai.
Lihat informasi harga yang lebih mendetail.