后台可以记录每篇博客的阅读次数,直接简单粗暴的推荐比较流行的博客即可,可能热门的博客会被很多人所喜欢。
问题:可能产生长尾效应,阅读数多的博客可能就有限的几篇,而大量的博客无人问津。
解决方案:将阅读次数与新鲜度结合,找到一个比较适合的排名方式,一篇刚发布的博客,有较大的新鲜度,可以将其排到前面。
算法的设计
(1)在抽取博客时,会抽取到文章发布的时间,我们可以将这个发布时间转化为时间戳,这个时间戳就可以作为一篇文章基础的评分,时间戳是随着时间不断增加的,新发布的博客会有比较大的时间戳,这样就保证了新来的博客的分值比较大。
(2)在时间戳的基础上,我们可以引入点击量,作为博客评分的另一个部分,我们给每一个点击量增加一个权重K,当博客被点击一次后,评分会+K(后期可以引入收藏,多一个收藏,评分还可以继续增加)。这样可以保证热度比较高的博客的分数也比较高。
(3)为了提高系统的响应时间,我考虑使用了redis的zset来进行数据的缓存,zset是一个根据score进行排序的集合,我们正好可以根据文章的评分让zset对博客的顺序自动的进行排序,我们取数据时,是需要顺序读取即可。
具体zset的操作
当每篇文章进入系统时,根据时间戳算出他的基础分数,加入zset中,当用户点击文章时,修改这篇文章的分数,将分数加K,当删除一篇文章时,将这篇文章从zset中删除
(4)当需要获取博客列表时,只需要根据range顺序的从redis中取数据即可,zset提供了方法可以取到排名从start到end的博客数据,所以很简单的就可以实现博客的分页查询。
具体实现
- 配置redis环境,在springboot项目中实现对redis的存取。
配置文件:
spring:
redis:
host: r-bp1943b4a5673ef4pd.redis.rds.aliyuncs.com
port: 6379
password: xxxx
有关redis存取方法的实现:
spring data for redis 提供了RedisTemplate类,实现对redis数据库的快捷存取
/**
* redis zset添加元素 如果元素存在则会用新的score替换原来的
* @param key
* @param value
* @param score
* @return
*/
public boolean zsetAdd(String key,String value,double score)
{
boolean result = false;
try {
redisTemplate.opsForZSet().add(key, value,score);
result = true;
} catch (Exception e) {
e.printStackTrace();
}