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.
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.
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));
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;
}
}
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?