Cheatsheet

Cómo administrar conjuntos ordenados en Redis

Published on April 15, 2020

Manager, Developer Education

Español
Cómo administrar conjuntos ordenados en Redis

Introducción

Redis es un almacén de datos clave-valor en memoria de código abierto. En Redis, los conjuntos ordenados son un tipo de datos similares a los conjuntos, ya que ambos son grupos de cadenas que no se repiten. La diferencia es que cada componente de un conjunto ordenado se asocia a una puntuación, lo que permite ordenarlos de la menor a la mayor. Como en el caso de los conjuntos, todos los componentes de un conjunto ordenado deben ser únicos, aunque varios pueden compartir la misma puntuación.

En este tutorial, se explica la forma de crear conjuntos ordenados, obtener y eliminar sus componentes y crear nuevos conjuntos ordenados a partir de conjuntos existentes.

Cómo usar esta guía

Esta guía está escrita a modo de ayuda memoria con ejemplos independientes. Lo alentamos a ir directamente a cualquier sección que sea pertinente para la tarea que desee completar.

Los comandos que se muestran en esta guía se probaron en un servidor de Ubuntu 18.04 con Redis 4.0.9. Para configurar un entorno similar, puede seguir el paso 1 de nuestra guía Cómo instalar y proteger Redis en Ubuntu 18.04. Mostraremos el comportamiento de estos comandos ejecutándolos con redis-cli, la interfaz de línea de comandos de Redis. Tenga en cuenta que si utiliza una interfaz de Redis diferente (por ejemplo, Redli), el resultado exacto de algunos comandos puede diferir.

De forma alternativa, podría proporcionar una instancia de base de datos de Redis gestionada para probar estos comandos, pero tenga en cuenta que, dependiendo del nivel de control que permita su proveedor de base de datos, es posible que algunos comandos de esta guía no funcionen según lo descrito.  Para proporcionar una base de datos gestionada de DigitalOcean, consulte nuestra documentación sobre bases de datos gestionadas. Luego, debe instalar Redli o configurar un túnel TLS para establecer conexión con la base de datos gestionada mediante TLS.

Crear conjuntos ordenados y añadir componentes

Para crear un conjunto ordenado, utilice el comando zadd. zadd acepta como argumento el nombre de la clave que contendrá el conjunto ordenado, seguido de la puntuación del componente que añada y el valor del propio componente. Con el siguiente comando, se creará una clave de conjunto ordenado denominada faveGuitarists con un componente, "Joe Pass", que tiene una puntuación de 1:

  1. zadd faveGuitarists 1 "Joe Pass"

zadd mostrará un entero que indica la cantidad de componentes añadidos al conjunto ordenado si se creó de forma correcta.

Output
(integer) 1

Puede añadir más de un componente a un conjunto ordenado con zadd. Tenga en cuenta que no es necesario que las puntuaciones sean secuenciales; puede haber brechas entre ellas, y varios componentes de un mismo conjunto ordenado pueden compartir la misma puntuación:

  1. zadd faveGuitarists 4 "Stephen Malkmus" 2 "Rosetta Tharpe" 3 "Bola Sete" 3 "Doug Martsch" 8 "Elizabeth Cotten" 12 "Nancy Wilson" 4 "Memphis Minnie" 12 "Michael Houser"
Output
(integer) 8

zadd puede aceptar las siguientes opciones, que debe ingresar después del nombre de clave y antes de la puntuación del primer componente:

  • NX o XX: estas opciones tienen efectos opuestos. Por lo tanto, solo puede incluir una de ellas en cualquier operación de zadd:
    • NX: indica a zadd que no actualice componentes existentes. Con esta opción, zadd añadirá únicamente elementos nuevos.
    • XX: indica a zadd a que solo actualice elementos existentes. Con esta opción, zadd nunca añadirá nuevos componentes.
  • CH: en general, zadd solo muestra la cantidad de nuevos elementos añadidos al conjunto ordenado. Con esta opción, sin embargo, zadd mostrará la cantidad de elementos modificados. Esto comprende los componentes recientemente añadidos y aquellos cuya puntuación se modificó.
  • INCR: hace que el comando aumente el valor de la puntuación del componente. Si el componente todavía no existe, el comando lo añadirá al conjunto ordenado con el aumento como puntuación, como si la puntuación original hubiera sido 0. Con INCR incluido, zadd muestra la puntuación nueva del componente si es correcta. Tenga en cuenta que solo puede incluir una puntuación o un componente a la vez cuando se utiliza esta opción.

