我在和菲特瑞搏斗。问题是如何构造数据,而不陷入计费陷阱/噩梦。
我有以下数据结构:
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"}
]
...
]那我只收一本书的费用。最有可能的是,我不会遇到40000个属性限制,也不会达到1MB的限制。
但是,使用FutureBuilder从文档中加载数据似乎需要一些时间,如果我使用StreamBuilder获取集合中的文档,这似乎会更快。
所以我不知道该采取哪种方法。使用集合可能会更符合逻辑,因为我永远不会在任何限制下运行,而且加载速度似乎更快,但从记帐的角度来看,嵌套这些部分会更有意义。
更好的选择是什么?
发布于 2019-06-20 12:00:12
我同意你的观点,当选择一个子集合的方法比传统的多个集合的方法是困难的。因此,当您决定选择子集合方法时,请记住以下情况。
何时使用子集合:
1)当您不想在文档中存储大量字段时。云修复有20,000个字段限制。(如果学校和课程信息超过20,000个字段)
2)更新父集合是常见的操作。Firestore只允许您以每秒1次的速度更新文档。(如果学校、课程和网页信息经常被修改)
3)当您想限制对文档的特定字段的访问时。(如果要限制对课程页面的访问,请执行以下操作。在这种情况下,将受限字段移动到另一个集合中的另一个文档也是一个好主意!)
不使用子集合时的:
1)当您想一起查询集合和子集合时。Firestore查询很浅。因此,当您查询父集合时,不会查询子集合,因此必须分别查询它们。(如果你有一个案例在一个窗口里展示所有的学校及其课程)
2)当你想在观看集合时显示子集合时(当你向一所学校展示时,你可能想显示它的课程。)在这里,读取的次数会增加,因为不是读取一个文档,而是一直读取一个文档及其子集合)。
3)当您想同时查询集合和子集合时。(您必须使用集合组查询,因为子集合本质上是集合。)
4)如果您正在考虑查询单个数据,您应该将它们放在一个集合中。(如果学校的特定属性通常由用户查询,或者某个课程的细节由多个用户查看)
我的建议:
Schools
- Array<CourseIds>
- Other infoSchools收集,存储学校信息,可以根据学校的质量搜索学校信息。学校信息还可以包含字段courses_available,它可以是单独存储课程名称及其unique id的数组或地图。
Courses
-Course infoCourses集合采用相同的方法,因为我假设课程信息将根据它们的属性进行大量查询。
CourseSections
-Course1Section1
-Pages
-Course1Section2
-Pages关于课程部分的信息的CourseSections集合,它有一个子集合Pages。
优势:
CourseSection可以按需读取,这样您就不需要在读取Course时阅读其所有部分。最终,选择取决于您拥有的用例。
希望这能有所帮助。
https://stackoverflow.com/questions/56672713
复制相似问题