Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

使用聚合查詢計數文檔

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

聚合查詢處理來自多個索引條目的數據以返回單個匯總值。

Cloud Firestore 支持count()聚合查詢。 count()允許您確定集合或查詢中的文檔數。服務器計算計數,並僅將結果(一個整數)傳輸回您的應用程序,與執行完整查詢相比,節省了計費文檔讀取和傳輸的字節數。

聚合查詢依賴於您的查詢已使用的現有索引配置,並根據掃描的索引條目數按比例縮放。這意味著中小型數據集的聚合在 20-40 毫秒內執行,儘管延遲會隨著計數的項目數量的增加而增加。

使用count()聚合

參考我們在獲取數據中設置的示例數據

以下count()聚合返回cities集合中的城市總數。

Web version 9

const coll = collection(db, "cities");
const snapshot = await getCountFromServer(coll);
console.log('count: ', snapshot.data().count);
    
迅速
let collection = db.collection("cities")
let countQuery = collection.count
do {
  let snapshot = try await countQuery.getAggregation(source: .server)
  print(snapshot.count)
} catch {
  print(error);
}
      
目標-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);
    }
  }
];
      

Kotlin+KTX

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");
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());
  }
});
      
爪哇
CollectionReference collection = db.collection("cities");
AggregateQuerySnapshot snapshot = collection.count().get().get();
System.out.println("Count: " + snapshot.getCount());
      
節點.js
const collectionRef = db.collection('cities');
const snapshot = await collectionRef.count().get();
console.log(snapshot.data().count);
      

count()聚合考慮了查詢中的任何過濾器和任何limit子句。例如,以下聚合返回state等於CA的城市數。

Web version 9

const coll = collection(db, "cities");
const query_ = query(coll, where('state', '==', 'CA'));
const snapshot = await getCountFromServer(query_);
console.log('count: ', snapshot.data().count);
    
迅速
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);
}
      
目標-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);
    }
  }
];
      

Kotlin+KTX

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");
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());
  }
});
      
爪哇
CollectionReference collection = db.collection("cities");
Query query = collection.whereEqualTo("state", "CA");
AggregateQuerySnapshot snapshot = query.count().get().get();
System.out.println("Count: " + snapshot.getCount());
      
節點.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()的定價取決於查詢匹配的索引條目數。您需要為大量匹配條目支付少量閱讀費用。

查看更詳細的定價信息