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:
- Redis Strings: Se presenta un breve pero claro ejemplo sobre cadenas: Redis Strings y ¿Qué significa que INCR es atómico?
- Alterar y consultar key space: Información complementaria al tema y algunos ejemplos: Alterar y consultar key space
- Redis expiración: Claves con tiempo limitado
:Presentamos una breve información sobre la expiración y ejemplos: Expiración de claves con tiempo limitado - Listas: Para conocer los primeros pasos en Listas y casos de uso comunes te recomendamos leer: Listas y casos de uso comunes
- Creación automática y eliminación de keys: Para conocer mas sobre las claves y ver algunos ejemplos: Creación automática y eliminación de keys
- Redis Hashes: Para reconocer los principales comandos puedes leer el post: Introducción a Hashes
- Redis Sets: En el post que dejo a continuación se presenta un ejemplo claro y conciso en: Redis Sets y algunos ejemplos
- Conjuntos ordenados de Redis: Para saber mas sobre conjunto sordenados leer: Conjuntos ordenados de Redis
- Puntajes lexicográficos: Con las versiones recientes de Redis 2.8, se introdujo una nueva característica que permite obtener rangos lexicográficamente, para saber mas lea el siguiente post: Puntajes lexicográficos
- Bitmaps: Para conocer los principales comandos y casos de uso comunes los invitamos a leer: Bitmaps
- HyperLogLogs: Es una estructura de datos probabilísticos utilizada para contar cosas únicas, si deseas conocer mas puede leer: HyperLogLogs