Firestore 社交媒体好友请求数据模型

use*_*545 2 data-modeling nosql firebase google-cloud-platform google-cloud-firestore

我正在使用 Firestore 构建社交媒体应用程序,我想知道构建好友请求数据的最佳方法是什么。

\n

当用户 John 想要向 Mary 和 Anne 添加好友时,我是否创建一个名为的根集合friend_requests并添加 3 个文档:

\n
    \n
  1. 以 John\xe2\x80\x99s 作为键的文档,userId其值将是 Mary 和 Anne\xe2\x80\x99s 的对象,其中包含他们的请求userIdstatus请求(待处理/接受/拒绝)
  2. \n
  3. 以 Mary\xe2\x80\x99suserId作为键的文档和一个带有 JohnuserIdstatusof request对象的数组
  4. \n
  5. 以 Annes\xe2\x80\x99s 作为键的文档userId和一个带有 JohnuserIdstatusof request对象的数组
  6. \n
\n

现在,当安妮和玛丽接受好友请求时,我删除friend_requests集合中的所有三个文档,然后:

\n
    \n
  • 我为每个用户(在users根集合中)添加一个名为的子集合friends,其中包含已接受请求的朋友的 usersIds、displayNames 和 photoURL
  • \n
\n

或者

\n
    \n
  • 我是否应该创建另一个根集合friends,为每个用户提供一个包含朋友信息的文档?
  • \n
\n

它似乎有很多重复的数据,因此我正在尝试解决它并找到在 Firestore 中执行此操作的最佳和最有效的方法。任何建议将不胜感激,也许我的做法是错误的!

\n

Ale*_*amo 7

虽然 Dharmaraj 的解决方案肯定会起作用,但我认为还有一个更简单的解决方案,可以帮助您稍微减少读取次数。因此,我们假设userOne向 发送好友请求userTwo,并向userThree发送好友请求userOne

Firestore-root
  |
  --- users (collection)
  |    |
  |    --- $userOneUid (document)
  |    |     |
  |    |     --- //User data
  |    |
  |    --- $userTwoUid (document)
  |    |     |
  |    |     --- //User data
  |    |
  |    --- $userThreeUid (document)
  |          |
  |          --- //User data
  |
  --- requests (collection)
       |
       --- $userOneUid (document)
       |     |
       |     --- ownRequests (map)
       |     |      |
       |     |      --- $userTwoUid
       |     |             |
       |     |             --- displayName: "User Two"
       |     |             |
       |     |             --- photoUrl: "https://"
       |     |             |
       |     |             --- status: "requested"
       |     |
       |     --- friendRequests (map)
       |     |      |
       |     |      --- $userThreeUid
       |     |             |
       |     |             --- displayName: "User Three"
       |     |             |
       |     |             --- photoUrl: "https://"
       |     |             |
       |     |             --- status: "requested"
       |     |
       |     --- allFriends (map)
       |            |
       |            --- //All friends
       |
       --- $userTwoUid (document)
       |     |
       |     --- friendRequests (map)
       |            |
       |            --- $userOneUid
       |                   |
       |                   --- displayName: "User One"
       |                   |
       |                   --- photoUrl: "https://"
       |                   |
       |                   --- status: "requested"
       |
       --- $userThreeUid (document)
             |
             --- ownRequests (map)
                    |
                    --- $userOneUid
                           |
                           --- displayName: "User One"
                           |
                           --- photoUrl: "https://"
                           |
                           --- status: "requested"
Run Code Online (Sandbox Code Playgroud)

为了拥有扁平化架构,我没有在 User 对象下创建嵌套集合或嵌套映射,而是创建了一个名为 的单独顶级集合requests。在这个集合中,将有一些文档,用于管理用户自己的请求、好友请求和所有好友。

看到这个架构,您可能会想,哦,但是我如何才能在单个文档中添加如此大量的数据呢?即使我们仅限于在单个文档中存储最多1 Mib 的存储空间,但在存储此类简单对象时,我们也可以存储相当多的存储空间。但是,如果您担心空间问题,那么您应该考虑为每种情况创建单独的集合ownRequestsfriendRequestsallFriends。在本例中,为简单起见,我们假设所有数据都适合一个文档。

接下来,如您所见,我们在每个映射下存储了 User 对象的最少数据,其中键是 UID,值由三个字段表示。通过这种方式,您可以显示姓名和个人资料照片,以清楚地表明执行好友请求的用户。

现在,当userOne向 发送好友请求时userTwo,需要完成两个操作。第一个是在的地图userOne内添加,第二个是在其自己的地图下添加。friendRequestsuserTwouserTwoownRequests

在这两个朋友之间,我们现在有一个好友请求,这意味着您始终必须确保限制userTwo将好友请求发送到userOne。你怎么能这么做呢?$userTwoUid只需检查内部ownRequests是否存在即可userOne。如果您希望userOne能够取消好友请求,或者userTwo拒绝好友请求,那么只需恢复上述两个操作即可。

同样的规则也适用于本案userThree

关于显示数据,如果您想显示您自己的请求、好友请求或所有好友的列表,您需要进行一次数据库调用,这需要一次读取。但是,如果您需要加载用户的更多数据,那么当您单击该用户时,您可以执行另一个请求并加载该用户的所有数据,因为您已经知道 UID。

userTwo接受来自 的好友请求时userOne,只需将他们的对象移动到allFriends地图内即可。如果您愿意,您还可以继续添加bannerFriends,以防止其他一些用户发送好友请求。另请注意,这也只需要一次读取。

它似乎有很多重复的数据,因此我正在尝试解决它并找到在 Firestore 中执行此操作的最佳和最有效的方法。

当涉及到 Firestore 这样的 NoSQL 数据库时,对数据进行非规范化是一种非常常见的做法,为此我建议您查看我在以下帖子中的回答:

您还可以在其中看到构建此类数据库的其他解决方案。

  • 谢谢你这么详细的回答!非常感激 (2认同)