我想将Firestore用于社交媒体供稿的方法有很多。到目前为止,我尚未提出想法,因此,对于这一想法,我希望能得到社区的反馈。
该想法是允许用户发布信息或记录其活动,并向关注/订阅该信息的任何用户显示该信息。帖子信息将存储在名为posts
的根集合中。
据我所知,这些方法所需的读写次数大致相同。
一个想法是在users/{userId}
中有一个称为posts的字段,该字段是我有兴趣为用户提取的documentId数组。这样一来,我就可以直接从posts
中提取数据,并获取最新版本的数据。
另一种方法似乎更像Firebasey,该方法是将文档存储在作为帖子本身副本的users / {userId} / feed中。我可以使用与postID
中的数据相同的posts
。大概,如果需要更新任何评论的数据,则可以使用组集合查询来获取所有被称为feed的集合,其中docID相等(或者只是创建一个字段来执行正确的"where", "==", docId
)。 / p>
第三种方法就是更新应查看帖子的人员列表。只要帖子列表比关注者列表短,这似乎更好。而不是维护每个关注者的所有帖子,而是维护每个帖子的所有关注者。对于每个新关注者,您需要更新所有帖子。
此列表将不是用户自己的帖子。相反,它将是显示该用户的所有帖子的列表。
三个挑战者:
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)
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)
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
答案 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“收藏”),这样您就可以在供稿上查看其所有帖子。
使用这种方法,一次写入很多,但是读取很快。如果您的应用要读取更多而写入更少,那么除非我错了,否则不必担心。