En lugar de pasar la opción INCR a zadd, puede usar el comando zincrby, que se comporta exactamente de la misma manera. En vez de dar al componente del conjunto ordenado el valor que indica la puntuación como zadd, aplica a la puntuación del componente un incremento equivalente a ese valor.  Por ejemplo, con el siguiente comando se aplica un incremento de 5 a la puntuación del componente "Stephen Malkmus", que originalmente era 4, con lo cual llega a 9.

  1. zincrby faveGuitarists 5 "Stephen Malkmus"
Output
"9"

Como en el caso de la opción INCR del comando zadd, si el componente especificado no existe, zincrby lo crea con el valor de incremento como puntuación.

Obtener componentes de conjuntos ordenados

La manera más básica de recuperar componentes de un conjunto ordenado es usar el comando zrange.  Este comando acepta como argumento el nombre de la clave cuyos componentes desea obtener y un intervalo de componentes que se encuentran en su interior. El intervalo está definido por dos números que representan índices basados en cero, lo cual significa que 0 representa el primer componente del conjunto ordenado (o el componente con la puntuación más baja), 1 el siguiente y así sucesivamente.

En el siguiente ejemplo, se mostrarán los primeros cuatro componentes del conjunto ordenado faveGuitarists creado en la sección anterior:

  1. zrange faveGuitarists 0 3
Output
1) "Joe Pass" 2) "Rosetta Tharpe" 3) "Bola Sete" 4) "Doug Martsch"

Tenga en cuenta que si el conjunto ordenado que pasa a zrange tiene dos o más elementos con la misma puntuación, les aplicará orden lexicográfico o alfabético.

Los índices de inicio y detención también pueden ser números negativos: -1 representa el último componente, -2 el penúltimo y así sucesivamente.

  1. zrange faveGuitarists -5 -2
Output
1) "Memphis Minnie" 2) "Elizabeth Cotten" 3) "Stephen Malkmus" 4) "Michael Houser"

zrange puede aceptar el argumento WITHSCORES que, cuando se incluya, también mostrará las puntuaciones de los componentes:

  1. zrange faveGuitarists 5 6 WITHSCORES
Output
1) "Elizabeth Cotten" 2) "8" 3) "Stephen Malkmus" 4) "9"

zrange solo puede mostrar un intervalo de componentes en orden numérico ascendente. Para revertir esto y mostrar un intervalo en orden decreciente, debe usar el comando zrevrange. Considere este comando como una reversión temporal del ordenamiento del conjunto ordenado dado antes de mostrar los componentes que se encuentran dentro del intervalo especificado. Como sucede con zrevrange, 0 representará el último componente de la clave, 1 el penúltimo y así sucesivamente:

  1. zrevrange faveGuitarists 0 5
Output
1) "Nancy Wilson" 2) "Michael Houser" 3) "Stephen Malkmus" 4) "Elizabeth Cotten" 5) "Memphis Minnie" 6) "Doug Martsch"

zrevrange también puede aceptar la opción WITHSCORES.

Puede mostrar un intervalo de componentes según sus puntuaciones con el comando zrangebyscore. En el siguiente ejemplo, con el comando se mostrará cualquier componente que se encuentre en la clave faveGuitarists con una puntuación de 2, 3, o 4:

  1. zrangebyscore faveGuitarists 2 4
Output
1) "Rosetta Tharpe" 2) "Bola Sete" 3) "Doug Martsch" 4) "Memphis Minnie"

En este ejemplo, el intervalo es inclusivo, lo cual significa que mostrará componentes con puntuaciones de 2 o 4. Puede excluir cualquier extremo del intervalo anteponiéndole un paréntesis abierto ((). En el siguiente ejemplo, se mostrarán todos los componentes con una puntuación superior o igual a 2, pero inferior a 4:

  1. zrangebyscore faveGuitarists 2 (4
Output
1) "Rosetta Tharpe" 2) "Bola Sete" 3) "Doug Martsch"

Al igual que zrange, zrangebyscore puede aceptar el argumento WITHSCORES. También acepta la opción LIMIT, que puede usar para obtener solo una selección de elementos del resultado de zrangebyscore. Esta opción acepta un desplazamiento, que indica el primer componente del intervalo que se mostrará con el comando y un recuento que define la cantidad total de componentes que se mostrarán con el comando. Por ejemplo, con el siguiente comando se analizarán los primeros seis componentes del conjunto ordenado faveGuitarists, pero solo se mostrarán 3 componentes de él, a partir del segundo componente del intervalo, representado por 1:

  1. zrangebyscore faveGuitarists 0 5 LIMIT 1 3
