Firestore - 最适合我的场景的数据结构是什么?

enl*_*One 2 google-cloud-firestore

我正在为我的应用程序寻找最佳架构。我应该选择顶级集合、子集合、数组等吗?

设置:

  1. 我的应用程序将有许多用户将参与的测验。
  2. 每个测验都会有多个问题。
  3. 每个问题都有多个答案,只能选择一个。
  4. 每个用户只能回答每个测验一次。

要求:

  1. 我需要存储每个用户的响应并能够在用户级别进行报告。
  2. 我需要查看每个测验、每个问题、答案数量的汇总结果。

任何帮助表示赞赏。

Dan*_*ein 5

我认为从基础开始,希望整个过程都有凝聚力。以下每个部分似乎都是独立工作的,您可能会发现将某些内容放在文档中而不是它们自己的集合中,或者维护子集合而不是根集合等是有意义的:

  • 每个测验都可以在测验集合中拥有自己的文档。
  • 每个问题(及其潜在答案)都可以在集合问题中拥有自己的文档。
  • 问题的 每个答案都可以在答案集合中拥有自己的文档,以避免将答案与问题一起存储。
  • 每个用户,用户中
  • 用户/测验中每个用户的答案

您可以考虑将问题嵌套在测验中,但您可能希望将它们保留为根级别,以便您可以轻松地在多个测验中重复使用问题。

因此,可能值得在每个问题的文档中保留一个该问题所属的测验的数组。

然后,您可以执行如下查询来获取测验的所有问题:

db.collection('questions').where('quizzes','array-contains', quizId)
Run Code Online (Sandbox Code Playgroud)

这将为您提供每个测验的所有问题并满足您的第二个要求(第一个要求已经满足)。

这些问题会带来潜在的答案,我认为每个问题都应该有自己的身份。像这样:

-- question1
----- "Do you xyz?"
----- potentialAnswers
--------- { id: xyz123, answer: "Yes" }
--------- { id: wxy456, answer: "No" }
Run Code Online (Sandbox Code Playgroud)

这允许您做的是获取用户给出的每个答案,并查询以查看答案数据库中是否存在匹配项。

到目前为止我很喜欢这一点,因为它允许您查询所有问题,并在一个查询/一个有组织的列表中获得所有潜在的答案。您可以在显示潜在答案时重新排列它们,因此多项选择的每次显示中的“C”不需要始终是相同的“C”。只要您比较时 ID 匹配,就可以确定。

该比较可能如下所示:

db.collection('answers').where('questionId','==', 'question1').where('answerId', '==', 'xyz123')
Run Code Online (Sandbox Code Playgroud)

如果您收到带有这样的查询的返回文档,那么他们的回答是正确的。

对于用户给出的每个答案,我都会将其标记在每个用户的子集合中,其中 quizId 是文档的 ID。因此,在 user1 下,他们将有一个名为测验的集合。

当用户回答时,您可以将他们给出的答案推送到该用户的测验文档中的地图。这可能看起来像这样:

-- user1
----- quizzes
-------- quiz1
----------- progress: 2/25
----------- complete: true
----------- score: 1/2
----------- answers
-------------- { questionId: question1, answer: xyz123, correct: true }
-------------- { questionId: question2, answer: rst456, correct: false }
Run Code Online (Sandbox Code Playgroud)

对于您希望用户参加的每个测验,只要 {userID}/quizzes} 中不存在具有该 quizID 的文档(并且complete=true),他们就可以开始它,或继续参加它,等等。

这比大多数人得到的要多,所以希望它有帮助。有些事情可能需要进一步充实,其他人可能有不同的意见,但我喜欢这些练习。