替代Firestore中的嵌套文档-是否在寻找最佳实践?

时间:2019-04-07 07:58:01

标签: firebase data-structures google-cloud-firestore

我对基于Firestore的项目的结构有些担心,因为直接嵌套文档似乎不是一种选择。

为简单起见,假设我们有一个Firestore数据库,其中包含有关足球比赛的数据。对于每场比赛,都有一个包含球员阵容的文件,一个包含比赛事件列表的文件,一个包含比赛统计信息的文件等。

由于统计信息,事件和阵容等信息是在不同的时间间隔更新,从不同的API调用导入并在使用应用程序的单独屏幕中使用的,因此我认为将它们保存在单独的文档中是最明智的做法。

我目前正在使用这样的结构:

/app-data/match-lineup/matches/123456
/app-data/match-events/matches/123456
/app-data/match-statistics/matches/123456

然后我这样指代它:

      db.collection("app-data")
      .doc("match-lineups")
      .collection("matches")
      .doc(id);

但是当我添加与比赛相关的更多不同文档时,我开始担心当前结构是否为反模式。

我更喜欢这样的结构,我发现它最优雅,并且与REST URL相似。

/matches/123456/lineup

但这不是一个选择,因为123456无法引用lineup文档。

解决方法可能类似于

/matches/123456/attributes/lineup

带有这样的参考

      db.collection("matches")
      .doc(id);
      .collection("attributes")
      .doc("lineup")

这是最好的折衷方案,还是应该考虑其他选择?

1 个答案:

答案 0 :(得分:2)

在NoSQL数据库中对数据建模时,永远不会有最佳和独特解决方案。

恕我直言,您的两种方法是完全有效的,因为每个集合中包含的数据都将“在使用中的应用程序的单独屏幕中使用”(即,没有理由将所有数据“集中”在一个文档中,正如您提到的)。在查询效率方面,两种方法相似。

但是,您可能还要考虑其他条件:(在撰写本文时)您不能查询跨馆藏。当您需要查询所有比赛时,例如在阵容中与特定球员的所有比赛或与eventType == "penalty"的所有比赛时,您可能会遇到用例。在这种情况下,您应该使用方法#1(即/app-data/match-lineup/matches/123456),因为使用方法#2不可能在匹配项中进行此类查询。