这是当前的样本结构
Posts(Collection)
- post1Id : {
viewCount : 100,
likes : 45,
points : 190,
title : "Title",
postType : image/video
url : FileUrl,
createdOn : Timestamp,
createdBy : user20Id,
userName : name,
profilePic: url
}
Users(Collection)
- user1Id(Document):{
postsCount : 10,
userName : name,
profilePic : url
}
viewed(Collection)
- post1Id(Document):{
viewedTime : ""
}
- user2Id(Document)
最终目标是 -我需要获取当前用户未查看过的getPosts,并按点数字段以分页的降序排列。
可能的最佳解决方案是什么(例如更改结构,云功能,来自客户端的多个查询)?
答案 0 :(得分:3)
我正在研究一种解决方案,以显示热门帖子并删除用户已经看到的帖子或内容不佳的帖子。处理两个查询真的很痛苦,尤其是在用户群增加的情况下。 很难维护“已查看”集合并过滤新帖子。想象一下,有 100 万个帖子被浏览过,然后过滤掉那些看不见的帖子。
所以我想出了一个解决方案,虽然不是很好,但仍然很酷。
这是我们的数据结构
帖子(收藏) --postid(文件)
这是一个带有基本细节的简单帖子结构。您可以看到我添加了一个优先级字段。这个领域会发挥作用。
如何使用优先权。
因此,当您开始滚动提要时,您将首先获得所有热门帖子,然后再获得优先级较低的帖子。如果您今天发布帖子并且人们开始对其进行投票。它将获得更长的生命周期,从而压倒糟糕的内容,当您对它投反对票时,只要用户无法访问它,它就会将帖子推下。
使用时间戳作为优先级,因为旧帖子会随着时间的推移而失去优先级。即使是今天的热门帖子明天也应该失去优先级。
需要考虑的事项:
使用寿命可以根据您的需要而变化。 用户群越大。你应该降低生命周期价值。因为如果今天发布的帖子被 10,000 名用户点赞,它会在未来 6.9 天趋势。如果有超过 100 个帖子被 10,000 多个用户点赞,那么在这 6.9 天内您将永远看不到新帖子。 因此,热门帖子应该不会持续一两天。
因此,在这种情况下,您可以提供 10 秒的生命周期,10,000 个点赞的生命周期为 1.1 天。
这不是一个完美的解决方案,但可以帮助您入门。
答案 1 :(得分:2)
看到您的数据库结构,我可以说您快到了。根据您的评论,您在以下参考文献中托管:
Users(Collection) -> userId(Document) -> viewed(Collection)
作为文档,用户查看过的所有帖子,而您想获取用户未查看的所有帖子。由于Firestore中没有!=
(不等于)运算符,也没有arrayNotContains()
函数,因此唯一的选择是为每个要显示的帖子创建一个额外的数据库调用,并检查是否该特定帖子是否已被看到。
要实现此目的,首先需要在名为postId
的帖子对象下添加另一个属性,该属性将实际的帖子ID保留为String。现在,每次您要显示新帖子时,都应该检查viewed
集合中是否已经存在该帖子ID。如果不存在,则在所需视图中显示该帖子,否则不显示。就是这样。
编辑:根据您的评论:
因此,要显示第一个帖子,需要两次Server调用。
是的,要显示第一个帖子,需要两个数据库调用,一个要获取帖子,第二个要查看它是否被看到。
大量服务器调用以获取第一篇文章。
否,如上所述只有两个呼叫。
我看错了吗
不,这是NoSQL数据库的工作方式。
还是没有其他有效的方法?
我不知道。还有另一种方法可以使用,但仅适用于用户数量有限且帖子查看次数有限的应用。此选项是将用户ID存储在每个post对象的数组中,并且每次您要显示帖子时,只需检查该数组中是否存在该用户id。
但是,如果数以百万计的用户可以查看帖子,则在数组中存储数百万个id并不是一个好选择,因为这种情况下的问题是文档具有限制< / strong>。因此,在文档中可以放入多少数据方面存在一些限制。根据有关usage and limits的官方文档:
文档的最大大小:1 MiB(1,048,576字节)
如您所见,单个文档中的数据总数限制为1 MiB。因此,您几乎无法将所有内容存储在文档中。