美文网首页
热搜排序实现——Redis有序集合zset

热搜排序实现——Redis有序集合zset

作者: DreamsonMa | 来源:发表于2019-11-25 14:15 被阅读0次

    这里主要涉及存储和查询方案。不涉及前端搜索的分词解析。完整方案,需要包括前端分词,排除停止词,挖掘相关的词后再进行热搜词的入库和搜索。

    Redis Zincrby 命令对有序集合中指定成员的分数加上增量 increment
    当 key 不存在,或分数不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。

    如:对key为2019-11-25,成员为keywords,增加5分

    redis 127.0.0.1:6379> ZINCRBY '2019-11-25' 5 keywords
    

    Redis Zrange 返回有序集中,结果由小到大;Zrevrange 命令返回结果由大到小。

    如:查出key为2019-11-25,top3的成员

    redis 127.0.0.1:6379> ZRANGE '2019-11-25'  0 3
    

    利用有序集合zset的特性,即可达到按权重排序的效果。

    Java实现:

    @Component
    @Slf4j
    public class HotSearchProcessor {
    
        /**
         * 保存搜索
         * @param keyword
         */
        public void saveSkuSearch(String keyword){
                JedisUtil.getJedisInstance().execZIncrBy(DateUtil.format(new Date(), "yyyyMMdd"), 1, keyword);
        }
       
        /**
         * 获取热搜
         *
         * @param backwardDay 统计天数
         * @param hotNum      热门检索数量
         * @return
         */
        public List<String> getSkuHotSearch(Integer backwardDay, Integer hotNum) {
    
            Date nowDate = new Date();
            int end = hotNum * 3;
            List<MallSkuHotSearchResp> totalList = new ArrayList<>(backwardDay * end);
            for (int i = 0; i <= backwardDay; i++) {
                Set<Tuple> tupleSet = JedisUtil.getJedisInstance().execZrevrangeWithScores(DateUtil.format(DateUtils.addDays(nowDate, 0 - i), "yyyyMMdd"), 0, end);
                if (CollectionUtils.isNotEmpty(tupleSet)) {
                    for (Tuple tuple : tupleSet) {
                        MallSkuHotSearchResp resp = new MallSkuHotSearchResp();
                        resp.setScore((int) tuple.getScore());
                        resp.setSearchKeyword(tuple.getElement());
                        totalList.add(resp);
                    }
                }
            }
            Map<String, Integer> map = new LinkedHashMap<>(totalList.size());
            totalList.stream().collect(Collectors.groupingBy(MallSkuHotSearchResp::getSearchKeyword)).forEach((k, v) -> {
                map.put(k, v.stream().mapToInt(MallSkuHotSearchResp::getScore).sum());
            });
            map.entrySet().stream().sorted(Map.Entry.<String, Integer>comparingByValue().reversed()).forEachOrdered(e -> map.put(e.getKey(), e.getValue()));
            List<String> respList = new ArrayList<>();
            map.entrySet().stream().limit(hotNum).forEach(entry -> {
                respList.add(entry.getKey());
            });
            return respList;
        }
    
    }
    

    相关文章

      网友评论

          本文标题:热搜排序实现——Redis有序集合zset

          本文链接:https://www.haomeiwen.com/subject/gjmdwctx.html