是否可以使用新的Firebase数据库Cloud Firestore来计算一个集合有多少项?
如果是,我该怎么做?
是否可以使用新的Firebase数据库Cloud Firestore来计算一个集合有多少项?
如果是,我该怎么做?
当前回答
自9.11.0版本以来,有一个新的内置函数getCountFromServer(),它在不实际下载文档的情况下获取结果集中的文档数量。
https://firebase.google.com/docs/reference/js/firestore_#getcountfromserver
其他回答
在2020年,Firebase SDK中还没有这个功能,但Firebase扩展(Beta)中有,不过设置和使用起来相当复杂……
合理的方法
帮手……(创建/删除似乎是多余的,但比onUpdate便宜)
export const onCreateCounter = () => async (
change,
context
) => {
const collectionPath = change.ref.parent.path;
const statsDoc = db.doc("counters/" + collectionPath);
const countDoc = {};
countDoc["count"] = admin.firestore.FieldValue.increment(1);
await statsDoc.set(countDoc, { merge: true });
};
export const onDeleteCounter = () => async (
change,
context
) => {
const collectionPath = change.ref.parent.path;
const statsDoc = db.doc("counters/" + collectionPath);
const countDoc = {};
countDoc["count"] = admin.firestore.FieldValue.increment(-1);
await statsDoc.set(countDoc, { merge: true });
};
export interface CounterPath {
watch: string;
name: string;
}
出口消防钩
export const Counters: CounterPath[] = [
{
name: "count_buildings",
watch: "buildings/{id2}"
},
{
name: "count_buildings_subcollections",
watch: "buildings/{id2}/{id3}/{id4}"
}
];
Counters.forEach(item => {
exports[item.name + '_create'] = functions.firestore
.document(item.watch)
.onCreate(onCreateCounter());
exports[item.name + '_delete'] = functions.firestore
.document(item.watch)
.onDelete(onDeleteCounter());
});
在行动
将跟踪构建根集合和所有子集合。
在/counters/ root路径下
现在收集计数将自动更新,最终!如果需要计数,只需使用收集路径并在其前面加上计数器即可。
const collectionPath = 'buildings/138faicnjasjoa89/buildingContacts';
const collectionCount = await db
.doc('counters/' + collectionPath)
.get()
.then(snap => snap.get('count'));
限制
由于此方法使用单个数据库和文档,因此每个计数器的Firestore约束为每秒更新1次。它最终将是一致的,但在添加/删除大量文档的情况下,计数器将落后于实际收集计数。
我同意@Matthew的观点,如果你执行这样的查询,成本会很高。
[开发者开始项目前的建议]
由于我们在一开始就预见到了这种情况,因此实际上可以用一个文档创建一个集合,即计数器,将所有计数器存储在一个类型为number的字段中。
例如:
对于集合上的每个CRUD操作,更新计数器文档:
当你创建一个新的集合/子集合时:(在计数器中+1)[1写操作] 当你删除一个集合/子集合时:(-1在计数器中)[1写操作] 当你更新一个现有的集合/子集合时,在counter文档上什么都不做:(0) 当你读取一个现有的集合/子集合时,在计数器文档上什么都不做:(0)
下一次,当您想要获得集合的数量时,您只需要查询/指向文档字段。[1读操作]
此外,你可以将集合的名称存储在一个数组中,但这将是棘手的,数组在firebase中的条件如下所示:
// we send this
['a', 'b', 'c', 'd', 'e']
// Firebase stores this
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}
// since the keys are numeric and sequential,
// if we query the data, we get this
['a', 'b', 'c', 'd', 'e']
// however, if we then delete a, b, and d,
// they are no longer mostly sequential, so
// we do not get back an array
{2: 'c', 4: 'e'}
所以,如果你不打算删除集合,你实际上可以使用数组来存储集合名称的列表而不是每次都查询所有的集合。
希望能有所帮助!
FireStore现在支持该功能,尽管是Beta版。 下面是Firebase的官方文档
Firestore引入了一个新的query .count(),它获取查询的计数而不获取文档。
这将允许简单地查询所有集合项并获得该查询的计数。
Ref:
Firebase 10 iOS SDK [JS SDK PR] (https://github.com/firebase/firebase-js-sdk/pull/6608)
目前,firebase只允许服务器端计数,如下所示
const collectionRef = db.collection('cities');
const snapshot = await collectionRef.count().get();
console.log(snapshot.data().count);
请不要,这是为nodeJS