web-dev-qa-db-fra.com

Comment utiliser les commandes SCAN dans Jedis

J'utilisais redis et jedis depuis un certain temps et je n'avais jamais eu besoin des commandes SCAN jusqu'à présent. Maintenant, cependant, je dois utiliser les commandes SCAN , en particulier hscan. Je comprends comment cela fonctionne au niveau redis, mais le côté wrapper jedis Java me laisse perplexe. Il y a des classes ScanResults et ScanParameter qui circulent et je ne sais pas comment les utiliser correctement. La documentation de cette fonctionnalité est inexistante ou du moins difficile à trouver. Quelqu'un peut-il indiquer où trouver des exemples décents de la façon de parcourir un hachage en utilisant hscan avec jedis?

Désolé de ne pas avoir de code, mais ce que j'ai essayé jusqu'à présent n'a aucun sens.

12
luksch

Dans la bonne tradition de répondre à ses propres questions, voici ce que j'ai découvert:

String 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;
  }                 
}

La partie importante est que cur est une variable String et qu’elle est "0" si l’analyse est terminée.

Avec l’aide de ScanParams, j’ai pu définir la taille approximative de chaque morceau à extraire du hachage. Approximatif, car le hachage peut changer pendant l'analyse, il est donc possible qu'un élément soit renvoyé deux fois dans la boucle. 

16
luksch

Je n'aime pas les variables de drapeau

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));
10
gschaden

Une suggestion à l'exemple ci-dessus. Vous pouvez spécifier la correspondance de clé dans la classe scanParams. Voir ci-dessous.

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;
        }
    }
3
Onno Becker Hof

Si vous utilisez habituellement les interfaces Java.util.Iterator ou Java.lang.Iterable, vous pouvez essayer le framework basé sur Redis/ Redisson .

Voici un exemple comment itérer tous les keys de la carte sous le nom "myMap" stocké dans 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)) {
    ...
}

Voici un exemple comment itérer tous les keys stockés dans 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)) {
    ...
}

N'est-ce pas si simple?

1
Nikita Koksharov