Redis, Jedis et les Sets
Je continue ma dĂ©couverte de Redis et Jedis (suite de lâarticle http://k33g.github.io/2014/05/22/PLAYING-WITH-REDIS.html sur Redis et les HashMaps). Jâavais alors dĂ©couvert la commande keys(matchParameters) que je trouvais assez gĂ©niale, mais lâon mâa fait remarquer Ă juste titre que ce nâĂ©tait pas performant et quâil valait mieux utiliser des sets pour classer ses donnĂ©es selon certains critĂšres.
Le sets, voyez ça comme un âcoupleâ clĂ©, liste de valeurs oĂč les valeurs sont des strings.
Connexion Ă Redis et dĂ©finition des âhumainsâ
Ăa câest la mĂȘme chose que la derniĂšre fois (avec une fille en plus)
Jedis jedis = new Jedis("localhost", 6379);
HashMap<String, String> bob = new HashMap<String, String>() {{
put("firstName", "Bob");
put("lastName", "Morane");
}};
HashMap<String, String> john = new HashMap<String, String>() {{
put("firstName", "John");
put("lastName", "Doe");
}};
HashMap<String, String> jane = new HashMap<String, String>() {{
put("firstName", "Jane");
put("lastName", "Doe");
}};
HashMap<String, String> wonderWoman = new HashMap<String, String>() {{
put("firstName", "Lynda");
put("lastName", "Carter");
}};Et je sauvegarde en base mes hashmaps:
jedis.hmset("bob", bob);
jedis.hmset("john", john);
jedis.hmset("jane", jane);
jedis.hmset("lynda", wonderWoman);Classer mes données avec des sets
Je vais crĂ©er 3 sets : "females", "males", "humans" pour âclasserâ mes hasmaps, grĂące Ă la commande sadd Ă laquelle je passe une clĂ© unique pour identifier le set et une liste de valeurs sous forme de string (qui ici reprĂ©sentent les clĂ©s de mes hashs):
jedis.sadd("females", "jane", "lynda");
jedis.sadd("males","bob", "john");
jedis.sadd("humans", "bob", "jane", "lynda", "john");Interroger mes sets
Maintenant si je souhaite avoir toutes les "females", il me suffit dâĂ©crire ceci en utilisant la commande smembers et en lui passant la clĂ© du set que je veux parcourir:
jedis.smembers("females").forEach((key) -> System.out.println(jedis.hgetAll(key)));Et nous obtiendrons:
{lastName=Carter, firstName=Lynda}
{lastName=Doe, firstName=Jane}
Si je veux compter le nombre de "males", jâutiliserais la commande scard
System.out.println(jedis.scard("males")); // nous obtiendrons 2Suppressions
Si je supprime la âhashâ Lynda:
jedis.del("lynda");Et que je relance le parcours du set "females":
jedis.smembers("females").forEach((key) -> System.out.println(jedis.hgetAll(key)));Et nous obtiendrons:
{}
{lastName=Doe, firstName=Jane}
Notez bien que la suppression de la âhashâ ne supprime pas lâenregistrement dans le set, ce qui est logique, mais tout le monde peut se tromper.
Pour supprimer un enregistrement du set, il suffit dâutiliser la commande srem en lui passant la clĂ© du set et la valeur Ă supprimer:
jedis.srem("females","lynda");Scan
On peut parcourir un set avec des critĂšres de recherche avec la mĂ©thode sscan qui permet de parcourir les valeur dâun set et dâen extraire celles qui correspondent Ă au critĂšre. Le critĂšre fonctionne de la mĂȘme façon quâavec keys : par exemple, je veux toutes les valeurs qui contiennent le caractĂšre "a", alors mon critĂšre sera : *a*. On retombe dans une problĂ©matique de performance, mais on aura beaucoup moins de clĂ©s Ă parcourir par rapport Ă avant oĂč lâon scannait la base entiĂšre.
Donc, imaginons que je veuille tous les "humans" dont la clĂ© contient "a", jâĂ©crirais ceci:
Je définis mon paramÚtre de recherche:
ScanParams params = new ScanParams();
params.match("*a*");Jâinterroge mon set
jedis.sscan("humans", SCAN_POINTER_START , params)
.getResult()
.forEach((key) -> System.out.println("key " + key + " : " + jedis.hgetAll(key)));Jâobtiendrais:
key jane : {lastName=Doe, firstName=Jane}
key lynda : {lastName=Carter, firstName=Lynda}
Remarque: SCAN_POINTER_START (ou redis.clients.jedis.ScanParams.SCAN_POINTER_START) correspond Ă String.valueOf(0) : je scanne Ă partir du 1er enregistrement.
Remarque bis: Ă manier avec prĂ©caution et parcimonie http://redis.io/commands/scan, je cite âIt is important to note that the MATCH filter is applied after elements are retrieved from the collection, just before returning data to the client.â
VoilĂ , jâavance tout doucement, la prochaine fois je travaillerais sur les range (je pense).
Tweet