コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

集計クエリによるドキュメントのカウント

集約クエリは、複数のインデックス エントリのデータを処理して、1 つのサマリー値を返します。

Firestore は、count() 集計クエリをサポートしています。count() を使用すると、コレクションまたはクエリ内のドキュメント数を判別できます。サーバーはカウントを計算し、結果(1 つの整数)のみをアプリに返します。このため、完全なクエリを実行する場合と比較すると、課金対象となるドキュメントの読み取りと転送されるバイト数の両方を節約できます。

集約クエリは、クエリですでに使用している既存のインデックス構成を使用し、またスキャンされるインデックス エントリの数に比例してスケーリングされます。つまり、小規模から中規模のデータセットの集約は 20~40 ミリ秒以内に実行されますが、カウントされるアイテム数にともなってレイテンシは増加します。

count() 集約を使用する

データの取得で設定したサンプルデータをご覧ください。

次の count() 集約は、cities コレクション内の都市の総数を返します。

Web バージョン 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);
    }
  }
];
      
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());
  }
});
      
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())
  }
}
      
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);
      

count() 集約では、クエリに対するフィルタと、limit 句が考慮されます。たとえば、次の集約は、stateCA と等しい都市の数を返します。

Web バージョン 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);
    }
  }
];
      
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());
  }
});
      
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())
  }
}
      
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);
      

Firestore セキュリティ ルールの count() 集約クエリに対する動作は、ドキュメントを返す通常のクエリに対する動作と同様です。つまり、特定のコレクション クエリまたはコレクション グループ クエリをクライアントが実行することがルールで許可されている場合に限り、クライアントはこれらのクエリに対しても count() 集約を実行できます。詳細については、Firestore セキュリティ ルールとクエリの相互作用の仕組みをご覧ください。

制限事項

count() 集約クエリには、次の制限事項があります。

  • 現在、count() 集約クエリは、直接サーバー レスポンス経由でのみサポートされています。クエリは Firestore バックエンドによってのみ処理され、ローカル キャッシュとバッファリングされた更新はスキップされます。この動作は、Firestore トランザクション内で実行されるオペレーションと同じです。現時点では、リアルタイム リスナーおよびオフライン クエリと、count() クエリを併用することはできません。

  • count() 集約が 60 秒以内に解決できない場合は、DEADLINE_EXCEEDED エラーが返されます。パフォーマンスは、インデックス構成とデータセット サイズに応じて異なります。

    60 秒の期限内にオペレーションを完了できない場合、回避策としては、大規模データセット用のカウンタを使用できます。

  • count() 集約は、インデックス エントリから読み取りを行い、インデックス付きフィールドのみをカウントします。

  • クエリに OrderBy 句を追加すると、カウントされるのは、並べ替えプロパティが存在するエンティティに制限されます。

料金

count() の料金は、クエリによって照合されるインデックス エントリの数に応じて異なります。照合されるエントリが多数ある場合も、少数の読み取りの料金が課金されます。

詳細については、料金に関する情報をご覧ください。