Firestore子集合与数组

时间:2019-04-30 18:39:20

标签: firebase google-cloud-firestore

首先,我知道Firestore的工作方式,并且花了很多时间,评估一种好的结构的不同方法。我仍然在考虑以下情形:

有一个已知配方的数据库。用户可以添加配方,但是必须确认它们是真实的配方,而不仅仅是一些变化。因此,每个用户都可以从用户生成的食谱列表中选择食谱,以表明自己知道如何烹饪(或添加新食谱)。

现在,我希望用户与其他人共享他们的食谱清单,但是在这里我不确定如何使用Firestore最好地做到这一点。诀窍是,我想一次显示所有食谱,并且不想对它们进行分页。

我目前正在评估两种可能性:

子集合

每当用户共享他的列表时,查看该列表的用户将必须加载食谱的整个列表,这可能导致大量的文档读取(我想实际上是〜50,在极少数情况下可能是1000)

优点:

  • 更自然的结构
  • 易于维护(例如删除食谱,检查是否存在特定食谱)
  • 更容易添加字段(例如timeOfCreation,comment,personalRating等)

缺点:

  • 从长远来看会导致大量读取

数组

我可以将每个已知配方(id和imageURL)保存在用户文档(或作为单个子文档“ KnownRecipes”)内的数组中。该数组可以采用

的形式
recipesKnown: [{rid: 293ndwa, imageURL: image1.com, timeAdded: 8371201332}, 
               {rid: 9012831, imageURL: image1.com, timeAdded: 8371201871},
               {rid: jd812da, imageURL: image1.com, timeAdded: 8371201118},
               ...
              ]

优点:

  • 只要有人想查看另一个用户的列表,我只需要阅读一个文档
  • 阅读用户列表可能更快

缺点:

  • 很难更新特定的配方(例如,某人想要更改imageURL:我需要在本地更改列表并将整个文档作为更新发送到服务器-因为我不能只更改数组中的单个元素)
  • 当用户决定拥有大约1000个配方时(这可能永远不会发生,但是有可能),可以达到Firestore限制的1MiB限制。可能的解决方法是创建一个单独的文档,然后将这两个数组拆分为这两个文档。

对于我来说,使用Subcollections的想法似乎是解决此问题的更“干净”的解决方案,但也许我缺少关于为什么其中一种解决方案优于另一种解决方案的争论。

我最常见的查询如下(按重要性降序排列):

  • 用户可以烹饪哪些食谱
  • 将用户可以烹饪的食谱添加到用户列表中
  • 谁可以烹饪特定的食谱(有食谱-> Cooks子集合)
  • 更新用户可以烹饪的现有食谱

3 个答案:

答案 0 :(得分:1)

我正在研究相同的问题...

问题之一是文档中保存的数据是否会超过1MB,这是文档的限制。研究一下它可以在1MB的纯文本格式中保存多少,这实在是太难了。即便如此,如果它要大得令人难以置信,它最终也会崩溃。因此,如果您以很大的方式思考子集合。

如果必须使用Firebase元素逻辑,答案将是子集合。

我仍然认为最主要的是要提取的数据。如果您致电该用户,您将直接提取该MB数据。而是使用子集合将不会加载,即使您加载了它也仍然可以延迟加载。

我猜您正在做子集合的那种设置。

答案 1 :(得分:0)

问题的答案取决于您想要实现的可扩展性水平。

如果通过设计要存储的子数据量有限且非常低,则应使用数组,因为您减少了文档读取次数,这意味着成本更低。

如果您的子数据应该随着时间的推移“无限地”增加,您应该使用子集合。

如果您要构建的数据库不应该向任何方向扩展(概念证明、非常小的企业等),请选择您觉得更舒服的方式。

答案 2 :(得分:0)

key 是额外的 collection 的缺点/优点

key 可以帮助避免重复;但这需要考虑什么是重复的定义(可能会改变);

array 的无键行为可以通过 auto-id 模拟。

附言@Thomas 在问题中的优缺点列表非常有帮助。