컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

집계 쿼리로 문서 수 집계

집계 쿼리는 여러 색인 항목의 데이터를 처리하여 단일 요약 값을 반환합니다.

Firestore는 count() 집계 쿼리를 지원합니다. count()를 사용하면 컬렉션 또는 쿼리의 문서 수를 결정할 수 있습니다. 서버는 수를 계산하고 하나의 정수만 앱으로 다시 전송하므로 전체 쿼리 실행과 비교했을 때 요금이 청구되는 문서 읽기 및 전송된 바이트 수 모두를 절약할 수 있습니다.

집계 쿼리는 쿼리를 이미 사용하는 기존 색인 구성을 기반으로 하며 스캔되는 색인 항목 수에 비례하여 확장됩니다. 즉, 항목 수에 따라 지연 시간이 증가하지만 중소 규모의 데이터 세트를 집계하면 20~40ms 이내에 수행됩니다.

count() 집계 사용

데이터 가져오기에서 설정한 예시 데이터를 참조하세요.

다음 count() 집계는 cities 컬렉션의 총 도시 수를 반환합니다.

웹 버전 9

const coll = collection(db, "cities");
const snapshot = await getCountFromServer(coll);
console.log('count: ', snapshot.data().count);
    
Swift
let collection = db.collection("cities")
let countQuery = collection.count
do {
  let snapshot = try await countQuery.getAggregation(source: .server)
  print(snapshot.count)
} catch {
  print(error);
}
      
Objective-C
FIRCollectionReference* collection = [db collectionWithPath:@"cities"];
[collection.count
  aggregationWithSource:FIRAggregateSourceServer
  completion:^(FIRAggregateQuerySnapshot *snapshot, NSError *error) {
    if (error == nil) {
        NSLog(@"Cities count: %@", snapshot.count);
    } else {
        NSLog(@"Error fetching count: %@", error);
    }
  }
];
      
자바
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());
  }
});
      
Kotlin+KTX
Android
val collection = db.collection("cities")
val countQuery = collection.count()
countQuery.get(AggregateSource.SERVER).addOnCompleteListener { task ->
  if (task.isSuccessful) {
    val snapshot = task.result
    Log.d(TAG, "Count: ${snapshot.count}")
  } else {
    Log.d(TAG, "Count failed: ", task.getException())
  }
}
      
자바
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 절을 고려합니다. 예를 들어 다음 집계는 stateCA인 도시 수를 반환합니다.

웹 버전 9

const coll = collection(db, "cities");
const query_ = query(coll, where('state', '==', 'CA'));
const snapshot = await getCountFromServer(query_);
console.log('count: ', snapshot.data().count);
    
Swift
let collection = db.collection("cities")
let query = collection.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
FIRCollectionReference* collection = [db collectionWithPath:@"cities"];
FIRQuery* query = [collection queryWhereField:@"state" isEqualTo:@"CA"];
[query.count
  aggregationWithSource:FIRAggregateSourceServer
  completion:^(FIRAggregateQuerySnapshot *snapshot, NSError *error) {
    if (error == nil) {
        NSLog(@"Cities count: %@", snapshot.count);
    } else {
        NSLog(@"Error fetching count: %@", error);
    }
  }
];
      
자바
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());
  }
});
      
Kotlin+KTX
Android
val collection = db.collection("cities")
val query = collection.whereEqualTo("state", "CA")
val countQuery = query.count()
countQuery.get(AggregateSource.SERVER).addOnCompleteListener { task ->
  if (task.isSuccessful) {
    val snapshot = task.result
    Log.d(TAG, "Count: ${snapshot.count}")
  } else {
    Log.d(TAG, "Count failed: ", task.getException())
  }
}
      
자바
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);
      

Firestore 보안 규칙은 문서를 반환하는 일반 쿼리처럼 count() 집계 쿼리에서 동일하게 작동합니다. 즉, 규칙이 클라이언트가 특정 컬렉션 또는 컬렉션 그룹 쿼리를 실행하도록 허용하는 경우에만 클라이언트가 이러한 쿼리에 대해 count() 집계를 수행할 수 있습니다. Firestore 보안 규칙이 쿼리와 상호작용하는 방법을 자세히 알아보세요.

제한사항

count() 집계 쿼리에는 다음 제한사항이 있습니다.

  • count() 집계 쿼리는 현재 직접 서버 응답을 통해서만 지원됩니다. 쿼리는 로컬 캐시 및 버퍼링된 업데이트를 건너뛰고 Firestore 백엔드에서만 제공됩니다. 이 동작은 Firestore 트랜잭션 내에서 실행되는 작업과 동일합니다. 현재 실시간 리스너 및 오프라인 쿼리에는 count() 쿼리를 사용할 수 없습니다.

  • count() 집계가 60초 이내에 해결되지 않으면 DEADLINE_EXCEEDED 오류가 반환됩니다. 성능은 색인 구성과 데이터 세트의 크기에 따라 달라집니다.

    60초 기한 내에 작업을 완료할 수 없는 경우 가능한 해결 방법은 대량 데이터 세트에 카운터를 사용하는 것입니다.

  • count() 집계는 색인 항목에서 읽고 색인 생성된 필드만 계산합니다.

  • 쿼리에 OrderBy 절을 추가하면 정렬 속성이 있는 항목으로 개수가 제한됩니다.

가격 책정

count()의 가격은 쿼리와 일치하는 색인 항목 수에 따라 다릅니다. 일치하는 항목의 수가 많으면 소액의 읽기 요금이 부과됩니다.

자세한 가격 책정 정보를 참조하세요.