Output
1) "Rosetta Tharpe" 2) "Bola Sete" 3) "Doug Martsch"

Con el comando zrevrangebyscore, se muestra un intervalo invertido de componentes según sus puntuaciones. Con el siguiente comando se muestran todos los componentes del conjunto con una puntuación de entre 10 y 6:

  1. zrevrangebyscore faveGuitarists 10 6
Output
1) "Stephen Malkmus" 2) "Elizabeth Cotten"

Al igual que zrangebyscore, zrangebyscore puede aceptar las opciones WITHSCORES y LIMIT. Además, puede excluir cualquier extremo del intervalo anteponiéndole un paréntesis abierto.

Puede haber momentos en que todos los componentes de un conjunto ordenado tengan la misma puntuación. En ese caso, puede hacer que Redis muestre de forma forzosa un intervalo de elementos en orden lexicográfico o alfabético con el comando zrangebylex. Para probar este comando, ejecute el siguiente comando zadd a fin de crear un conjunto ordenado en el que cada componente tenga la misma puntuación:

  1. zadd SomervilleSquares 0 Davis 0 Inman 0 Union 0 porter 0 magoun 0 ball 0 assembly

zrangebylex debe ir seguido del nombre de una clave, un intervalo de inicio y un intervalo de detención. Los intervalos de inicio y detención deben iniciarse con un paréntesis abierto (() o un corchete abierto ([), como se muestra a continuación:

  1. zrangebylex SomervilleSquares [a [z
Output
1) "assembly" 2) "ball" 3) "magoun" 4) "porter"

Tenga en cuenta que en este ejemplo solo se mostraron cuatro de los ocho componentes del conjunto, a pesar de que el comando buscaba un intervalo de la a a la z. Esto se debe a que los valores de Redis distinguen entre mayúsculas y minúsculas; por lo tanto, los componentes que comienzan con letras mayúsculas se excluyeron de su resultado. Para mostrarlos, puede ejecutar lo siguiente:

  1. zrangebylex SomervilleSquares [A [z
Output
1) "Davis" 2) "Inman" 3) "Union" 4) "assembly" 5) "ball" 6) "magoun" 7) "porter"

zrangebylex también acepta los caracteres especiales -, que representa un infinito negativo y +, que representa un infinito positivo. Por lo tanto, con la siguiente sintaxis de comando también se mostrarán todos los componentes del conjunto ordenado:

  1. zrangebylex SomervilleSquares - +

Tenga en cuenta que zrangebylex no puede mostrar componentes del conjunto en orden lexicográfico inverso (alfabético ascendente). Para hacerlo, utilice zrevrangebylex:

  1. zrevrangebylex SomervilleSquares + -
Output
1) "porter" 2) "magoun" 3) "ball" 4) "assembly" 5) "Union" 6) "Inman" 7) "Davis"

Debido a que está destinado a usarse con conjuntos ordenados en los que todos los componentes tienen la misma puntuación, zrangebylex no acepta la opción WITHSCORES.  Sin embargo, sí acepta la opción LIMIT.

Obtener información sobre conjuntos ordenados

Para averiguar la cantidad de componentes de un conjunto ordenado determinado (o, en otras palabras, su cardinalidad), utilice el comando zcard. En el siguiente ejemplo, se muestra la cantidad de componentes contenidos en la clave faveGuitarists de la primera sección de esta guía:

  1. zcard faveGuitarists
Output
(integer) 9

zcount puede indicar la cantidad de elementos de un conjunto ordenado determinado que se encuentran dentro de un intervalo de puntuaciones. El primer número que sigue a la clave es el comienzo del intervalo y el segundo es el final:

  1. zcount faveGuitarists 3 8
Output
(integer) 4

zscore obtiene la puntuación de un componente especificado de un conjunto ordenado:

  1. zscore faveGuitarists "Bola Sete"
Output
"3"

Si el componente o la clave especificados no existen, zscore mostrará (nil).

zrank es similar a zscore, pero, en vez de mostrar la puntuación del componente determinado, muestra su clasificación. En Redis, una clasificación es un índice basado en cero de los componentes de un conjunto ordenado por su puntuación. Por ejemplo, "Joe Pass" tiene una puntuación de 1, pero, dado que esa es la puntuación más baja de todos los componentes de la clave, tiene una clasificación de 0:

  1. zrank faveGuitarists "Joe Pass"
