Firestore:如何通过计算在用户和全局级别上存储数据?

时间:2018-10-22 14:21:33

标签: database firebase google-cloud-firestore storage google-cloud-functions

我想知道在用户和全局级别将数据存储在Firestore中的最佳方法是什么,以便可以轻松检索和计算所有信息。

例如,假设您正在制作一个赛车应用程序,其中将您在赛道上的平均时间记录给特定用户,但您还希望使用该用户的平均时间与该用户所在位置的全球平均时间进行比较。 / p>

我正在考虑的设置是这样的:

全局Firestore数据

{
  Location: France,
  globalAverageTime: 6 minutes,
  numberOfParticipants: 2
}

用户Firestore数据

[
 {
   username: "firstuser",
   location: France
   time: 8 minutes
 },
 {
  username: "seconduser",
  location: France
  time: 4 minutes
 }
]

从本质上讲,容纳所有此类数据的最佳方法是什么?这样,每次用户更新轨道周围的个人平均时间时,都会根据该用户的位置和新时间来计算新的全球平均时间。因此,例如在上面的示例中,法国有两个“参与者数量”,一个为8分钟,一个为4分钟,因此该区域的平均时间为6分钟。

要运行这样的系统,最好的方法是使用云功能,该功能在每次更新用户数据后都会运行计算,然后更新全局数据?这也是设置系统的最佳方法,以便每个用户以后都可以将自己与平均值进行比较吗?

让我知道可以进行的任何改进,或者如何更改Firestore中数据的设置方式。

2 个答案:

答案 0 :(得分:1)

有趣的问题!我认为subcollections可能是这里的答案。

您可以通过几种不同的方式来解决问题。但是想到的第一个是:

请考虑以下顶级收藏集:

  • 用户
  • 曲目

“用户”集合包含由用户驱动的曲目,如下所示:

-- 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子集合中有很多用户的问题:如果您获取/ tracks / track_1集合,它会获取用户子集合。您必须专门获取该子集合才能检索该数据,这意味着您可以轻松检索一个轨道或多个轨道,而无需同时获取所有用户。

您可以了解有关交易here的信息。

从文档中

  

使用Cloud Firestore客户端库,您可以将多个操作分组为一个事务。当您要基于某个字段的当前值或某个其他字段的值更新该值时,事务很有用。您可以通过创建一个事务来增加计数器的数量,该事务读取该计数器的当前值,然后对其进行递增,然后将新值写入Cloud Firestore。

因此,您可以监视/tracks/{track_id}/users/{user_id}的功能,在该功能中,用户每次完成曲目并设置时间后,都可以使用新的平均值更新曲目

答案 1 :(得分:0)

恕我直言,您可以保持数据库结构不变。并回答您的问题:

  

要运行这样的系统,最好的方法是使用云功能,该功能在每次更新用户数据后都会运行计算,然后更新全局数据?

最好的解决方案是使用Cloud Function,因为您可以在服务器端计算这些数字。因此,您将能够自动运行后端代码,以响应Firebase功能和HTTPS请求触发的事件。在特定情况下,只有在这两个用户对象中的globalAverageTime属性之一发生更改时,才应更改time属性。

  

这也是设置系统的最佳方法,以便每个用户以后可以将自己与平均值进行比较吗?

我认为是的,因为您可以将客户端用户的最佳时间与全球时间进行比较。