是否可以使用新的Firebase数据库Cloud Firestore来计算一个集合有多少项?
如果是,我该怎么做?
是否可以使用新的Firebase数据库Cloud Firestore来计算一个集合有多少项?
如果是,我该怎么做?
当前回答
Firebase/Firestore中的新功能提供了集合中的文档计数:
请参阅本线程以了解如何实现它,并提供了一个示例。
如何计算在一个集合中的Firebase Firestore与WHERE查询在react.js文档的数量
其他回答
截至2022年10月,Firestore在客户端sdk上引入了count()方法。现在您可以在没有下载的情况下计算查询。
对于1000份文件,它将收取你阅读1份文件的费用。
网络(v9)
Firebase 9.11.0介绍:
const collectionRef = collection(db, "cities");
const snapshot = await getCountFromServer(collectionRef);
console.log('count: ', snapshot.data().count);
Web V8
不可用。
节点(管理)
const collectionRef = db.collection('cities');
const snapshot = await collectionRef.count().get();
console.log(snapshot.data().count);
Android (Kotlin)
在firestore v24.4.0 (BoM 31.0.0)引入:
val query = db.collection("cities")
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())
}
}
苹果平台(Swift)
Firestore v10.0.0引入:
do {
let query = db.collection("cities")
let countQuery = query.countAggregateQuery
let snapshot = try await countQuery.aggregation(source: AggregateSource.server)
print(snapshot.count)
} catch {
print(error)
}
据我所知,目前还没有内置的解决方案,只能在节点sdk中实现。 如果你有
db.collection('someCollection')
你可以使用
.select([fields])
定义要选择的字段。如果执行空select(),则只会得到一个文档引用数组。
例子:
db.collection (someCollection) .select () . get () ( (snapshot) => console.log(snapshot.docs.length) );
此解决方案只是针对下载所有文档的最坏情况的优化,并且不能扩展到大型集合!
再看看这个: 如何获得在一个集合与云Firestore的文件的数量计数
解决办法是:
在firebase文档中编写一个计数器,每次创建新条目时都在事务中增加计数器
您将计数存储在新条目的字段中(即:position: 4)。
然后在该字段上创建一个索引(position DESC)。
您可以对查询执行跳过+限制操作。Where("position", "<" x).OrderBy("position", DESC)
希望这能有所帮助!
Firebase/Firestore中的新功能提供了集合中的文档计数:
请参阅本线程以了解如何实现它,并提供了一个示例。
如何计算在一个集合中的Firebase Firestore与WHERE查询在react.js文档的数量
和许多问题一样,答案是——视情况而定。
在前端处理大量数据时应该非常小心。除了让你的前端感觉迟钝之外,Firestore还会向你收取每百万次读取60美元的费用。
小型收藏(少于100份文件)
小心使用-前端用户体验可能会受到影响
在前端处理这个应该没问题,只要你没有对这个返回的数组做太多的逻辑处理。
db.collection('...').get().then(snap => {
size = snap.size // will return the collection size
});
中等藏书(100至1000份)
小心使用- Firestore读取调用可能会花费很多
在前端处理这个问题是不可行的,因为它有很大的可能会降低用户系统的速度。我们应该处理这个逻辑服务器端,只返回大小。
这种方法的缺点是您仍然在调用Firestore读取(等于您的集合的大小),从长远来看,这最终可能会使您的成本超过预期。
云功能:
db.collection('...').get().then(snap => {
res.status(200).send({length: snap.size});
});
前端:
yourHttpClient.post(yourCloudFunctionUrl).toPromise().then(snap => {
size = snap.length // will return the collection size
})
大量的收集(1000+文档)
最具可扩展性的解决方案
FieldValue.increment ()
截至2019年4月,Firestore现在允许增量计数器,完全原子,无需事先读取数据。这确保了即使同时从多个源进行更新(以前使用事务解决)也能获得正确的计数器值,同时还减少了执行的数据库读取次数。
通过监听任何删除或创建的文档,我们可以向数据库中的计数字段添加或删除。
参见firestore文档-分布式计数器 或者看看杰夫·德莱尼的《数据聚合》。他的指南对于任何使用AngularFire的人来说都是非常棒的,但他的课程也应该适用于其他框架。
云功能:
export const documentWriteListener = functions.firestore
.document('collection/{documentUid}')
.onWrite((change, context) => {
if (!change.before.exists) {
// New document Created : add one to count
db.doc(docRef).update({ numberOfDocs: FieldValue.increment(1) });
} else if (change.before.exists && change.after.exists) {
// Updating existing document : Do nothing
} else if (!change.after.exists) {
// Deleting document : subtract one from count
db.doc(docRef).update({ numberOfDocs: FieldValue.increment(-1) });
}
return;
});
现在在前端,你可以查询这个numberOfDocs字段来获得集合的大小。