首页 > 解决方案 > 使用分页从 redis 缓存中检索数据

问题描述

我有结构如下的redis缓存

private HashOperations<String, Long, Object> hashOperations;
//put data in cache
hashOperations.put("Key", 1, SomeObject);

我需要通过分页从缓存中获取数据(第一页 50 个结果,第二页接下来 50 个结果,依此类推)。这如何用spring data redis实现。任何帮助表示赞赏。

标签: javacachingredisspring-data-redis

解决方案


如果您需要保证元素的顺序,我认为您将需要某种排序集 (HSCAN是读取整个散列的好方法,但它不保证返回的顺序,也不保证会有它返回的内容中没有重复数据)。唯一符合排序集描述的 Redis 数据类型是:ZSET. ZSETs 具有类似于HASHes 的字段,但是,在它们的字段内,它们有一个double用于对字段进行排序的“分数”,而不是字符串值。

因此,要获得“哈希分页”,您可以做的一件事是让 aZSET具有与您的HASH. 将HASH包含您的字段中的数据,ZSET并将跟踪它们的顺序。

ZSETs 有一个名为ZRANGE( documentation ) 的方法,它允许您从集合中获取特定数量的元素。对于 50 的“页面”大小,它看起来像这样:

# this gets you the "page" with the first 50 elements
ZRANGE 0 50

# this gets you the "page" with the second 50 elements
ZRANGE 50 100

# etc.

因此,要向 zset/hash 添加一些数据然后获取页面,您可以执行以下操作(伪代码 - 可能无法编译):

RedisTemplate<String, String> redisTemplate;

String myKey = "exampleKey";

// example of adding one record to the HASH + ZSET
String myField = "field1";
String myData = "123ABC";

// in this example data inserted into the ZSET is ordered based on when it was inserted.
// if you want to order it differently you can figure out your own way of coming up with scores
redisTemplate.opsForZSet().add(myKey + "zset", myField, System.getCurrentTimeMillis());
redisTemplate.opsForHash.put(mykey + "hash", myField, myData);

// Get one page from the hash
Set<String> first50hashFields = redisTemplate.opsForZSet().range(myKey + "zset", 0, 50);

List<String> firstPage = LinkedList<>();
for (String hashFieldKey : first50hashFields) {
     String hashFieldValue = redisTemplate.opsForHash().get(myKey + "hash", hashFieldKey);

     firstPage.add(hashFieldValue);
}

希望全字符串示例足以说明如何做到这一点。


推荐阅读