199 lines
7.9 KiB
Java
199 lines
7.9 KiB
Java
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<String> getSearchHistoryByUserId(String userId) {
|
||
try{
|
||
List<String> 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<Map.Entry<Object, Object>> cursor = stringRedisTemplate.opsForHash().scan(redisKey, ScanOptions.NONE);
|
||
while (cursor.hasNext()) {
|
||
Map.Entry<Object, Object> 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<String> getHotList(String searchKey) {
|
||
try {
|
||
Long now = System.currentTimeMillis();
|
||
List<String> result = new ArrayList<>();
|
||
ZSetOperations<String, String> zSetOperations = stringRedisTemplate.opsForZSet();
|
||
ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
|
||
Set<String> 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(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;
|
||
}
|
||
Long time = Long.valueOf(Objects.requireNonNull(valueOperations.get(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<String, String> zSetOperations = stringRedisTemplate.opsForZSet();
|
||
ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
|
||
List<String> 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<String, String> zSetOperations = stringRedisTemplate.opsForZSet();
|
||
ValueOperations<String, String> 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;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
}
|