1. 排行榜应用,取TOP N操作
使用hash保存文章信息,用zset保存排行榜信息,方便直接获取最新的id。
public class ArticleService { private Jedis jedis = new Jedis("127.0.0.1", 6379); private static int VOTE_SCORE = 400; private static int ONE_WEEK_IN_SECONDS = 7 * 24 * 3600; private static int PAGE_COUNT = 7; // 发布文章 public String postArticle(String title, String content, String userId) { String articleId = "article:" + jedis.incr("article:"); long now = System.currentTimeMillis() / 1000; HashMap<String, String> articleData = new HashMap<String, String>(); articleData.put("title", title); articleData.put("content", content); articleData.put("author", userId); articleData.put("datetime", String.valueOf(now)); articleData.put("votes", "0"); // 初始化投票数为0 jedis.hmset(articleId, articleData); // 添加文章 jedis.expire(getVoteId(articleId), ONE_WEEK_IN_SECONDS); // 设置文章投票过期时间, 过期时会被自动删除 jedis.zadd("timelist" , now, articleId); // 将文章添加到时间排行榜, 以时间戳进行排名 jedis.zadd("scorelist", now + VOTE_SCORE, articleId); // 将文章添加到分数排行榜, 以时间戳+投票数进行排名 return articleId; } // 文章投票 public void voteArticle(String articleId, String userId) { double expiretime = jedis.zscore("timelist", articleId) + ONE_WEEK_IN_SECONDS; if(System.currentTimeMillis() / 1000 > expiretime) { // 判断投票是否过期 return; } if(jedis.sadd(getVoteId(articleId), userId) == 1) { // 若用户已投票则返回0 jedis.zincrby("scorelist", VOTE_SCORE, articleId); jedis.hincrBy(articleId, "votes", 1); } } // 获取文章列表 public List<Map<String, String>> getArticles(int page, String orderKey) { int start = (page - 1) * PAGE_COUNT; int end = page * PAGE_COUNT - 1; Set<String> ids = jedis.zrevrange(orderKey, start, end); // 按分数倒序排序 List<Map<String,String>> articles = new ArrayList<Map<String,String>>(); for (String id : ids){ Map<String,String> articleData = jedis.hgetAll(id); articleData.put("id", id); articleData.put("vote members:", jedis.smembers(getVoteId(id)).toString()); articles.add(articleData); } return articles; } private String getVoteId(String articleId) { return "vote:" + articleId.split(":")[1]; } public static void main( String[] args ) throws InterruptedException { ArticleService service = new ArticleService(); String articleId1 = service.postArticle("Python", "This is a python article", "z001"); print("post " + articleId1); String articleId2 = service.postArticle("Java", "Hello World", "z002"); print("post " + articleId2); service.voteArticle(articleId1, "z005"); print("vote " + articleId1); print(service.getArticles(1, "timelist")); print(service.getArticles(1, "scorelist")); } public static void print(Object obj) { System.out.println(obj); } } ------------------------------ 输出结果 ---------------------------------- 第一篇文章得到一个投票(评分+400分),因此在分数排行榜排名靠前,但是在时间排行榜依旧靠后 post article:1 post article:2 vote article:1 [ -- 时间排行榜 {id=article:2, content=Hello World, author=z002, title=Java, votes=0, vote members:=[], datetime=1524191117}, {id=article:1, content=This is a python article, author=z001, title=Python, votes=1, vote members:=[z005], datetime=1524191117} ] [ -- 分数排行榜 {id=article:1, content=This is a python article, author=z001, title=Python, votes=1, vote members:=[z005], datetime=1524191117}, {id=article:2, content=Hello World, author=z002, title=Java, votes=0, vote members:=[], datetime=1524191117} ]