如何实现类似淘宝搜索记录,前十条记录滚动记录

  • 思路


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

实现步骤

  • 1.以用户唯一ID作为redis的key,数据结构使用ZSET,首先插入模拟数据200条,其中value为当前用户浏览的记录ID,score为插入时的时戳,中间有休眠模拟用户点击操作,间隔时间为1秒。
  • String key = "wangsr0001";
    for (int i = 0; i < 200 ; i++) {
                TimeUnit.SECONDS.sleep(1L);
                String randomChineseName = RandomPersonInfoUtil.getRandomTelephoneNumber();
                redisTemplate.opsForZSet().add(key,randomChineseName,System.currentTimeMillis());
     }

    2.开始模拟第201条数据插入,最后面删除操作时,因为时间最早的排在最前面,所以删除索引是从0开始,

  • /**
         * 新阅读记录插入
         * @author wjl
         */
    
        @Test
        public void insertTest(){
           //key
            String key = "wangsr0001";
           //阈值
            long top  = 200;
           //新访问记录ID
            String value  = "15646051140";
            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);
            }
        }

    3.列表查询历史记录,倒序

  • /**
         * 列表查询
         * @author wjl
         */
        @Test
        public void scanTest(){
            String key = "wangsr0001";
            long start = 1;
            long size  = 10;
            Set scoreWithScores = redisTemplate.opsForZSet().reverseRangeWithScores(key, start - 1, size - 1 );
            Iterator 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());
            }
        }

你可能感兴趣的:(java)