说明
上一个月在写一个用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);
}
}