论坛构建
介绍如何使用 Redis 去构建一个论坛
主要功能
- 用户账号
- 创建帖子、回复帖子、为帖子投票
- 为帖子分类,查看属于特定分类的帖子
- 将多个分类(category)归类至某个标签(tab),查看属于特定标签的帖子
- 每日热议帖子排行榜
- 基于算法的帖子推荐
一个帖子的构成部分:
- 分类
- 标题
- 用户的投票数量
- 作者
- 发布时间
- 点击量
- 内容
- TAG
根据分类展示帖子
分类页面会根据帖子最后一次被回复的时间来排序帖子。
Category 类
API | 作用 | 实现原理 |
---|---|---|
Category(client, name) | 设置客户端以及分类的名字。 | |
include_topic(topic_id) | 将给定的帖子添加到当前分类中。 | ZADD |
is_included(topic_id) | 检查给定的帖子是否属于当前分类。 | 使用 ZSCORE 检查有序集合中,topic_id 对应的分值是否存在,如果不存在,那么帖子不属于该分类。 |
count_topic() | 返回当前分类包含的帖子数量。 | ZCARD |
paging(n, count) | 按 count 个帖子为一页,返回该分类第 n 页的帖子。 | ZREVRANGE |
根据标签展示帖子
一个标签可以包含多个分类,而属于被包含分类的帖子会出现在标签的列表里面。
实现标签功能需要两个步骤:
- 记录标签和分类之间的关系。
举个例子,程序要记住,”程序员”、”Linux”、”node.js”这些分类都属于”技术”标签。
- 记录标签属下的帖子,当用户点击某个标签时,展示该标签属下的各个帖子。
举个例子,帖子 132312 属于”程序员”分类,而该分类又属于”技术”标签,所以程序应该在用户点击”技术”页面时,展示出帖子 132312 。
Tag 类
API | 作用 | 实现原理 |
---|---|---|
Tag(client, tag_name) | 设置客户端和标签的名字。 | |
add_member(category_name) | 将给定的分类添加到当前标签里面。 | SADD |
is_member(category_name) | 检查给定的分类是否属于当前标签。 | SISMEMBER |
get_all_member() | 返回当前标签包含的所有分类。 | SMEMBERS |
count_member() | 返回标签包含的分类数量。 | SCARD |
include_topic(category_name, topic_id) | 将给定分类的帖子添加到当前标签的帖子列表里面。 | ZADD |
paging(n, count) | 返回标签包含的帖子。 | ZREVRANGE |
count_topic() | 返回标签目前包含的帖子数量。 | ZCARD |
回复帖子
用户可以对帖子进行回复。每条回复会至少会包含作者、回复时间和回复内容这些信息。并且每个帖子都需要一个列表来储存所有回复。这和我们之前为了实现微博评论而创建的 Comment 类和 CommentList 类的需求基本相同,所以只要对这两个类进行一些简单的修改,就可以重用它们了。
每日热议帖子排行
每日热议帖子排行榜展示了每天回复数量最多的帖子, 这个排行榜每天更新一次。
为了实现这个排行榜,程序需要使用一个键名为 bbs::reply_day_rank 的有序集合,其中有序集合的元素为帖子的 ID ,而元素的分值则是帖子在当前被回复的数量。
每当 ID 为 N 的帖子新增一条回复时,程序就执行以下命令来增加帖子在排行榜中的回复数量:
ZINCRBY bbs::reply_day_rank N 1
并且程序会为 bbs:reply_day_rank 设置生存时间,让它在一天之后自动过期,并自动创建新榜单。
这可以通过修改并重用之前介绍过的 DayRank 类来实现。
ReplyDayRank 类
API | 作用 | 实现原理 |
---|---|---|
ReplyDayRank(client) | 设置客户端。 | |
incr_reply_count(topic_id) | 为给定帖子的回复计数值增一。 | ZINCRBY |
get_top(n) | 返回排行榜中排名前 N 的帖子。 | ZREVRANGE |
帖子推荐系统
算法对帖子进行评分时,考虑的因素可能有:用户的贡献值、发布时间、用户的投票数、用户的回复数量,等等。
实现推荐系统的方法:
- 选择一个推荐算法,用于计算帖子的评分。
- 计算各个帖子的评分,并以有序的方式展示它们。
TopicRecommand 类
API | 作用 | 实现原理 |
---|---|---|
TopicRecommand(client) | 设置客户端。 | |
update_rank(topic_id, upvote,downvote, post_time) | 更新帖子的推荐评分。 | ZADD |
paging(n, count) | 返回算法推荐的第 n 页的帖子。 | ZREVRANGE |