Los Redis SETS son colecciones de cadenas no ordenadas. El comando SADD agrega nuevos elementos a un conjunto.

También es posible realizar otras operaciones contra Redis SETS como probar si ya existe un elemento determinado, realizar la intersección, la unión o la diferencia entre conjuntos Redis múltiples, y así sucesivamente.

> sadd myset 1 2 3
(integer) 3
> smembers myset
1. 3
2. 1
3. 2

Aquí agregué tres elementos a mi conjuntos y le dije a Redis que devuelva todos los elementos.

Como puede ver, no están clasificados:

Redis puede devolver los elementos en cualquier orden en cada llamada, ya que no existe un contrato con el usuario sobre el orden de los elementos.

Redis tiene comandos para probar la membresía. Por ejemplo, verificar si existe un elemento:

> sismember myset 3
(integer) 1
> sismember myset 30
(integer) 0

“3” es un miembro del conjunto, mientras que “30” no lo es.

En Redis, los SET son similares a los LIST en que son un secuencia de cadenas, pero a diferencia de LIST, Redis SET usa una tabla hash para mantener todas las cadenas únicas.

Redis SETS: son buenos para expresar relaciones entre objetos…

Por ejemplo, podemos usar fácilmente Redis SETS para implementar etiquetas.

Una forma simple de modelar este problema es tener un conjunto para cada objeto que queremos etiquetar. El conjunto contiene los ID de las etiquetas asociadas con el objeto.

Una ilustración es etiquetar artículos de noticias. Si el artículo ID 1000 está etiquetado con las etiquetas 1, 2, 5 y 77, un conjuntos Redis puede asociar estas ID de etiqueta con la noticia:

> sadd news:1000:tags 1 2 5 77
(integer) 4

También es posible que deseemos tener la relación inversa: la lista de todas las noticias etiquetadas con una etiqueta determinada:

> sadd tag:1:news 1000
(integer) 1
> sadd tag:2:news 1000
(integer) 1
> sadd tag:5:news 1000
(integer) 1
> sadd tag:77:news 1000
(integer) 1

Obtener todas las etiquetas para un objeto dado es trivial:

> smembers news:1000:tags
1. 5
2. 1
3. 77
4. 2

Nota: en el ejemplo, suponemos que tiene otra estructura de datos, por ejemplo, un hash Redis, que asigna identificadores de etiquetas a nombres de etiquetas.

Hay otras operaciones no triviales que aún son fáciles de implementar utilizando los comandos Redis correctos.

Por ejemplo, es posible que deseemos una lista de todos los objetos con las etiquetas 1, 2, 10 y 27 juntas. Podemos hacer esto usando el comando SINTER, que realiza la intersección entre diferentes conjuntos.

Nosotros podemos usar:

> sinter tag:1:news tag:2:news tag:10:news tag:27:news
... results here ...

Además de la intersección, también puede realizar uniones, diferenciar, extraer un elemento aleatorio, etc.

El comando para extraer un elemento se llama SPOP y es útil para modelar ciertos problemas.

Por ejemplo, para implementar un juego de póquer basado en la web, es posible que desee representar su mazo con un conjunto. Imagine que usamos un prefijo de un carácter para (C) lubs, (D) iamonds, (H) earts, (S) pades:

>  sadd deck C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 CJ CQ CK
   D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 DJ DQ DK H1 H2 H3
   H4 H5 H6 H7 H8 H9 H10 HJ HQ HK S1 S2 S3 S4 S5 S6
   S7 S8 S9 S10 SJ SQ SK
   (integer) 52

Ahora queremos proporcionar a cada jugador 5 cartas. El comando SPOP elimina un elemento aleatorio y lo devuelve al cliente, por lo que es la operación perfecta en este caso.

Sin embargo, si lo llamamos directamente contra nuestro mazo, en la próxima jugada del juego necesitaremos rellenar nuevamente el mazo de cartas, lo que puede no ser el ideal. Entonces, para empezar, podemos hacer una copia del conjunto almacenado en la clave del mazo en el juego: 1: clave de cubierta.

Esto se logra usando SUNIONSTORE, que normalmente realiza la unión entre varios conjuntos y almacena el resultado en otro conjunto.

Sin embargo, dado que la unión de un solo conjunto es en sí misma, puedo copiar mi mazo con:

> sunionstore game:1:deck deck
(integer) 52

Ahora estoy listo para proporcionarle al primer jugador cinco cartas:

> spop game:1:deck
"C6"
> spop game:1:deck
"CQ"
> spop game:1:deck
"D1"
> spop game:1:deck
"CJ"
> spop game:1:deck
"SJ"

Un par de tomas, no es genial …

Este es un buen momento para introducir el comando set que proporciona la cantidad de elementos dentro de un conjunto. Esto a menudo se llama la cardinalidad de un conjunto en el contexto de la teoría de conjuntos, por lo que el comando Redis se llama SCARD.

> scard game:1:deck
(integer) 47

The math works: 52 - 5 = 47.

Cuando necesite obtener elementos aleatorios sin eliminarlos del conjunto, existe el comando SRANDMEMBER adecuado para la tarea. También presenta la capacidad de devolver elementos repetitivos y no repetitivos.

 

A continuación te acercamos un listado de diversos posts de Redis, para que puedas continuar leyendo sobre el tema: