优化检索由Firebase的Firestore中的另一个Collection分组的数据
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了优化检索由Firebase的Firestore中的另一个Collection分组的数据相关的知识,希望对你有一定的参考价值。
我的Firestore数据库中有两个集合,相当于:
// ItemCategories collection
{
id_category_1: {
name: 'Category 1',
},
id_category_2: {
name: 'Category 2',
},
id_category_3: {
name: 'Category 3',
},
// ...
}
// Items collection
{
id_item_1: {
CategoryId: 'id_category_1',
name: 'Item 1',
},
id_item_2: {
CategoryId: 'id_category_1',
name: 'Item 2',
},
id_item_3: {
CategoryId: 'id_category_3',
name: 'Item 3',
},
id_item_4: {
CategoryId: 'id_category_2',
name: 'Item 4',
},
// ...
}
我想检索和格式化我的项目按类别分隔,如下:
const ItemList = {
'Category 1': [
{
id: 'id_item_1',
CategoryId: 'id_category_1',
name: 'Item 1',
},
{
id: 'id_item_2',
CategoryId: 'id_category_1',
name: 'Item 2',
},
],
'Category 2': [
{
id: 'id_item_4',
CategoryId: 'id_category_2',
name: 'Item 4',
},
],
'Category 3': [
{
id: 'id_item_3',
CategoryId: 'id_category_3',
name: 'Item 3',
},
],
};
我目前正在处理一堆Promises:
// Function to retrieve Items for a given CategoryId
const getItemsByCategory = async CategoryId => {
const Items = await new Promise(resolve => {
firebase
.firestore()
.collection('items')
.where('CategoryId', '==', CategoryId)
.orderBy('name', 'ASC')
.onSnapshot(querySnapshot => {
const values = [];
querySnapshot.forEach(doc => {
values.push({
...doc.data(),
key: doc.id,
});
});
resolve(values);
});
});
return Items;
};
// Function to actually get all the items, formatted as wanted
export const getItemList = () => {
return dispatch => { // I'm in a Redux Action
const Items = {};
firebase
.firestore()
.collection('itemCategories')
.orderBy('name', 'ASC')
.get() // Categories can't be changed
.then(querySnapshot => {
const Promises = [];
querySnapshot.forEach(doc => {
const category = doc.data().name;
const P = new Promise(resolve => {
getItemsByCategory(doc.id).then(values => {
const result = {
category,
values,
};
resolve(result);
});
});
Promises.push(P);
});
Promise.all(Promises).then(values => {
values.forEach(v => {
Items[v.category] = v.values;
});
// Here I have the formatted items
console.log(Items);
//dispatch(setItemList(Items)); // Redux stuff
});
});
}
};
这段代码正在运行,但我觉得应该有办法优化它。我至少可以看到两个问题:
- 此代码进行(N + 1)个Firestore调用(其中N是类别的数量)。随着Firebase对每次通话收费,我无法看到这种扩展。
- 我们必须等待N个承诺实际显示数据;如果类别数量增长太多,执行时间可能会成为一个问题。
有没有比我更好的解决方案?
随着Firebase对每次通话收费,我无法看到这种扩展。
Firestore不会根据“电话”收费。它对读取的文档数量和传输的数据量收费。如果您需要阅读所有类别,那么您只需支付阅读该集合的大量文档。读取这些文档需要多少次调用无关紧要(例外情况是返回0结果的查询仍会导致一次读取)。
在实践中,在等待返回N个文档的1个查询或每个返回1个文档的N个查询之间没有太大的区别。您仍然只是在等待N个文档。使用Firestore时,没有任何查询无法很好地扩展。限制因素始终取决于收到的文件数量,而不是查询数量。您的代码主要花费时间等待结果传输。当然,你可以在记忆中拥有的东西有一个实际的上限,但承诺的数量并不是一件大事。
除此之外,我不明白为什么你在onSnapshot
使用getItemsByCategory
。好像你只想使用get()而不是只在侦听器中接收一个结果。你的代码会更加简单。
以上是关于优化检索由Firebase的Firestore中的另一个Collection分组的数据的主要内容,如果未能解决你的问题,请参考以下文章
检索数据时出现 Vue/Firestore/Firebase 错误
Android Studio Firebase Firestore 无法检索字段数据
如何从Swift中的Cloud FireStore Firebase访问特定字段
我可以通过哪些方法正确地在 Firebase Firestore 中的数据结构来建模多对多关系以检索 vue js 中的特定 uid