哪种社会媒体供稿是最理想的Firestore模式?

时间:2019-06-11 20:41:30

标签: firebase google-cloud-firestore

我想将Firestore用于社交媒体供稿的方法有很多。到目前为止,我尚未提出想法,因此,对于这一想法,我希望能得到社区的反馈。

该想法是允许用户发布信息或记录其活动,并向关注/订阅该信息的任何用户显示该信息。帖子信息将存储在名为posts的根集合中。

据我所知,这些方法所需的读写次数大致相同。

一个想法是在users/{userId}中有一个称为posts的字段,该字段是我有兴趣为用户提取的documentId数组。这样一来,我就可以直接从posts中提取数据,并获取最新版本的数据。

另一种方法似乎更像Firebasey,该方法是将文档存储在作为帖子本身副本的users / {userId} / feed中。我可以使用与postID中的数据相同的posts。大概,如果需要更新任何评论的数据,则可以使用组集合查询来获取所有被称为feed的集合,其中docID相等(或者只是创建一个字段来执行正确的"where", "==", docId)。 / p>

第三种方法就是更新应查看帖子的人员列表。只要帖子列表比关注者列表短,这似乎更好。而不是维护每个关注者的所有帖子,而是维护每个帖子的所有关注者。对于每个新关注者,您需要更新所有帖子。

此列表将不是用户自己的帖子。相反,它将是显示该用户的所有帖子的列表。

三个挑战者:

  1. users / {userId},其字段名为feed-指向全局帖子的文档ID数组。获取该供稿,按ID获取所有文档。每次用户有活动时,都需要为每个关注者更新每个数组。

    users (coll)
        -> uid (doc)
        -> uid.feed: postId1, postId2, postId3, ...] (field)
    
    posts (coll)
        -> postId (doc)
    

查询(伪):

doc(users/{uid}).get(doc)
    feed = doc.feed
    for postId in feed:
        doc(posts/{postId}).get(doc)
  1. users / {userId} / feed,其中包含您希望该用户查看的所有posts的副本。每个活动/帖子都需要添加到每个相关的供稿列表中。

    users (coll)
        -> uid (doc)
             -> feed: (coll)
                   -> postId1 (doc)
                   -> postId2
                   -> postId3
    
    posts (coll)
        -> postId (doc)
    

查询(伪):

collection(users/{uid}/feed).get(docs)
    for post in docs:
        doc(posts/{post}).get(doc)
  1. users / {userId} / feed,其中包含您希望该用户查看的所有posts的副本。每个活动/帖子都需要添加到每个相关的供稿列表中。

    users (coll)
        -> uid (doc)
    
    
    posts (coll)
        -> postId (doc)
        -> postId.followers_array[followerId, followerId2, ...] (field)
    

查询(伪):

collection(posts).where(followers, 'array_contains', uid).get(docs)

读取/写入

1。更新数据 对于每个活动的作者user,找到所有关注此活动的用户 用户。当前,用户作为文档存储在集合中,因此这是followerNumber文档读取的内容。对于每个用户,通过在postId前面添加这将是followerNumber文档写入来更新其数组。

1。显示数据/ Feed 对于提要的每次获取:从用户文档中获取数组(读取1个文档)。对于每个postId,请致电posts/{postId}

这将是numberOfPostsCalled文档读取。

2。更新数据 对于每个活动的作者user,找到所有关注此活动的用户 用户。当前,用户作为文档存储在集合中,因此这是followerNumber文档读取的内容。对于每个用户,将ID为postId的新文档添加到users/{userId}/feed中,这将是followerNumber文档写入。

2。显示数据/ Feed 对于提要的每次获取:从users/{userId}/feed

获取一定数量的帖子

这将是numberOfPostsCalled文档读取。

第二种方法要求我在进行编辑时使所有文档保持最新。因此,尽管这种方法看起来更像是火力四射的方法,但保持postId并直接获取的方法似乎更合乎逻辑。

3。更新数据 对于每个新关注者,需要更新被关注者撰写的每个帖子。新的关注者将追加到名为关注者的数组中。

3。显示数据 对于提要的每次获取:从posts获得一定数量的帖子,其中uid == viewerUid

2 个答案:

答案 0 :(得分:1)

很好,当我谈论最佳选择时,我真的需要一个点或一个质量属性进行比较,我会假设您关心速度(不是必要的性能)和成本。

这就是我要解决的问题,它涉及多个集合,但我的目标是仅1个查询。

用户(col)

{
 "abc": {},
 "qwe": {}
}

帖子(col)

{
  "123": {},
  "456": {}
}

users_posts(col)

{
  "abc": {
    "posts_ids": ["123"]
  }
}

到目前为止,问题是,我需要做几次查询才能获取所有帖子信息...这是云函数进入游戏的地方。您可以创建第4个集合,在其中可以预先计算Feed

users_dashboard

{
  "abc": {
    posts: [
    {
       id: "123", /.../
    }, {
       id: "456", /.../
     }
    ]
  }
}

云功能如下:

/* on your front end you can manage the add or delete ids from user posts */
export const calculateDashboard = functions.firestore.document(`users_posts/{doc}).onWrite(async(change, _context) {
   const firestore = admin.firestore()
   const dashboardRef = firestore.collection(`users_dashboard`)
   const postRef = firestore.collection(`posts`)

   const user = change.after.data()
   const payload = []
   for (const postId of user.posts_ids) {
      const data = await postRef.doc(postId).get().then((doc) => doc.exists ? doc.data() : null)
      payload.push(data)
   }
   // Maybe you want to exponse only certain props... you can do that here
   return dashboardRef.doc(user.id).set(payload) 
})

文档的最大大小为1 MiB (1,048,576 bytes),可以存储大量数据,因此您在此处可以看到很多帖子。让我们谈谈费用;我以前认为firestore更像是有几个小型文档,但实际上我发现它在将大量文档添加到大型文档中时效果很好。

现在在仪表板上,您只需要查询:

const dashboard = firestore.collection(`users_dashboard`).doc(userID).get()

这是解决此问题的一种很自以为是的方法。您可以避免使用users_posts,但是除了发布相关更改之外,您可能不想触发此过程。

答案 1 :(得分:0)

在这种情况下,似乎第二种方法最好。.我真的不明白@andresmijares想要做什么,他提到了将帖子存储在文档中的方法,这不是一个好方法,想象一下是否有如果超过2万个帖子(我认为文档可以容纳该帖子),则该文档将无法存储更多数据。更好的方法是将帖子作为文档存储在集合中(就像您在第二个选项中一样) ..因此,让我们回顾一下最佳方法是什么。

1)_您在(帖子“收藏集”)和您正在关注的用户(订阅源“收藏集”)中分享了一个帖子。.也许这可以通过云功能来完成,我们不要忘记进行汇总(使用云功能)还需要显示在用户个人资料中的帖子数。

2)_您关注某个用户,并将其所有帖子从(帖子“收藏”)放入您的(Feed“收藏”),这样您就可以在供稿上查看其所有帖子。

使用这种方法,一次写入很多,但是读取很快。如果您的应用要读取更多而写入更少,那么除非我错了,否则不必担心。