Redis 有序集合(sorted set)
Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个 double 类型的分数。Redis 正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储 40 多亿个成员)。
- service示例代码
@Service("redisService")
public class RedisServiceImpl implements RedisService {
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 使用Sorted Set记录keyword
* zincrby命令,对于一个Sorted Set,存在的就把分数加x(x可自行设定),不存在就创建一个分数为1的成员
*
* @param keyword 搜索关键词
*/
@Override
public void searchZincrby(String keyword) {
// 名为sortedSetName的Sorted Set不用预先创建,不存在会自动创建,存在则向里添加数据
String sortedSetName = "searchHotWord";
// x 的含义请见本方法的注释
double x = 1.0;
redisTemplate.opsForZSet().incrementScore(sortedSetName, keyword, x);
}
/**
* zrevrange命令, 查询Sorted Set中指定范围的值
* 返回的有序集合中,score大的在前面
* zrevrange方法无需担心用于指定范围的start和end出现越界报错问题
*
* @param start 查询范围开始位置
* @param end 查询范围结束位置
* @return
*/
@Override
public Set<ZSetOperations.TypedTuple<String>> queryTopSearchHotWord(Integer start, Integer end) {
String sortedSetName = "searchHotWord";
Set<ZSetOperations.TypedTuple<String>> resultSet = redisTemplate.opsForZSet().reverseRange(sortedSetName, start, end);
return resultSet;
}
}
- controller示例代码
@RestController
@RequestMapping("/redis")
public class RedisController {
@Autowired
private RedisService redisService;
/**
* 测试redis记录keyword
*
* @param keyword 搜索关键词
* @return
*/
@GetMapping("/test_search")
public ResultVO testSearch(@RequestParam("keyword") String keyword) {
redisService.searchZincrby(keyword);
// ResultVO和ResultVOUtil是自定义的class,为了方便展示结果,阅读时忽略即可
return ResultVOUtil.success(1, "test-return");
}
/**
* 测试redis查询指定范围的热词
*
* @param start 查询范围开始位置
* @param end 查询范围结束位置,没有越界问题
* @return
*/
@GetMapping("/test_query_top_search_hot_word")
public ResultVO testQueryTopSearchHotWord(@RequestParam("start") Integer start,
@RequestParam("end") Integer end) {
Set<ZSetOperations.TypedTuple<String>> resultSet = redisService.queryTopSearchHotWord(start, end);
// ResultVO和ResultVOUtil是自定义的class,为了方便展示结果,阅读时忽略即可
return ResultVOUtil.success(1, "success", resultSet);
}
}