java+redis实现搜索历史功能

说明

上一个月在写一个用uni-app来做架构的app软件。功能实现有一个和其他软件都有的一个搜索历史功能,这里分享一下。

实现

1,使用redis的zset,用户唯一ID作为key,用户访问记录ID作为value,访问时间作为分数score
2,每次浏览记录向该用户集合中插入一条记录,插入前判断是否有旧的记录,有则删除,然后添加,每 次插入的记录时间戳递增,借助zset本身的有序性,很容易实现查询排序翻转
3,插入后获取总记录,如果大于阈值,则删除阈值之外更旧的记录,时间倒序

直接上代码吧
1,这里是查询到已经存储在Redis里最新的10条记录

/**
     * 查询搜索历史
     * @return  列表查询历史记录,倒序
     */
    @Override
    public List<String> selectSearchResultList() {
        List<String> searchList = new ArrayList<>();
        /** 这里拿到用户的唯一ID作为KEY来给到Redis **/
        int userId = Integer.parseInt(SecurityUtils.getUserId().toString()); 
        String key = CacheConstants.SEARCH_CONFIG + userId;
        long start = 1;             // 指定开始区间值
        long size  = 10;            // 指定长度区间值 (查询搜索历史记录最新的10条)
        Set<ZSetOperations.TypedTuple> scoreWithScores = redisTemplate.opsForZSet().reverseRangeWithScores(key, start - 1, size - 1 );
        Iterator<ZSetOperations.TypedTuple> iterator = scoreWithScores.iterator();
        BigDecimal bigDecimal = null;
        while (iterator.hasNext()){
            ZSetOperations.TypedTuple next = iterator.next();
            bigDecimal = BigDecimal.valueOf(next.getScore());
            //System.out.println("==》ID: "+next.getValue()+" 时间: "+bigDecimal.toPlainString());
            if ( next.getValue() != null ){
                searchList.add(next.getValue().toString());
            }
        }
        // 这里返回List给到前端
        return searchList;
    }

2,这里的代码是前端调用搜索接口时+加上这里的代码,把值存储到Redis中

		int userId = Integer.parseInt(SecurityUtils.getUserId().toString());      // 拿到用户ID
        // 把用户ID当key,搜索内容当value 存入 Redis
        redisTemplate.opsForZSet().add(CacheConstants.SEARCH_CONFIG+userId,companyName,System.currentTimeMillis());
        // 调用下面的方法对存入Redis的数据进行处理
        insertSearchSort(CacheConstants.SEARCH_CONFIG+userId,companyName);

3,对传进来的搜索内容进行判断筛选

    /**
     * 对传进来的搜索内容进行判断
     * @param key
     * @param value
     */
    public void insertSearchSort(String key,String value){
        //阈值-历史最多10个
        long top  = 10;
        // 拿到存入Redis里数据的唯一分值
        Double score = redisTemplate.opsForZSet().score(key, value);
        //检索是否有旧记录  1.无则插入记录值  2.有则删除 再次插入
        if(null != score){
            //删除旧的
            redisTemplate.opsForZSet().remove(key,value);
        }
        //加入新的记录,设置当前时间戳为分数score
        redisTemplate.opsForZSet().add(key,value,System.currentTimeMillis());
        //获取总记录数
        Long aLong = redisTemplate.opsForZSet().zCard(key);
        if(aLong > top){
            //获取阈值200之后的记录  (0,1] 并移除
            redisTemplate.opsForZSet().removeRange(key,0,aLong-top-1);
        }
    }

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