是否可以使用新的Firebase数据库Cloud Firestore来计算一个集合有多少项?
如果是,我该怎么做?
是否可以使用新的Firebase数据库Cloud Firestore来计算一个集合有多少项?
如果是,我该怎么做?
当前回答
不,目前还没有内置的聚合查询支持。然而,有几件事你可以做。
这里记录了第一个。您可以使用事务或云函数来维护聚合信息:
这个例子展示了如何使用一个函数来跟踪子集合中的评级数量,以及平均评级。
exports.aggregateRatings = firestore
.document('restaurants/{restId}/ratings/{ratingId}')
.onWrite(event => {
// Get value of the newly added rating
var ratingVal = event.data.get('rating');
// Get a reference to the restaurant
var restRef = db.collection('restaurants').document(event.params.restId);
// Update aggregations in a transaction
return db.transaction(transaction => {
return transaction.get(restRef).then(restDoc => {
// Compute new number of ratings
var newNumRatings = restDoc.data('numRatings') + 1;
// Compute new average rating
var oldRatingTotal = restDoc.data('avgRating') * restDoc.data('numRatings');
var newAvgRating = (oldRatingTotal + ratingVal) / newNumRatings;
// Update restaurant info
return transaction.update(restRef, {
avgRating: newAvgRating,
numRatings: newNumRatings
});
});
});
});
jbb提到的解决方案在您只想不频繁地计数文档时也很有用。确保使用select()语句来避免下载所有文档(当您只需要一个计数时,这是很大的带宽)。select()目前仅在服务器sdk中可用,因此该解决方案不适用于移动应用程序。
其他回答
不,目前还没有内置的聚合查询支持。然而,有几件事你可以做。
这里记录了第一个。您可以使用事务或云函数来维护聚合信息:
这个例子展示了如何使用一个函数来跟踪子集合中的评级数量,以及平均评级。
exports.aggregateRatings = firestore
.document('restaurants/{restId}/ratings/{ratingId}')
.onWrite(event => {
// Get value of the newly added rating
var ratingVal = event.data.get('rating');
// Get a reference to the restaurant
var restRef = db.collection('restaurants').document(event.params.restId);
// Update aggregations in a transaction
return db.transaction(transaction => {
return transaction.get(restRef).then(restDoc => {
// Compute new number of ratings
var newNumRatings = restDoc.data('numRatings') + 1;
// Compute new average rating
var oldRatingTotal = restDoc.data('avgRating') * restDoc.data('numRatings');
var newAvgRating = (oldRatingTotal + ratingVal) / newNumRatings;
// Update restaurant info
return transaction.update(restRef, {
avgRating: newAvgRating,
numRatings: newNumRatings
});
});
});
});
jbb提到的解决方案在您只想不频繁地计数文档时也很有用。确保使用select()语句来避免下载所有文档(当您只需要一个计数时,这是很大的带宽)。select()目前仅在服务器sdk中可用,因此该解决方案不适用于移动应用程序。
据我所知,目前还没有内置的解决方案,只能在节点sdk中实现。 如果你有
db.collection('someCollection')
你可以使用
.select([fields])
定义要选择的字段。如果执行空select(),则只会得到一个文档引用数组。
例子:
db.collection (someCollection) .select () . get () ( (snapshot) => console.log(snapshot.docs.length) );
此解决方案只是针对下载所有文档的最坏情况的优化,并且不能扩展到大型集合!
再看看这个: 如何获得在一个集合与云Firestore的文件的数量计数
聚合计数查询刚刚在Firestore中预览。
在2022年Firebase峰会上宣布:https://firebase.blog/posts/2022/10/whats-new-at-Firebase-Sumit-2022
摘录:
[开发人员预览]Count()函数:与新的计数函数 Firstore[原文],你现在可以得到匹配文件的计数当你 运行查询或从集合中读取,而不加载实际的 文件,这为你节省了很多时间。
他们在峰会上展示的代码示例:
在问答环节中,有人问了汇总查询的定价问题,Firebase团队给出的答案是,它的成本是读取价格的1 / 1000(四舍四入到最近的读取,详情见下面的评论),但将计算汇总的所有记录。
有了新版本的Firebase,您现在可以运行聚合查询了! 简单的写
.count().get();
在您的询问之后。
其中一个快速省钱的技巧是:-
创建一个文档并在firestore中存储一个“count”变量,当用户在集合中添加新文档时,增加该变量,当用户删除一个文档时,减少变量。如。 updateDoc(doc(db, "Count_collection", "Count_Doc"), {count: increment(1)});
注:计数用(-1)递减,用(1)递增
如何节省金钱和时间:-
你(firebase)不需要循环通过集合,浏览器也不需要加载整个集合来计数文档的数量。 所有的计数都保存在一个名为“count”或其他变量的文档中,因此使用不到1kb的数据,并且它只在firebase firestore中使用1次读取。