Запрос агрегации обрабатывает данные из нескольких записей индекса, чтобы вернуть одно итоговое значение.
Cloud Firestore поддерживает запрос агрегации count()
. count()
позволяет определить количество документов в коллекции или запросе. Сервер подсчитывает количество и передает только результат, одно целое число, обратно в ваше приложение, экономя как на чтениях оплачиваемых документов, так и на переданных байтах по сравнению с выполнением полного запроса.
Запросы агрегирования основаны на существующей конфигурации индекса, которую уже используют ваши запросы, и масштабируются пропорционально количеству просканированных записей индекса. Это означает, что агрегация наборов данных малого и среднего размера выполняется в течение 20–40 мс, хотя задержка увеличивается с увеличением количества подсчитанных элементов.
Используйте агрегацию count()
Обратитесь к примеру данных, которые мы настроили в Получение данных .
Следующая агрегация count()
возвращает общее количество городов в коллекции cities
.
Web modular API
const coll = collection(db, "cities"); const snapshot = await getCountFromServer(coll); console.log('count: ', snapshot.data().count);
Быстрый
let query = db.collection("cities") let countQuery = query.count do { let snapshot = try await countQuery.getAggregation(source: .server) print(snapshot.count) } catch { print(error) }
Цель-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"), );
Джава
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);
Агрегация count()
учитывает любые фильтры в запросе и любые limit
. Например, следующая агрегация возвращает количество городов, в которых state
равно 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);
Быстрый
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) }
Цель-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"), );
Джава
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);
Правила безопасности Cloud Firestore работают с запросами агрегации count()
так же, как и с обычными запросами, возвращающими документы. Другими словами, если и только если ваши правила позволяют клиентам выполнять определенные запросы коллекции или группы коллекций, клиенты также могут выполнять агрегацию count()
для этих запросов. Узнайте больше о том , как правила безопасности Cloud Firestore взаимодействуют с запросами .
Ограничения
Обратите внимание на следующие ограничения на запрос агрегации count()
:
Запросы агрегации
count()
в настоящее время поддерживаются только через прямой ответ сервера. Запросы обслуживаются только серверной частью Cloud Firestore, минуя локальный кеш и любые буферизованные обновления. Это поведение идентично операциям, выполняемым внутри транзакций Cloud Firestore . В настоящее время вы не можете использовать запросыcount()
с прослушивателями в реальном времени и автономными запросами.Если агрегация
count()
не может разрешиться в течение 60 секунд, она возвращает ошибкуDEADLINE_EXCEEDED
. Производительность зависит от конфигурации вашего индекса и размера набора данных.Если операция не может быть завершена в течение 60 секунд, возможным обходным путем является использование счетчиков для больших наборов данных.
Агрегация
count()
считывает записи индекса и подсчитывает только проиндексированные поля.Добавление предложения
OrderBy
в запрос ограничивает количество документов, в которых существует поле сортировки.
Цены
Стоимость count()
зависит от количества записей индекса, соответствующих запросу. За большое количество совпадающих записей взимается плата за небольшое количество прочтений.
Смотрите более подробную информацию о ценах .