package com.lovenav.service.serviceImpl; import com.lovenav.service.RedisService; import com.lovenav.utils.RedisKeyUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.data.redis.core.*; import javax.annotation.Resource; import org.apache.commons.lang.StringUtils; import java.util.*; @Transactional @Service("redisService") public class RedisServiceImpl implements RedisService { private Logger logger = LoggerFactory.getLogger(RedisService.class); /** * 取热搜前几名返回 */ private static final Integer HOT_SEARCH_NUMBER = 9; /** * 多少时间内的搜索记录胃热搜 */ private static final Long HOT_SEARCH_TIME = 30 * 24 * 60 * 60L; @Resource private StringRedisTemplate stringRedisTemplate; //新增一条该userid用户在搜索栏的历史记录 //searchkey 代表输入的关键词 /** * 新增一条该userid用户在搜索栏的历史记录 */ public Long addSearchHistoryByUserId(String userId, String searchKey) { try{ String redisKey = RedisKeyUtils.getSearchHistoryKey(userId); // 如果存在这个key boolean b = Boolean.TRUE.equals(stringRedisTemplate.hasKey(redisKey)); if (b) { // 获取这个关键词hash的值,有就返回,没有就新增 Object hk = stringRedisTemplate.opsForHash().get(redisKey, searchKey); if (hk != null) { return 1L; }else{ stringRedisTemplate.opsForHash().put(redisKey, searchKey, "1"); } }else{ // 没有这个关键词就新增 stringRedisTemplate.opsForHash().put(redisKey, searchKey, "1"); } return 1L; }catch (Exception e){ logger.error("redis发生异常,异常原因:",e); return 0L; } } /** * 删除个人历史数据 */ public Long delSearchHistoryByUserId(String userId, String searchKey) { try { String redisKey = RedisKeyUtils.getSearchHistoryKey(userId); // 删除这个用户的关键词记录 return stringRedisTemplate.opsForHash().delete(redisKey, searchKey); }catch (Exception e){ logger.error("redis发生异常,异常原因:",e); return 0L; } } /** * 获取个人历史数据列表 */ public List getSearchHistoryByUserId(String userId) { try{ List stringList = null; String redisKey = RedisKeyUtils.getSearchHistoryKey(userId); // 判断存不存在 boolean b = Boolean.TRUE.equals(stringRedisTemplate.hasKey(redisKey)); if(b){ stringList = new ArrayList<>(); // 逐个扫描,ScanOptions.NONE为获取全部键对,ScanOptions.scanOptions().match("map1").build() 匹配获取键位map1的键值对,不能模糊匹配 Cursor> cursor = stringRedisTemplate.opsForHash().scan(redisKey, ScanOptions.NONE); while (cursor.hasNext()) { Map.Entry map = cursor.next(); String key = map.getKey().toString(); stringList.add(key); } return stringList; } return null; }catch (Exception e){ logger.error("redis发生异常,异常原因:",e); return null; } } /** * 根据searchKey搜索其相关最热的前十名 (如果searchKey为null空,则返回redis存储的前十最热词条) */ public List getHotList(String searchKey) { try { Long now = System.currentTimeMillis(); List result = new ArrayList<>(); ZSetOperations zSetOperations = stringRedisTemplate.opsForZSet(); ValueOperations valueOperations = stringRedisTemplate.opsForValue(); Set value = zSetOperations.reverseRangeByScore(RedisKeyUtils.getHotSearchKey(), 0, Double.MAX_VALUE); //key不为空的时候 推荐相关的最热前十名 if(StringUtils.isNotEmpty(searchKey)){ for (String val : value) { if (StringUtils.containsIgnoreCase(val, searchKey)) { //只返回最热的前十名 if (result.size() > HOT_SEARCH_NUMBER) { break; } Long time = Long.valueOf(Objects.requireNonNull(valueOperations.get("search:search-time:"+val))); //返回最近一个月的数据 if ((now - time) < HOT_SEARCH_TIME) { result.add(val); } else {//时间超过一个月没搜索就把这个词热度归0 zSetOperations.add(RedisKeyUtils.getHotSearchKey(), val, 0); } } } }else{ for (String val : value) { //只返回最热的前十名 if (result.size() > HOT_SEARCH_NUMBER) { break; } System.out.println(valueOperations.get(val)); Long time = Long.valueOf(Objects.requireNonNull(valueOperations.get("search:search-time:"+val))); //返回最近一个月的数据 if ((now - time) < HOT_SEARCH_TIME) { result.add(val); } else { //时间超过一个月没搜索就把这个词热度归0 zSetOperations.add(RedisKeyUtils.getHotSearchKey(), val, 0); } } } return result; }catch (Exception e){ logger.error("redis发生异常,异常原因:",e); return null; } } /** * 新增一条热词搜索记录,将用户输入的热词存储下来 */ public int incrementScoreByUserId(String searchKey) { Long now = System.currentTimeMillis(); ZSetOperations zSetOperations = stringRedisTemplate.opsForZSet(); ValueOperations valueOperations = stringRedisTemplate.opsForValue(); List title = new ArrayList<>(); title.add(searchKey); for (int i = 0, length = title.size(); i < length; i++) { String tle = title.get(i); try { if (zSetOperations.score(RedisKeyUtils.getHotSearchKey(), tle) <= 0) { zSetOperations.add(RedisKeyUtils.getHotSearchKey(), tle, 0); valueOperations.set(RedisKeyUtils.getSearchTimeKey(tle), String.valueOf(now)); } } catch (Exception e) { zSetOperations.add(RedisKeyUtils.getHotSearchKey(), tle, 0); valueOperations.set(RedisKeyUtils.getSearchTimeKey(tle), String.valueOf(now)); } } return 1; } /** * 每次点击给相关词searchKey热度 +1 */ public Long incrementScore(String searchKey) { try{ Long now = System.currentTimeMillis(); ZSetOperations zSetOperations = stringRedisTemplate.opsForZSet(); ValueOperations valueOperations = stringRedisTemplate.opsForValue(); // 没有的话就插入,有的话的直接更新;add是有就覆盖,没有就插入 zSetOperations.incrementScore(RedisKeyUtils.getHotSearchKey(), searchKey, 1); valueOperations.getAndSet(RedisKeyUtils.getSearchTimeKey(searchKey), String.valueOf(now)); return 1L; }catch (Exception e){ logger.error("redis发生异常,异常原因:",e); return 0L; } } }