我想知道在用户和全局级别在Firestore中存储数据的最佳方法是什么,以便所有信息都可以轻松检索并可以计算。
例如,假设您正在制作一个赛车应用程序,其中您的赛道平均时间记录给特定用户,但您还希望使用此用户的平均时间与该用户所在位置的全球平均值进行比较。
我正在考虑的设置是这样的:
全球数据恢复
{
Location: France,
globalAverageTime: 6 minutes,
numberOfParticipants: 2
}
用户恢复数据
[
{
username: "firstuser",
location: France
time: 8 minutes
},
{
username: "seconduser",
location: France
time: 4 minutes
}
]
因此,从本质上讲,存储所有这些类型数据的最佳方法是什么?因此,每次用户更新他们在轨道周围的个人平均时间时,都会根据该用户的位置和新时间计算新的全球平均值。例如,在上面的例子中,法国有两个"参与者人数",一个是8分钟,另一个是4分钟,因此该区域的平均时间是6分钟。
要运行这样的系统,最好的办法是使用云函数,在每次更新用户数据后运行计算,然后更新全局数据?这也是设置系统的最佳方式,以便每个用户以后可以将自己与平均值进行比较吗?
让我知道可以进行的任何改进,或者我应该如何更改在 firestore 中设置数据的方式。
有趣的问题!我认为子集合可能是这里的答案。
您可以通过几种不同的方式解决问题。但首先想到的是:
请考虑以下顶级集合:
- 用户
- 轨道
"users"集合包含由用户驱动的轨道,如下所示:
-- Users
-- user_1
-- tracks (object)
-- track_1: true (could also be a float instead of boolean, representing the completion time for the user)
-- track_2: true
-- track_5: true
然后在"曲目"集合中,您有以下内容:
-- Tracks
-- track_1
-- location
-- globalAverageTime
-- numberOfParticipants
-> 'users' (subcollection)
-- user_1 (document)
-- completionTime: 6.43
这样,每次将新文档写入轨道时,您都可以触发函数 ->用户通过事务进行子集合和更新。
编辑要回答有关在轨道子集合中有许多用户的问题:如果您获取/tracks/track_1 集合,它将不会获取用户子集合。您必须专门获取该子集合才能检索该数据,这意味着您可以轻松检索一个或多个曲目,而无需获取所有用户。
您可以在此处阅读有关交易的信息。
从文档中:
使用 Cloud Firestore 客户端库,您可以将多个操作分组到单个事务中。当您想要根据字段的当前值或其他字段的值更新字段的值时,事务非常有用。您可以通过创建一个事务来递增计数器,该事务读取计数器的当前值,递增计数器,然后将新值写入云 Firestore。
因此,您可以有一个监视/tracks/{track_id}/users/{user_id}
功能,每次用户完成曲目并设置时间时,您都会使用新的平均值更新曲目
恕我直言,您可以保持数据库结构不变。并回答您的问题:
要运行这样的系统,最好的办法是使用云函数,在每次更新用户数据后运行计算,然后更新全局数据?
最好的解决方案是使用云函数,因为您可以在服务器端计算这些数字。因此,您将能够自动运行后端代码,以响应由 Firebase 功能和 HTTPS 请求触发的事件。在您的特定情况下,仅当这两个用户对象中的time
属性之一发生更改时,才应更改globalAverageTime
属性。
这也是设置系统的最佳方式,以便每个用户以后可以将自己与平均值进行比较吗?
在我看来,是的,因为您将能够将客户端用户的最佳时间与全局时间进行比较。