文档与收藏

时间:2019-06-19 17:03:51

标签: flutter google-cloud-firestore

我在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将文档放入集合中,这似乎会更快。

所以我无法确定要采取哪种方法。使用集合将在某种程度上更合乎逻辑,因为我将永远不会在任何限制下运行,并且加载似乎更快,但是从计费的角度来看,嵌套这些部分更有意义。

哪种选择更好?

1 个答案:

答案 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

优势:

  1. 这将帮助您在每个部分中添加很多页面。
  2. CourseSection可以按需读取,因此您在读取Course时不需要阅读所有部分。

最终,选择取决于您拥有的用例。

希望这会有所帮助。