对于获取社交媒体供稿,哪个是最理想的Firestore模式? [英] Which is a more optimal Firestore schema for getting a Social Media feed?

查看:47
本文介绍了对于获取社交媒体供稿,哪个是最理想的Firestore模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm toying with several ideas for using Firestore for a social media feed. So far, the ideas I've had haven't panned out, so for this one I'm hoping to get the community's feedback.

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

The idea is to allow users to post information, or to record their activity, and to any user following/subscribed to that information, display it. The posts information would be in a root collection called posts.

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

The approaches, as far as I can tell, require roughly the same number of reads and writes.

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

One idea is to have within the users/{userId} have a field called posts which is an array of documentIds that I'm interested in pulling for the user. This would allow me to pull directly from posts and get the most up-to-date version of the data.

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

Another approach seems more Firebasey which is to store documents within users/{userId}/feeds that are copies of the posts themselves. I can use the same postID as the data in posts. Presumably, if I need to update the data for any review, I can use a group collection query to get all collections called feeds, where the docID is equal (or just create a field to do a proper "where", "==", docId).

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

Third approach is all about updating the list of people who should view the posts. This seems better as long as the list of posts is shorter than the lists of followers. Instead of maintaining all posts on every follower, you're maintaining all followers on each post. For every new follower, you need to update all posts.

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

This list would not be a user's own posts. Instead it would be a list of all the posts to show that user.

三个挑战者:

Three challengers:

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

  1. users/{userId} with field called feed - an array of doc Ids that point to the global posts. Get that feed, get all docs by ID. Every array would need to be updated for every single follower each time a user has activity.

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 的副本.每个活动/帖子都需要添加到每个相关的供稿列表中.

  1. users/{userId}/feed which has a copy of all posts that you would want this user to see. Every activity/post would need to be added to every relevant feed list.

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 的副本.每个活动/帖子都需要添加到每个相关的供稿列表中.

  1. users/{userId}/feed which has a copy of all posts that you would want this user to see. Every activity/post would need to be added to every relevant feed list.

users (coll)
    -> uid (doc)


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

查询(伪):

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

读取/写入

Reads/Writes

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

1. Updating the Data For the author user of every activity, find all users following that user. Currently, the users are stored as documents in a collection, so this is followerNumber document reads. For each of the users, update their array by prepending the postId this would be followerNumber document writes.

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

1. Displaying the Data/Feed For each fetch of the feed: get array from user document (1 doc read). For each postId, call, posts/{postId}

这将是numberOfPostsCalled文档读取.

This would be numberOfPostsCalled document reads.

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

2. Updating the Data For the author user of every activity, find all users following that user. Currently, the users are stored as documents in a collection, so this is followerNumber document reads. For each of the users, add a new document with ID postId to users/{userId}/feed this would be followerNumber document writes.

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

2. Displaying the Data/Feed For each fetch of the feed: get a certain number of posts from users/{userId}/feed

这将是numberOfPostsCalled文档读取.

This would be numberOfPostsCalled document reads.

第二种方法要求我在进行编辑时使所有文档保持最新状态.因此,尽管这种方法看起来更像是firebase风格的,但是保留 postId 并直接获取它的方法似乎更合乎逻辑.

This second approach requires me to keep all of the documents up to date in the event of an edit. So despite this approach seeming more firebase-esque, the approach of holding a postId and fetching that directly seems slightly more logical.

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

3. Updating the Data For every new follower, each post authored by the person being followed needs to be updated. The new follower is appended to an array called followers.

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

3. Displaying the Data For each fetch of the feed: get a certain number of posts from posts where uid == viewerUid

推荐答案

很好,当我谈论最理想的情况时,我真的需要一个点或一个品质属性来进行比较,我会假设您关心速度(没有必要)性能)和成本.

Nice, when I talk about what is more optimal I really need a point or a quality attribute to compare, I' will assume you care about speed (not necessary performance) and costs.

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

This is how I would solve the problem, it involves several collections but my goal is 1 query only.

用户(col)

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

帖子(col)

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

users_posts(col)

users_posts (col)

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

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

So far so good, the problem is, I need to do several queries to get all the posts information... This is where cloud functions get into the game. You can create a 4th collection where you can pre-calculate your feed

users_dashboard

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字节),您可以在其中存储大量数据,因此在此处可以有很多帖子.让我们谈谈费用;我以前认为firestore更像是有几个小型文档,但实际上我发现它在将大量文档添加到大型文档中时也能很好地发挥作用.

The doc max size is 1 MiB (1,048,576 bytes) that is plenty of data you can store in, so you can have like a lot of posts here. Let's talk about costs; I used to think firestore was more like to have several small docs but I've found in practice it works equally well with big size into a big amount of docs.

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

Now on your dashboard you only need query:

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

这是解决此问题的一种很自以为是的方法.您可以避免使用 users_posts ,但是也许除了其他与帖子相关的更改之外,您不想触发此过程.

This a very opinionated way to solve this problem. You could avoid using the users_posts, but maybe you dont want to trigger this process for other than posts related changes.

这篇关于对于获取社交媒体供稿,哪个是最理想的Firestore模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