Cloud Firestore 针对最少的 read/write 操作优化了数据库设置
Cloud Firestore optimized database setup for minimal read/write operations
我想知道我的数据库设置方式是否会导致过多的递归读取,从而导致读取操作的数量成倍增加。
我目前有一个用户集合,在每个用户文档中,我还有 3 个其他目录,goods
、bundles
和 parts
。例如,每个用户都有一个零件列表和一个捆绑包列表。
bundles
目录中的每个文档都有一个地图数组,每个地图中都引用了 parts
目录中的文档。
当我查询捆绑包时,我还想获取捆绑包中每个部分的详细信息。这需要我 运行 另一个 onSnapshot
吗?
这是一个例子:
数据库:
users (catalog)
userID
parts
partID1
partID2
partID3
bundles
bundleID1
title: "string",
parts: [
part:"/users/userID/parts/partID1,
qty: 1
]
parts: [
part:"/users/userID/parts/partID2,
qty: 1
]
parts: [
part:"/users/userID/parts/partID3,
qty: 1
]
获取捆绑包
initBundle(bid) {
const path = this.database.collection('users').doc('userID').collection('bundles').doc(bid);
path.ref.onSnapshot(bundle => {
const partsArr = [];
bundle.data().parts.forEach(part => {
part.part.onSnapshot(partRef => {
const partObj = {
data: partRef.data(),
qty: part.qty
};
partsArr.push(partObj);
});
});
const bundleObj = {
title: bundle.data().title,
parts: partsArr
};
this.bundle.next(bundleObj);
});
return this.bundle;
}
我为此使用 Ionic/Angular,所以当我 return 项目时,它需要是一个对象数组。我正在重新创建对象以包含此 init
上的每个部分。如您所见,对于捆绑包 return 中的每个部分,我都在做另一个 onSnapshot
。这对我来说似乎不正确。
让我恍然大悟的一件事是,我可能应该给用户打一个电话,而这反过来又 return 就是一切?但是那时我如何获得子目录?我不确定如何在不支付账单的情况下继续操作!
如果您执行嵌套 part.part.onSnapshot(partRef => {
侦听器,请务必管理这些侦听器。我知道三种常见的方法:
一旦您的外部 onSnapshot
侦听器消失,嵌套的侦听器也应该停止(因为可能不再需要它们的数据)。这是一种相当简单的方法,因为您只需要一个用于整个包的侦听器列表
或者,您可以根据外部侦听器中该部分的状态管理每个 "part" 侦听器,当 "part1" 的侦听器从捆绑包中消失时移除该侦听器。这可以成为一个高效的解决方案,但确实需要(相当多的)额外代码。
许多开发人员使用 get()
s 进行嵌套文档读取,因为这意味着无需管理。
我想知道我的数据库设置方式是否会导致过多的递归读取,从而导致读取操作的数量成倍增加。
我目前有一个用户集合,在每个用户文档中,我还有 3 个其他目录,goods
、bundles
和 parts
。例如,每个用户都有一个零件列表和一个捆绑包列表。
bundles
目录中的每个文档都有一个地图数组,每个地图中都引用了 parts
目录中的文档。
当我查询捆绑包时,我还想获取捆绑包中每个部分的详细信息。这需要我 运行 另一个 onSnapshot
吗?
这是一个例子:
数据库:
users (catalog)
userID
parts
partID1
partID2
partID3
bundles
bundleID1
title: "string",
parts: [
part:"/users/userID/parts/partID1,
qty: 1
]
parts: [
part:"/users/userID/parts/partID2,
qty: 1
]
parts: [
part:"/users/userID/parts/partID3,
qty: 1
]
获取捆绑包
initBundle(bid) {
const path = this.database.collection('users').doc('userID').collection('bundles').doc(bid);
path.ref.onSnapshot(bundle => {
const partsArr = [];
bundle.data().parts.forEach(part => {
part.part.onSnapshot(partRef => {
const partObj = {
data: partRef.data(),
qty: part.qty
};
partsArr.push(partObj);
});
});
const bundleObj = {
title: bundle.data().title,
parts: partsArr
};
this.bundle.next(bundleObj);
});
return this.bundle;
}
我为此使用 Ionic/Angular,所以当我 return 项目时,它需要是一个对象数组。我正在重新创建对象以包含此 init
上的每个部分。如您所见,对于捆绑包 return 中的每个部分,我都在做另一个 onSnapshot
。这对我来说似乎不正确。
让我恍然大悟的一件事是,我可能应该给用户打一个电话,而这反过来又 return 就是一切?但是那时我如何获得子目录?我不确定如何在不支付账单的情况下继续操作!
如果您执行嵌套 part.part.onSnapshot(partRef => {
侦听器,请务必管理这些侦听器。我知道三种常见的方法:
一旦您的外部
onSnapshot
侦听器消失,嵌套的侦听器也应该停止(因为可能不再需要它们的数据)。这是一种相当简单的方法,因为您只需要一个用于整个包的侦听器列表或者,您可以根据外部侦听器中该部分的状态管理每个 "part" 侦听器,当 "part1" 的侦听器从捆绑包中消失时移除该侦听器。这可以成为一个高效的解决方案,但确实需要(相当多的)额外代码。
许多开发人员使用
get()
s 进行嵌套文档读取,因为这意味着无需管理。