2015-11-21 11 views
8

Stavo usando redis e jedis per un po 'di tempo e non avevo mai avuto bisogno dei comandi SCAN finora. Ora però ho bisogno di usare i comandi SCAN, in particolare hscan. Capisco come funziona sul livello redis, ma il lato jedis Java wrapper mi confonde. Ci sono le classi ScanResults e ScanParameter che circolano e non ho un'idea chiara su come usarle correttamente. La documentazione di questa funzione è inesistente o almeno difficile da trovare. Qualcuno può indicare dove trovare esempi decenti di come iterare su un hash usando hscan con jedis?Come utilizzare i comandi SCAN in Jedis

Mi spiace non avere codice, ma quello che ho provato fino ad ora non ha assolutamente senso.

+2

Prova a guardare in fonti Jedi, in particolare i test - che di solito danno un indizio: https://github.com/xetorthio/jedis/blob /master/src/test/java/redis/clients/jedis/tests/commands/HashesCommandsTest.java#L339 –

+0

grazie per quel puntatore. Tuttavia, i test non sembrano davvero scorrere su un hash. Ad esempio, posso vedere solo una chiamata a hscan. Mi manca ancora il concetto del cursore corrente come String. – luksch

risposta

10

Nella buona tradizione di rispondere proprie domande, ecco cosa ho scoperto:

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 parte importante è che cagnaccio è una variabile String ed è "0" se la scansione è completata.

Con l'aiuto di ScanParams, sono riuscito a definire la dimensione approssimativa di ciascun blocco per ottenere dall'hash. Approssimativo, poiché l'hash potrebbe cambiare durante la scansione, quindi potrebbe essere che un elemento venga restituito due volte nel ciclo.

2

Un suggerimento per l'esempio sopra. È possibile specificare la corrispondenza della chiave all'interno della classe scanParams. Vedi sotto.

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

Non mi piace variabili bandiera

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