通过分页从redis缓存检索数据

ryevplcw  于 2021-06-09  发布在  Redis
关注(0)|答案(2)|浏览(561)

我有如下结构的redis缓存

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

我需要通过分页从缓存中获取数据(第一页50个结果,第二页下50个结果,依此类推)。如何用springdataredis实现这一点。感谢您的帮助。

cs7cruho

cs7cruho1#

如果你需要保证元素的顺序,我想你需要某种排序集( HSCAN 是读取整个散列的好方法,但它不能保证返回内容的顺序,也不能保证返回内容中不会有重复的数据)。唯一符合排序集描述的redis数据类型是: ZSET . ZSET 的字段类似于 HASH 是的,但是在字段中有一个 double 用于对字段进行排序的“score”。
因此,要获得“散列分页”,可以做的一件事是 ZSET 所有的字段都和你的相同 HASH . 这个 HASH 将包含字段中的数据和 ZSET 将跟踪他们的订单。 ZSET 有一个方法叫做 ZRANGE (文档)允许您从集合中获取特定数量的元素。如果“页面”大小为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);
}

希望所有的字符串示例都足以说明如何做到这一点。

7dl7o3gd

7dl7o3gd2#

我在网上找到了一些解决方法并使用了相同的方法。

@Override
    public List<Entity> findAll(final int pageNum, final int pageSize) {
        final int startIndex = pageNum * pageSize;
        final int end = (pageNum + 1) * pageSize;
        int tmpIndex = 0;
        final List<Entity> entities = new ArrayList<>();
        try (Cursor<Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(CACHE_KEY,
                ScanOptions.scanOptions().match("*").build())) {
            while (cursor.hasNext()) {
                if (tmpIndex >= startIndex && tmpIndex < end) {
                    final Entry<Object, Object> entry = cursor.next();
                    final Entity entity = (Entity) entry.getValue();
                    entities.add(entity);
                    tmpIndex++;
                    continue;
                }
                if (tmpIndex >= end) {
                    break;
                }
                tmpIndex++;
                cursor.next();
            }
        } catch (Exception ex) {
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("Exception while fetching data from redis cache : " + ex);
            }
        }
        return entities;
    }

相关问题