获取我们在 Firebase 峰会上发布的所有信息,了解 Firebase 可如何帮助您加快应用开发速度并满怀信心地运行应用。了解详情

使用聚合查询计数文档

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。

聚合查询处理来自多个索引条目的数据以返回单个汇总值。

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()的定价取决于查询匹配的索引条目数。您需要为大量匹配条目支付少量阅读费用。

查看更详细的定价信息