是否可以使用新的Firebase数据库Cloud Firestore来计算一个集合有多少项?
如果是,我该怎么做?
是否可以使用新的Firebase数据库Cloud Firestore来计算一个集合有多少项?
如果是,我该怎么做?
当前回答
FireStore现在支持该功能,尽管是Beta版。 下面是Firebase的官方文档
其他回答
使用admin. keystore . fieldvalue . Increment增加一个计数器:
exports.onInstanceCreate = functions.firestore.document('projects/{projectId}/instances/{instanceId}')
.onCreate((snap, context) =>
db.collection('projects').doc(context.params.projectId).update({
instanceCount: admin.firestore.FieldValue.increment(1),
})
);
exports.onInstanceDelete = functions.firestore.document('projects/{projectId}/instances/{instanceId}')
.onDelete((snap, context) =>
db.collection('projects').doc(context.params.projectId).update({
instanceCount: admin.firestore.FieldValue.increment(-1),
})
);
在本例中,每次将文档添加到instances子集合时,我们都会增加项目中的instanceCount字段。如果该字段还不存在,它将被创建并增加到1。
增量在内部是事务性的,但如果需要更频繁地递增,则应该使用分布式计数器。
通常最好实现onCreate和onDelete而不是onWrite,因为你将调用onWrite进行更新,这意味着你在不必要的函数调用上花费了更多的钱(如果你更新了你的集合中的文档)。
据我所知,目前还没有内置的解决方案,只能在节点sdk中实现。 如果你有
db.collection('someCollection')
你可以使用
.select([fields])
定义要选择的字段。如果执行空select(),则只会得到一个文档引用数组。
例子:
db.collection (someCollection) .select () . get () ( (snapshot) => console.log(snapshot.docs.length) );
此解决方案只是针对下载所有文档的最坏情况的优化,并且不能扩展到大型集合!
再看看这个: 如何获得在一个集合与云Firestore的文件的数量计数
截至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)
}
解决办法是:
在firebase文档中编写一个计数器,每次创建新条目时都在事务中增加计数器
您将计数存储在新条目的字段中(即:position: 4)。
然后在该字段上创建一个索引(position DESC)。
您可以对查询执行跳过+限制操作。Where("position", "<" x).OrderBy("position", DESC)
希望这能有所帮助!
不,目前还没有内置的聚合查询支持。然而,有几件事你可以做。
这里记录了第一个。您可以使用事务或云函数来维护聚合信息:
这个例子展示了如何使用一个函数来跟踪子集合中的评级数量,以及平均评级。
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中可用,因此该解决方案不适用于移动应用程序。