Output
(integer) 0

Hay otro comando de Redis denominado zrevrank que realiza la misma función que zrank, pero, en su lugar, invierte las clasificaciones de los componentes del conjunto. En el siguiente ejemplo, el componente "Joe Pass" tiene la puntuación más baja y, por lo tanto, la clasificación invertida más alta:

  1. zrevrank faveGuitarists "Joe Pass"
Output
(integer) 8

La única relación entre la puntuación de un componente y su clasificación es la posición que ocupa su puntuación en relación con las de otros miembros.  Si hay una brecha de puntuación entre dos componentes secuenciales, no se reflejará en su clasificación. Tenga en cuenta que si dos componentes tienen la misma puntuación, el primero en orden alfabético tendrá la menor clasificación.

Al igual que zscore, zrank y zrevrank devolverán (nil) si la clave o el componente no existen.

zlexcount puede indicar la cantidad de componentes que se encuentran en un conjunto ordenado en un intervalo lexicográfico. En el siguiente ejemplo, se utiliza el conjunto ordenado SomervilleSquares de la sección anterior:

  1. zlexcount SomervilleSquares [M [t
Output
(integer) 5

Este comando tiene la misma sintaxis que zrangebylex. Por lo tanto, consulte la sección anterior para obtener información detallada sobre cómo definir un intervalo de cadena.

Eliminar componentes de conjuntos ordenados

Con el comando zrem, es posible eliminar uno o más componentes de un conjunto ordenado:

  1. zrem faveGuitarists "Doug Martsch" "Bola Sete"

zrem mostrará un entero que indicará la cantidad de componentes que eliminó del conjunto ordenado:

Output
(integer) 2

Hay tres comandos de Redis que le permiten eliminar componentes de un conjunto ordenado basado en un intervalo. Por ejemplo, si todos los componentes de un conjunto ordenado tienen la misma puntuación, puede eliminar componentes sobre la base de un intervalo lexicográfico con zremrangebylex. Este comando utiliza la misma sintaxis que zrangebylex. En el siguiente ejemplo, se eliminarán de la clave SomervilleSquares creada en la sección anterior todos los componentes que comiencen con una letra mayúscula :

  1. zremrangebylex SomervilleSquares [A [Z

zremrangebylex dará como resultado un entero que indica la cantidad de componentes que eliminó:

Output
(integer) 3

También puede eliminar componentes en base a un intervalo de puntuaciones con el comando zremrangebyscore, que utiliza la misma sintaxis que el comando zrangebyscore. En el siguiente ejemplo, se eliminarán todos los componentes de faveGuitarists con una puntuación de 4, 5 o 6:

  1. zremrangebyscore faveGuitarists 4 6
Output
(integer) 1

Puede eliminar componentes de un conjunto en base a un intervalo de clasificaciones con el comando zremrangebyrank, que utiliza la misma sintaxis que zrangebyrank. Con el siguiente comando, se eliminarán los tres componentes del conjunto ordenado con las clasificaciones más bajas, que se definen en función de un intervalo de índices basados en cero:

  1. zremrangebyrank faveGuitarists 0 2
Output
(integer) 3

Tenga en cuenta que los números que se pasan a remrangebyrank también pueden ser negativos: -1 representa la clasificación más alta, -2 la siguiente y así sucesivamente.

Crear nuevos conjuntos ordenados a partir de conjuntos existentes

Redis incluye dos comandos que le permiten comparar componentes de varios conjuntos ordenados y crear conjuntos nuevos sobre la base de esas comparaciones: estos son zinterstore y zunionstore. Para experimentar con ellos, ejecute los siguientes comandos zadd a fin de crear conjuntos ordenados de ejemplo.

  1. zadd NewKids 1 "Jonathan" 2 "Jordan" 3 "Joey" 4 "Donnie" 5 "Danny"
  2. zadd Nsync 1 "Justin" 2 "Chris" 3 "Joey" 4 "Lance" 5 "JC"

zinterstore encuentra los componentes que comparten dos o más conjuntos ordenados (en su intersección) y produce un nuevo conjunto ordenado que contiene únicamente estos componentes. Este comando debe incluir, en orden, el nombre de una clave de destino en la que los componentes de la intersección se almacenarán como conjunto ordenado, el número de claves que se pasan a zinterstore y los nombres de las claves que desea analizar:

  1. zinterstore BoyBands 2 NewKids Nsync

zinterstore mostrará un entero que indica la cantidad de elementos almacenados en el conjunto ordenado de destino. Debido a que NewKids y Nsync solo comparten un componente, "Joey", el comando mostrará 1:

Output
(integer) 1

Tenga en cuenta que si la clave de destino ya existe, zinterstore sobrescribirá su contenido.

zunionstore creará un nuevo conjunto ordenado que contendrá todos los componentes de las claves que se le pasaron. Este comando utiliza la misma sintaxis que zinterstore y requiere el nombre de una clave de destino, la cantidad de claves que se pasan al comando y los nombres de estas:

  1. zunionstore SuperGroup 2 NewKids Nsync

Al igual que zinterstore, zunionstore , mostrará un entero que indica la cantidad de elementos almacenados en la clave de destino. Si bien los dos conjuntos ordenados originales tienen cinco componentes, dado que los conjuntos ordenados no pueden tener componentes repetidos y cada clave tiene un componente denominado "Joey", el entero resultante será 9:

Output
(integer) 9

Al igual que zinterstore, zunionstore sobrescribirá el contenido de la clave de destino si ya existe.

Para tener más control sobre las puntuaciones de los componentes al crear conjuntos ordenados nuevos con zinterstore y zunionstore, los dos comandos aceptan las opciones WEIGHTS y AGGREGATE.

La opción WEIGHTS va seguida de un número por cada conjunto ordenado incluido en el comando que pondera o multiplica la puntuación de cada componente. El primer número después de la opción WEIGHTS pondera las puntuaciones de la primera clave que se pasó al comando, el segundo número pondera la segunda y así sucesivamente.

En el siguiente ejemplo, se crea un nuevo conjunto ordenado que contiene las claves intersecantes de los conjuntos ordenados NewKids y Nsync. Pondera las puntuaciones de la clave de NewKids en un factor de tres y las de la clave de Nsync en un factor de siete:

  1. zinterstore BoyBandsWeighted 2 NewKids Nsync WEIGHTS 3 7

Si la opción WEIGHTS no se incluye, la ponderación por defecto es 1 tanto para zinterstore como para zunionstore.

AGGREGATE acepta tres subopciones. La primera, SUM, implementa el comportamiento predeterminado de zinterstore y zunionstore añadiendo las puntuaciones de los componentes coincidentes en los conjuntos combinados.

Si ejecuta una operación zinterstore o zunionstore en dos conjuntos ordenados que comparten un componente, pero este tiene una puntuación diferente en cada conjunto, puede hacer que la operación asigne por la fuerza la menor de las dos puntuaciones en el nuevo conjunto con la subopción MIN.

  1. zinterstore BoyBandsWeightedMin 2 NewKids Nsync WEIGHTS 3 7 AGGREGATE MIN

Debido a que los dos conjuntos ordenados solo tienen un componente coincidente con la misma puntuación (3), este comando creará un nuevo conjunto con el componente que tenga la menor de las dos puntuaciones ponderadas:

  1. zscore BoyBandsWeightedMin "Joey"
Output
"9"

De la misma manera, AGGREGATE puede forzar zinterstore o zunionstore a asignar la mayor de las dos puntuaciones con la opción MAX:

  1. zinterstore BoyBandsWeightedMax 2 NewKids Nsync WEIGHTS 3 7 AGGREGATE MAX

A través de este comando, se crea un nuevo conjunto con un componente, "Joey", que tiene la mayor de las dos puntuaciones ponderadas.

  1. zscore BoyBandsWeightedMax "Joey"
Output
"21"

Puede ser útil considerar a WEIGHTS como una alternativa para manipular las puntuaciones de los componentes temporalmente antes de que se analicen. De la misma manera, es útil concebir a la opción AGGREGATE como una opción para decidir cómo controlar las puntuaciones de los componentes antes de añadirlos a sus nuevos conjuntos.

Conclusión

En esta guía, se detallan varios comandos que se utilizan para crear y administrar conjuntos ordenados en Redis. Si desea ver en esta guía descripciones de otros comandos, argumentos o procedimientos relacionados, deje sus solicitudes o sugerencias en la sección de comentarios a continuación.

Para obtener más información sobre los comandos de Redis, consulte nuestra serie de tutoriales Cómo administrar bases de datos de Redis.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar

Manager, Developer Education

Technical Writer @ DigitalOcean

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.