我有零级的Firestore经验,并且来自SQL背景。我使用SQL编写了一个应用程序,该应用程序似乎运行良好,但是我对如何使用Firestore的NoSQL方法复制设计感到困惑。
说我有一支拥有很多比赛的球队。那个团队有很多球员。每个游戏都有很多玩家。
现在说我想存储每个游戏中每个玩家的统计信息以及每个玩家的累积统计信息。
在SQL中,我会将统计信息存储在单独的表中:viewModel.navigationArgs.observe(this, Observer{
//navigation code
if (it != null) //don't call finishedNavigating, when null passed in to _navigationArgs.value
viewModel.finishedNavigating()
})
表(每个游戏的统计信息),并将每个游戏的统计信息添加到gameResults
表(累积统计信息)中。
在Firestore中,我将如何高效地实现同一目标?
我当时正在考虑以各个团队作为文档的players
根集合,然后是每个团队的两个同级子集合:teams
和games
(后者用于累积玩家统计信息)。每个players
文档(单个游戏)将具有另一个子集合,也称为games
,该子集合将为每个玩家提供该特定游戏的统计信息。我会将每个玩家的游戏统计信息复制到累积统计信息players
子集合中。不知道这是否是Firestore中效率低下/不合适的设置。如果是这样,建模的最佳方法是什么?
答案 0 :(得分:0)
我认为您只需要四个根集合,
1)团队
2)个玩家
3)游戏
4)player_status
答案 1 :(得分:0)
Firestore是NoSQL数据库,@ pepe是正确的。对于最佳实践,最好是对于要存储的每种信息类型具有不同的根集合。但是,我也将发布此答案,以详细说明您的数据库到底看起来像什么,以及如何将数据存储在那里。
Firestore的工作方式:
Firestore具有收藏集,文档,字段。
例如,如果您想存储联系信息,可以这样做:
集合:“联系人”> 文档:“ UNIQUE_ID”>字段:名称: STRING,名称: STRING,移动: NUMBER
数据将像这样保存:
contacts > UNIQUE_ID_01 > Name: Andrew
Sname: Williams
Mobile: 99741258
UNIQUE_ID_02 > Name: Margaret
Sname: Smith
Mobile: 99451236
如您所见,每个联系人都有其自己的UNIQUE ID,该ID可以在创建文档时自动生成,也可以使用API生成。然后,每个文档就是您要存储的有关此联系人的所有信息。
现在,这将帮助您在不想再次存储相同信息的其他集合中建立关系,而只需保存参考UNIQUE ID。例如,您正在为公司做一个集合,其中的联系人在那工作。无需在公司的子文档中具有将再次具有名称,名称,移动电话等的字段,而是将每个联系人的所有唯一ID存储在单个数组字段中。然后,如果您想查找联系人的信息,则对每个文档ID进行新查询,然后获取所需的数据。
首先,建议写下要存储的数据并指定它们之间的关系:
类型:
您要更新:
现在,您指定要保存的信息类型将成为您的根集合。
收藏集:“团队”> 文档:“ UNIQUE_TEAM_ID”>字段:标题: STRING,玩家: ARRAY, Team_stats :NUMBER
收藏集:“游戏”> 文档:“ UNIQUE_GAME_ID”>字段:标题: STRING,日期:时间戳,玩家:阵列,团队:阵列
收藏集:“玩家”> 文档:“ UNIQUE_PLAYER_ID”>字段:名称: STRING,姓氏 > STRING,移动:NUMBER, Stats_all_games :NUMBER
Players > UNIQUE_PLAYER_ID_01 > Name: Andrew
Surname: Williams
Mobile: 99784512
Stats_all_games: 75.0
UNIQUE_PLAYER_ID_02 > Name: Margaret
Surname: Smith
Mobile: 99451236
Stats_all_games: 75.0
Teams > UNIQUE_TEAM_ID_01 > Title: Awesome Team
Players: [UNIQUE_PLAYER_ID_01, UNIQUE_PLAYER_ID_02]
Team_stats: 95.0
UNIQUE_TEAM_ID_02 > Title: Another Awesome Team
Players: [UNIQUE_PLAYER_ID_03, UNIQUE_PLAYER_ID_04]
Team_stats: 46.0
Games > UNIQUE_GAME_ID_01 > Title: Team 1 vs Team 2
Date: 1576593460
Teams: [UNIQUE_TEAM_ID_01, UNIQUE_TEAM_ID_02]
Players: [UNIQUE_PLAYER_ID_01, UNIQUE_PLAYER_ID_02 ...]
UNIQUE_GAME_ID_01 > Title: Team 3 vs Team 4
Date: 1576593460
Teams: [UNIQUE_TEAM_ID_03, UNIQUE_TEAM_ID_04]
Players: [UNIQUE_PLAYER_ID_15, UNIQUE_PLAYER_ID_16 ...]
因此,想法是将唯一的ID存储在数组中,因此,例如,当查询团队的每个状态时,您将仅获取有关团队的数据以及必要时用于创建新查询的必要数据。
例如,您可以查询以查看日期1576593460之后的所有游戏。当数据作为快照加载时,如果您想获取团队的信息,则可以获取ID,然后可以再次查询这些ID以获取团队的信息。如果还需要查看玩家,则在检索到的数据中也包含所有玩家ID,因此您可以按人查询并获得每个玩家的个人数据。
这或多或少是我将实现此目标的方式。毫无疑问,还有许多其他选择,甚至还有关于如何使用Firestore的更好实践。但是,如果您喜欢这种方法并更好地理解它,那么可以使用您的逻辑来实现
答案 2 :(得分:0)
其他答案似乎已经回答了问题。但是,如果您还想拥有python后端,则可以改进查询数据的步骤。请参阅我目前正在开发的framework中的MeetingSession
示例。如果您使用flask-boiler
,则后端将处理
您可以查询以查看日期1576593460之后的所有游戏。将数据作为快照加载时,如果您想获取团队的信息,则可以使用ID,然后可以再次使用这些ID查询以获取信息的团队。如果还需要查看玩家,则在检索到的数据中也包含所有玩家ID,因此您可以按人查询并获得每个玩家的个人数据。
并将结果存储在已归一化的单个document
中。前端只需要访问文档aggregated_game_id_01
。这样可以减少用例中的延迟,但是还有其他缺点,例如存储不必要的数据。
因此,除了其他答案中提到的根集合之外,您还可以使用flask-boiler
TeamsView > UNIQUE_TEAM_ID_01 > Title: Awesome Team
Players: {UNIQUE_PLAYER_ID_01: {
Name: Andrew
Surname: Williams
Mobile: 99784512
Stats_all_games: 75.0}
UNIQUE_PLAYER_ID_02: {
Name: Margaret
Surname: Smith
Mobile: 99451236
Stats_all_games: 75.0}
}
Team_stats: 95.0
希望这为您提供了查询数据的附加选项。如果您需要更多说明,请告诉我。谢谢。