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 2
Suppressions
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