是否可以使用新的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中可用,因此该解决方案不适用于移动应用程序。

其他回答

有了新版本的Firebase,您现在可以运行聚合查询了! 简单的写

.count().get(); 

在您的询问之后。

据我所知,目前还没有内置的解决方案,只能在节点sdk中实现。 如果你有

db.collection('someCollection')

你可以使用

.select([fields])

定义要选择的字段。如果执行空select(),则只会得到一个文档引用数组。

例子:

db.collection (someCollection) .select () . get () ( (snapshot) => console.log(snapshot.docs.length) );

此解决方案只是针对下载所有文档的最坏情况的优化,并且不能扩展到大型集合!

再看看这个: 如何获得在一个集合与云Firestore的文件的数量计数

Firebase/Firestore中的新功能提供了集合中的文档计数:

请参阅本线程以了解如何实现它,并提供了一个示例。

如何计算在一个集合中的Firebase Firestore与WHERE查询在react.js文档的数量

没有直接的选择。不能执行db.collection("CollectionName").count()。 下面是查找集合中文档数量的两种方法。

1:-得到集合中的所有文件,然后得到它的大小。(不是最好的解决方案)

db.collection("CollectionName").get().subscribe(doc=>{
console.log(doc.size)
})

通过使用上述代码,您的文档读取的大小将等于集合中的文档大小,这就是为什么必须避免使用上述解决方案的原因。

2:-创建一个单独的文档与在您的集合,将存储在集合中的文件的数量计数。(最佳解决方案)

db.collection("CollectionName").doc("counts")get().subscribe(doc=>{
console.log(doc.count)
})

上面我们创建了一个带有名称计数的文档来存储所有计数信息。您可以通过以下方式更新计数文档:—

在文档计数上创建一个触发器 在创建新文档时,增加counts文档的count属性。 删除文档时,递减counts文档的count属性。

w.r.t价格(文档读取= 1)和快速数据检索上述解决方案是很好的。

解决办法是:

在firebase文档中编写一个计数器,每次创建新条目时都在事务中增加计数器

您将计数存储在新条目的字段中(即:position: 4)。

然后在该字段上创建一个索引(position DESC)。

您可以对查询执行跳过+限制操作。Where("position", "<" x).OrderBy("position", DESC)

希望这能有所帮助!