我有一个companies
的集合,并且在每个公司文档中,我都有一个appointments
的集合。我想在一个云函数中遍历所有appointments
的所有companies
,因此我正在使用以下收集组查询:
db.collectionGroup('appointments')
.get()
.then((querySnapshot: any) => {
querySnapshot.forEach((appointmentDoc: any) => {
const appointment: Appointment = appointmentDoc.data();
appointmentDoc.ref.parent.parent.get().then((companyDoc: any) => {
const company: Company = companyDoc.data();
...
});
});
});
您可以看到,在每次迭代中,我也都获得了约会来自的公司的数据。这可行,但是我担心性能。如果我有500个约会,那么此方法基本上不是对数据库进行501调用(对约会进行1次调用,然后获取所有500个约会的公司数据)吗?有没有一种更好的方法可以访问该父数据,所以我不会进行所有这些额外的调用?如果我可以按比例扩展此方法,那就太好了。
无法与appointments
集合中的文档同时获取父文档。
您唯一可以做的是将文档ID分成10组,然后对它们进行IN
query。但是我怀疑是否值得付出努力,因为电汇流量可能几乎相同。
请注意,尽管性能通常与通话次数没有线性关系,所以请在进行优化之前进行测试。另请参阅IN
。
也:请考虑一下为什么一次需要500个文档。通常,您将需要加载筛选的数据,这似乎要多得多。有关Firestore中数据建模的一般提示,我推荐Google Firestore - how to get document by multiple ids in one round trip?的第一集。
Firestore实际上不会根据查询数向您收费。它基于文档读取次数。因此,如果您有500个约会,那么您的代码将读取1000个文档,因为它为每个约会文档读取一次公司文档。
您可以做的只是只读取一次每个公司文档total,而不是一次针对该公司的每次约会。您可以使用以下方法在内存中维护高速缓存:
Getting to know Cloud Firestore
尽管这是不完整的,因为内部查询仍然是异步的,并且将继续以约会迭代器可以运行的速度查询公司。您将必须以某种方式对内部查询进行序列化,或者按公司ID对约会进行分组,然后对这些组进行迭代,以免多次获取公司文档。
但是我希望您在这里有了一个想法,即使用内存缓存可以节省您的文档读取。
我使用了非常分层的结构,看起来会遇到类似的问题,但是...
...对于像Firestore这样的NoSQL数据库,您必须放弃DRY的SQL要求。如果数据是静态的(例如,您实际需要进行约会的任何“公司”数据),则您绝对可以并且应该复制该数据。
例如,您可以将结构简单地添加到附件文档中:
// cache of companies identified by their document ID
const companies: { [key: string]: Company } = {}
db.collectionGroup('appointments')
.get()
.then((querySnapshot: any) => {
querySnapshot.forEach((appointmentDoc: any) => {
const appointment: Appointment = appointmentDoc.data();
const parentRef = appointmentDoc.ref.parent.parent
const companyId = parentRef.id
let company: Company
if (companies[companyId]) {
company = companies[companyId]
// work with cached company here
}
else {
parentRef.get().then((companyDoc: any) => {
company: Company = companyDoc.data();
companies[companyId] = company
// work with queried company here
});
}
});
});
是的,这使用存储空间。所以? Firestore通常不收取少量的额外存储费用,并且收取新副本的费用[[does。由于此数据不会动态更改,因此在创建约会文档时将其添加到约会文档中效率更高。
应该为动态数据保留文档提取。appointmentSchema = {
....
....
company: {
id: {string},
name: {string},
location: {string}
}
}
...,您可以直接解析此字符串以在文档路径的任何地方up查找集合名称和documentId。我也经常使用它。