我在Firestore上挣扎。问题是如何构建数据,而又不会遇到计费陷阱/噩梦。
我具有以下数据结构:
school
course1
section1
page1
page2
section2
page1
page2
...
我认为一门课程通常不超过50个部分。
使用收藏集
所以我可以使用集合并为每个部分创建一个文档,其中包含每个部分的名称和描述。
db.collection("schools")
.document("school1")
.collection("courses")
.document("course1")
.collection("sections").snapshots()
文档结构:
name: "Section 1"
description: "Description 1"
但是,如果我需要显示这些部分的列表,则根据Firestore计费,每次读取文档都会收取费用。这意味着,如果有20个部分,我将为20次读取付费。
使用具有嵌套集合的文档
我也可以只创建一个“课程1”文档并嵌套所有部分。
db.collection("schools")
.document("school1")
.collection("courses")
.document("course1")
.get()
文档结构:
name: "Course 1"
description: "The description",
sections: [
{
name: "Section 1",
description: "Description 1"
pages: [
{name: "Page 1", description: "Page Description 1"},
{name: "Page 2", description: "Page Description 2"}
]
},
{
name: "Section 2",
description: "Description 2"},
pages: [
{name: "Page 1", description: "Page Description 1"},
{name: "Page 2", description: "Page Description 2"}
]
...
]
然后,我只会为阅读1次而付费。我很可能不会遇到40'000属性限制,也不会遇到1 MB限制。
但是使用FutureBuilder从文档中加载数据似乎需要一些时间,如果我使用StreamBuilder将文档放入集合中,这似乎会更快。
所以我无法确定要采取哪种方法。使用集合将在某种程度上更合乎逻辑,因为我将永远不会在任何限制下运行,并且加载似乎更快,但是从计费的角度来看,嵌套这些部分更有意义。
哪种选择更好?
答案 0 :(得分:1)
我同意您的看法,与传统的多重收集方法相比,选择子收集方法比较困难。因此,在决定选择子集合方法时,请记住以下几种情况。
何时使用子集合:
1)当您不想在文档中存储很多字段时。 Cloud Firestore有20,000个字段限制。 (如果“学校和课程”信息可以超过20,000个字段)
2)更新父集合时是常见的操作。 Firestore仅允许您以1个写入/秒的速度更新文档。 (如果“学校,课程和信息页”信息经常被修改)
3)当您想限制对文档特定字段的访问时。 (如果您想限制对课程页面的访问。在这种情况下,将限制的字段移至另一个集合中的另一个文档也是一个好主意!)
何时不使用子集合:
1)当您要一起查询集合和子集合时。 Firestore查询很浅。因此,在查询父集合时将不会查询子集合,因此必须单独查询它们。 (如果您有一个案例可以在一个窗口中显示所有学校及其课程)
2)当您要在查看收藏集时显示子收藏集。(显示学校时,您可能想要显示其课程。此处的阅读次数将增加,因为您正在阅读的不是阅读一个文档,而是阅读一个文档及其子集合)
3)当您要一起查询集合和子集合时(必须使用集合组查询,因为子集合本质上是集合。)
4)如果您要查询单个数据,则应将它们放在集合中。 (如果学校的特定属性通常是由用户查询的,或者课程的详细信息是由多个用户查看的)
我的建议:
Schools
- Array<CourseIds>
- Other info
Schools
集合用于存储学校信息,可以根据其质量在学校中搜索。学校信息还可以包含fields_available字段,该字段可以是一个数组或映射,用于单独存储课程名称及其unique id
。
Courses
-Course info
Courses
集合使用相同的方法,因为我假设将根据课程属性来查询课程信息。
CourseSections
-Course1Section1
-Pages
-Course1Section2
-Pages
CourseSections
集合以获取有关课程部分的信息,该部分具有子集合
Pages
。
优势:
CourseSection
可以按需读取,因此您在读取Course
时不需要阅读所有部分。 最终,选择取决于您拥有的用例。
希望这会有所帮助。