2012-04-14 22 views
22

Actualmente estoy jugando con Redis y tengo algunas preguntas. ¿Es posible obtener valores de una matriz de claves?Obteniendo múltiples valores clave de Redis

Ejemplo:

users:1:name "daniel" 
users:1:age "24" 

users:2:name "user2" 
users:2:age "24" 

events:1:attendees "users:1", "users:2" 

Cuando i redis.get events:1:attendees devuelve "users:1", "users:2". Puedo recorrer esta lista y obtener usuarios: 1, obtener usuarios: 2. Pero esto parece estar mal, ¿hay alguna forma de obtener toda la información de los asistentes en 1?

En los carriles que haría algo como esto:

@event.attendees.each do |att| 
    att.name 
end 

Pero en Redis no puedo porque devuelve las claves y no el objeto real almacenado en esa clave.

gracias :)

Respuesta

38

Hacer un bucle en los elementos y acceder de forma síncrona a cada elemento no es muy eficiente. Con Redis 2.4, hay varias maneras de hacer lo que quiere:

  • utilizando el comando sort
  • mediante el uso de la canalización
  • utilizando el parámetro variadic comandos

con Redis 2.6, también puede usar scripts Lua, pero esto no es realmente necesario aquí.

Por cierto, la estructura de datos que describió podría mejorarse mediante hash. En lugar de almacenar datos de usuario en claves separadas, puede agruparlos en un objeto hash.

Usando el comando sort

Puede utilizar los Redis tipo comando para recuperar los datos en un ida y vuelta.

redis> set users:1:name "daniel" 
OK 
redis> set users:1:age 24 
OK 
redis> set users:2:name "user2" 
OK 
redis> set users:2:age 24 
OK 
redis> sadd events:1:attendees users:1 users:2 
(integer) 2 
redis> sort events:1:attendees by nosort get *:name get *:age 
1) "user2" 
2) "24" 
3) "daniel" 
4) "24" 

El uso de la canalización

El Rubí soporte al cliente la canalización (es decir, la capacidad de enviar varias consultas a Redis y esperar varias respuestas).

keys = $redis.smembers("events:1:attendees") 
res = $redis.pipelined do 
    keys.each do |x| 
     $redis.mget(x+":name",x+":age") 
    end 
end 

El código anterior solo recuperará los datos en dos viajes de ida y vuelta.

Mediante el comando parámetro variadic

El comando MGET se puede utilizar para recuperar varios datos en una sola toma:

redis> smembers events:1:attendees 
1) "users:2" 
2) "users:1" 
redis> mget users:1:name users:1:age users:2:name users:2:age 
1) "daniel" 
2) "24" 
3) "user2" 
4) "24" 

El costo es también aquí dos de ida y vuelta. Esto funciona si puede garantizar que la cantidad de claves para recuperar sea limitada. Si no, la canalización es una solución mucho mejor.

+0

Gracias por la respuesta! ¡Voy a probar tu código sugerido! Gracias :) –

+0

Gracias @Didier, siempre es bueno aprender cosas nuevas! –

5

Puede utilizar el comando Redis' EVAL que le envíe una Lua script que ejecuta un 'servidor' bucle y devolver los resultados en un bloque.

Cuestiones relacionadas