• Redis构建文章聚合信息分类网站


    本系列教程内容提要

    Java工程师之Redis实战系列教程教程是一个学习教程,是关于Java工程师的Redis知识的实战系列教程,本系列教程均以解决特定问题为目标,使用Redis快速解决在实际生产中的相关问题,为了更方便的与大家一起探讨与学习,每个章节均提供尽可能详细的示例源码及注释,所有示例源码均可在javacourse-redis-in-action找到相关帮助!

    你思考过这个问题吗?

    如果你想过自己开发一个论坛网站,或者文章网站?最起码想过开发自己的博客网站吧?那么你是否考虑过这个问题--“当你数据库查询你的记录时,你考虑过这些记录应当以什么样的方式展现在网页?按发布时间?按浏览次数?

    • 按发布时间(嗯,应当时没问题的...)
    • 按浏览次数(嗯,如果给定一个时间范围也是没问题的...)

    你是否浏览过stackoverflow,如下图所示,你是否考虑过这些记录时按照什么展现的呢?唔...经过你的长久思考后,你想“应该不是最新,也不是浏览最多,应该时经过一系列的机制后算出来的....”

    我们通过什么机制进行排序呢?

    既然你能想到一定是经过一系列的运算过程的出来的排序过程,那么我们可否设计一个符合我们自己网站的 "运算过程" 呢? 我们规定:

    • 文章的发布时间+A支持票乘以常量E-B反对票乘以常量E
    • 文章7天后不再支持投支持票/反对票

    设计Redis表结构

    表名 结构
    文章 HASH
    投票人 SET
    群组 SET
    文章评分排行 ZSET
    文章最新排行 ZSET
    群组最新文章 ZSET
    群组评分排行 ZSET

    核心源码

    查询文章 (查询功能做的最多的就是拼装数据,但是在查询某个群组的文章的时候,就是涉及到了Redis的交集运算)

        /**
         * 获得所有文章列表文章列表
         *
         * @param page  页数
         * @param order 排序
         * @param model 模型
         * @return
         */
        @GetMapping(value = "/getArticleList")
        public String getArticle(@RequestParam(required = false, defaultValue = "1") Integer page, @RequestParam(required = false, defaultValue = "score") String order, Model model) {
            /*获取文章列表*/
            List<Article> articleArrayList = getArticles(jedis, page, order + ":");
            /*拼装分页信息*/
            model.addAttribute("articleArrayList", articleArrayList);
            model.addAttribute("order", order);
            model.addAttribute("page", page);
            return "index";
        }
    
        /**
         * 获取分组文章列表
         *
         * @return
         */
        @GetMapping(value = "/getGroupArticleList")
        public String getGroupArticle(@RequestParam(required = false, defaultValue = "1") Integer page,
                                      @RequestParam(required = false, defaultValue = "score") String order,
                                      @RequestParam(required = true) String group, Model model) {
            List<Article> groupArticles = getGroupArticles(jedis, group, page, order + ":");
            /*拼装分页信息*/
            model.addAttribute("groupArticles", groupArticles);
            model.addAttribute("group", group);
            model.addAttribute("order", order);
            model.addAttribute("page", page);
            return "group";
        }
    

    发布文章 (发布文章需要注意的是根据文章的所属群组,将其添加至相关群组)

    /**
         * 发布文章
         *
         * @param article
         * @param model
         * @return
         */
        @PostMapping(value = "/addArticle")
        public String addArticle(Article article, Model model) {
            /*模拟用户*/
            User user = getUser();
            /*从Redis获取文章的自增ID*/
            String id = String.valueOf(jedis.incr("article:"));
            /*将文章的发帖人本人添加至投票列表*/
            String voted = "voted:" + id;
            jedis.sadd(voted, user.getUserId().toString());
            jedis.expire(voted, ONE_WEEK_IN_SECONDS);
            /*将文章添加至文章列表*/
            long now = System.currentTimeMillis() / 1000;
            String articleId = "article:" + id;
            HashMap<String, String> articleData = new HashMap<>();
            articleData.put("title", article.getTitle());
            articleData.put("link", article.getLink());
            articleData.put("user", user.getUserId().toString());
            articleData.put("time", String.valueOf(now));
            articleData.put("votes", "1");
            articleData.put("group", article.getGroup());
            articleData.put("opposeVotes", "0");
            jedis.hmset(articleId, articleData);
            /*将文章添加至分值列表*/
            jedis.zadd("score:", now + VOTE_SCORE, articleId);
            /*将文章添加至发布时间列表*/
            jedis.zadd("time:", now, articleId);
            /*将文章加入其所属分组*/
            addGroup(jedis, articleId, new String[]{article.getGroup()});
            /*设置模型数据*/
            model.addAttribute("page", 1);
            model.addAttribute("order", "score");
            return "redirect:/article/getArticleList";
        }
    

    投票 (根据我们前面的规定,7天后不再提供对该文章的投票功能,所以需要在进行投票之前注意文章的发布时间)

        /**
         * 投票
         *
         * @param articleId
         * @param model
         * @return
         */
        @GetMapping(value = "/articleVote")
        public String articleVote(Integer articleId, int tag, RedirectAttributes model) {
            /*模拟用户*/
            User user = getUser();
            String result = article_vote(jedis, user, articleId, tag);
    
            /*设置模型数据*/
            model.addFlashAttribute("result", result);
            model.addFlashAttribute("page", 1);
            model.addFlashAttribute("order", "score");
            return "redirect:/article/getArticleList";
        }
    

    运行效果图

    各位友友可以下载本章的示例源码,运行访问 http://localhost:8080/article/getArticleList

    本章源码提供完整的运行环境源码GitHub下载

  • 相关阅读:
    Google搜索解析
    情绪管理--不要总做“好脾气”的人。
    全排列的实现
    ORACLE触发器具体解释
    3、应用设置之界面标注
    C++ 排序函数 sort(),qsort()的使用方法
    muduo网络库使用心得
    探索WebKit内核(一)------ 菜鸟起步
    eclipse+webservice开发实例
    使用Jquery+EasyUI进行框架项目开发案例解说之中的一个---员工管理源代码分享
  • 原文地址:https://www.cnblogs.com/jimisun/p/10016111.html
Copyright © 2020-2023  润新知