更新:自2022年10月起,Firestore支持使用聚合查询
计算文档,在JavaScript中的写法如下:
const coll = collection(db, "cities");
const snapshot = await getCountFromServer(coll);
console.log('count: ', snapshot.data().count);
你还可以使用查询来限制计算的文档,就像这样:
const coll = collection(db, "cities");
const query_ = query(coll, where('state', '==', 'CA'));
const snapshot = await getCountFromServer(query_);
console.log('count: ', snapshot.data().count);
当您使用
count()
操作时,每计算1,000个文档,您将被收取1个文档读取费用,但每个
count()
操作至少需要1个文档读取费用。计数操作的最长执行时间为60秒,超过该时间将超时。有关性能测试,请参见
Cloud Firestore中计数文档的速度有多快?。
出于性能和成本考虑,当需要计算大量用户的项目时,通常仍然需要使用其他方法,因此我将保留下面的先前答案。
更新:自2023年底以来,还可以在读取时跨多个Firestore文档计算总和和平均值。我建议查看关于
使用聚合查询汇总数据的文档和我的帖子:
如何处理Firestore中的聚合值。
之前的回答:
根据你提供的链接
docs:
Cloud Firestore不支持原生的聚合查询。
所以这基本上回答了你标题中的问题:Firestore没有内置的能力在数据库服务器上运行聚合操作。
常见的解决方案有:
在客户端上运行聚合操作
听起来你现在正在做的就是:你正在下载所有内部数据,然后在客户端上进行聚合。这种方法对于小数据集来说效果很好,但是如果你只是在客户端上显示聚合结果,那么你可能会下载比实际需要的数据要多得多。所以,如果你的数据集可能很大(当你使用Firestore时通常会变得很大),你应该考虑其他选择。
每次数据更改时更新聚合结果
在这种情况下,你将聚合值存储在数据库中,并在写入需要聚合的值时更新它。文档中展示了使用这种方式计算移动平均值的示例,这种方式根本不需要查询,因此可以适用于任何大小的数据集。
在这种情况下,你需要记住Firestore每秒只能执行大约一次写入操作。所以,如果你的数据量超过这个限制,你可能需要像文档中展示的分布式计数器那样分布你的聚合查询。
使用另一个数据库进行聚合查询
另一种选择是将Firestore用于存储客户端读取的数据,但使用另一个数据库进行复杂的动态查询。
一个典型的例子是将数据从Firestore导出到BigQuery,然后在BigQuery中进行计算,并将结果写回Firestore,以便客户端可以读取它们。在这种情况下,你将两个产品用于它们最擅长的领域:Firestore用于大规模数据服务,BigQuery用于大规模数据处理。