Как использовать команды SCAN в Jedis

Я использовал redis и jedis в течение некоторого времени и никогда не нуждался в командах SCAN. Теперь, однако, мне нужно использовать команды SCAN, в частности hscan. Я понимаю, как он работает на уровне redis, но сторона-оболочка jedis Java запутывает меня. Существуют классы ScanResults и ScanParameter, и у меня нет четкого представления о том, как правильно их использовать. Документация по этой функции отсутствует или, по крайней мере, трудно найти. Может ли кто-нибудь указать, где найти достойные примеры того, как перебирать хэш с помощью hscan с jedis?

Извините, у меня нет кода, но то, что я пробовал до сих пор, просто не имеет никакого смысла.

Ответ 1

В хорошей традиции ответа на собственные вопросы, вот что я узнал:

key = "THEKEY";
ScanParams scanParams = new ScanParams().count(100);
String cur = redis.clients.jedis.ScanParams.SCAN_POINTER_START; 
boolean cycleIsFinished = false;
while(!cycleIsFinished){
  ScanResult<Entry<String, String>> scanResult = 
        jedis.hscan(key, cur, scanParams);
  List<Entry<String, String>> result = scanResult.getResult();

  //do whatever with the key-value pairs in result

  cur = scanResult.getStringCursor();
  if (cur.equals("0")){
    cycleIsFinished = true;
  }                 
}

Важная часть состоит в том, что cur является переменной String и "0", если проверка завершена.

С помощью ScanParams я смог определить приблизительный размер каждого фрагмента, чтобы получить хэш. Приблизительный, потому что хэш может измениться во время сканирования, поэтому может быть, что элемент возвращается дважды в цикле.

Ответ 2

Мне не нравятся переменные флага

Jedis jedis = new Jedis("localhost");

ScanParams scanParams = new ScanParams().count(10).match("*");
String cur = SCAN_POINTER_START;
do {
    ScanResult<String> scanResult = jedis.scan(cur, scanParams);

    // work with result
    scanResult.getResult().stream().forEach(System.out::println);
    cur = scanResult.getStringCursor();
} while (!cur.equals(SCAN_POINTER_START));

Ответ 3

Предложение к приведенному выше примеру. Вы можете указать совпадение клавиш в классе scanParams. См. Ниже.

ScanParams scanParams = new ScanParams();
    scanParams.match("*");

    String cursor = redis.clients.jedis.ScanParams.SCAN_POINTER_START;
    boolean cycleIsFinished = false;
    while (!cycleIsFinished) {

        ScanResult<String> scanResult = jedisRead.scan(cursor, scanParams);
        List<String> result = scanResult.getResult();

        /*
         * do what you need to do with the result
         */



        cursor = scanResult.getStringCursor();
        if (cursor.equals("0")) {
            cycleIsFinished = true;
        }
    }

Ответ 4

Если вы используете интерфейсы java.util.Iterator или java.lang.Iterable тогда вы можете попробовать попробовать Redison на основе Redison.

Вот пример того, как перебирать все ключи карты под именем "myMap", хранящиеся в Redis:

RedissonClient redissonClient = RedissonClient.create(config);

// implements java.util.concurrent.ConcurrentMap interface
RMap<String, String> map = redissonClient.getMap("myMap");

// default batch size on each HSCAN invocation is 10
for (String key: map.keySet()) {
    ...
}

// default batch size on each HSCAN invocation is 250
for (String key: map.keySet(250)) {
    ...
}

Вот пример того, как перебирать все ключи, хранящиеся в Redis:

RedissonClient redissonClient = RedissonClient.create(config);

RKeys keys = redissonClient.getKeys();

// default batch size on each SCAN invocation is 10
for (String key: keys.getKeys()) {
    ...
}

// default batch size on each SCAN invocation is 250
for (String key: keys.getKeys(250)) {
    ...
}

Очень просто, не так ли?