Dan*_*ein 5 firebase google-cloud-firestore
我正在考虑将 Firestore 用于社交媒体提要的几个想法。到目前为止,我的想法还没有实现,所以对于这个想法,我希望得到社区的反馈。
这个想法是允许用户发布信息,或记录他们的活动,并向任何关注/订阅该信息的用户显示它。帖子信息将位于名为posts
.
据我所知,这些方法需要的读取和写入次数大致相同。
一个想法是在users/{userId}
有一个名为 posts 的字段中,它是一个我有兴趣为用户提取的 documentIds 数组。这将允许我直接从数据中提取posts
并获取最新版本的数据。
另一种方法似乎更像是 Firebasey,它是将文档存储在 users/{userId}/feeds 中,这些文档是帖子本身的副本。我可以使用相同postID
的数据posts
。据推测,如果我需要为任何评论更新数据,我可以使用组集合查询来获取所有称为提要的集合,其中 docID 是相等的(或者只是创建一个字段来执行适当的操作"where", "==", docId
)。
第三种方法是更新应该查看帖子的人员列表。只要帖子列表比关注者列表短,这似乎更好。您不是在每个关注者上维护所有帖子,而是在每个帖子上维护所有关注者。对于每个新关注者,您都需要更新所有帖子。
此列表不会是用户自己的帖子。相反,它将是显示该用户的所有帖子的列表。
三个挑战者:
users/{userId} 与字段称为feed
- 指向全局帖子的文档 ID 数组。获取该提要,通过 ID 获取所有文档。每次用户有活动时,都需要为每个关注者更新每个数组。
users (coll)
-> uid (doc)
-> uid.feed: postId1, postId2, postId3, ...] (field)
posts (coll)
-> postId (doc)
Run Code Online (Sandbox Code Playgroud)查询(伪):
doc(users/{uid}).get(doc)
feed = doc.feed
for postId in feed:
doc(posts/{postId}).get(doc)
Run Code Online (Sandbox Code Playgroud)
users/{userId}/feed 其中包含posts
您希望该用户看到的所有内容的副本。每个活动/帖子都需要添加到每个相关的提要列表中。
users (coll)
-> uid (doc)
-> feed: (coll)
-> postId1 (doc)
-> postId2
-> postId3
posts (coll)
-> postId (doc)
Run Code Online (Sandbox Code Playgroud)查询(伪):
collection(users/{uid}/feed).get(docs)
for post in docs:
doc(posts/{post}).get(doc)
Run Code Online (Sandbox Code Playgroud)
users/{userId}/feed 其中包含posts
您希望该用户看到的所有内容的副本。每个活动/帖子都需要添加到每个相关的提要列表中。
users (coll)
-> uid (doc)
posts (coll)
-> postId (doc)
-> postId.followers_array[followerId, followerId2, ...] (field)
Run Code Online (Sandbox Code Playgroud)查询(伪):
collection(posts).where(followers, 'array_contains', uid).get(docs)
Run Code Online (Sandbox Code Playgroud)
读/写
1. 更新数据
对于user
每项活动的作者,查找关注该用户的所有用户。目前,用户作为文档存储在集合中,因此这是 followerNumber 文档读取。对于每个用户,通过预先添加postId
这将是 followerNumber 文档写入来更新他们的数组。
1. 显示数据/提要
对于提要的每次获取:从用户文档中获取数组(读取 1 个文档)。对于每个 postId,调用,posts/{postId}
这将是 numberOfPostsCalled 文档读取。
2. 更新数据
对于user
每项活动的作者,查找关注该用户的所有用户。目前,用户作为文档存储在集合中,因此这是 followerNumber 文档读取。对于每一个用户来说,用ID添加新文档postId
到users/{userId}/feed
这将是followerNumber文件写入。
2. 显示数据/提要
对于提要的每次获取:从以下位置获取一定数量的帖子users/{userId}/feed
这将是 numberOfPostsCalled 文档读取。
第二种方法要求我在编辑时使所有文档保持最新。因此,尽管这种方法看起来更像 firebase,但postId
直接持有 a和 fetch的方法似乎更合乎逻辑。
3. 更新数据 对于每个新关注者,被关注者发表的每篇帖子都需要更新。新的追随者被附加到一个名为追随者的数组中。
3. 显示
每次获取提要的数据:从posts
哪里获取一定数量的帖子uid == viewerUid
很好,当我谈论什么是更优化时,我确实需要一个点或质量属性来比较,我会假设您关心速度(不是必需的性能)和成本。
这就是我解决问题的方法,它涉及多个集合,但我的目标只是 1 个查询。
用户(列)
{
"abc": {},
"qwe": {}
}
Run Code Online (Sandbox Code Playgroud)
帖子(列)
{
"123": {},
"456": {}
}
Run Code Online (Sandbox Code Playgroud)
用户帖子(列)
{
"abc": {
"posts_ids": ["123"]
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止一切顺利,问题是,我需要进行多次查询才能获取所有帖子信息......这就是云函数发挥作用的地方。您可以创建第四个集合,您可以在其中预先计算您的 Feed
用户仪表板
{
"abc": {
posts: [
{
id: "123", /.../
}, {
id: "456", /.../
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
云函数看起来像这样:
/* 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)
})
Run Code Online (Sandbox Code Playgroud)
文档最大大小是1 MiB (1,048,576 bytes)
您可以存储的大量数据,因此您可以在这里发布很多帖子。我们来谈谈成本;我曾经认为 firestore 更像是有几个小文档,但我发现在实践中它同样可以很好地处理大尺寸的大量文档。
现在在你的仪表板上你只需要查询:
const dashboard = firestore.collection(`users_dashboard`).doc(userID).get()
Run Code Online (Sandbox Code Playgroud)
这是解决这个问题的一种非常固执己见的方法。您可以避免使用users_posts
,但也许您不想为与帖子相关的更改以外的其他内容触发此过程。
归档时间: |
|
查看次数: |
2031 次 |
最近记录: |