Redis
 sql >> Database >  >> NoSQL >> Redis

Come annidare un elenco in una struttura in Redis per ridurre il livello superiore?

Nella maggior parte dei casi, SADD o ZADD con i comandi di pipelining sarà migliore. Utilizzare una transazione MULTI/EXEC se c'è il rischio che un altro client possa ottenere la chiave nel mezzo, ottenendo quindi un oggetto incompleto.

Stringere l'elenco in un campo hash può essere giustificabile in alcuni casi.

Per quanto riguarda "Rimuovi rapidamente le chiavi", assicurati di utilizzare UNLINK invece di DEL .

Se scegli di stringere, ecco come supportare atomicamente l'inserimento e la rimozione in un array con codifica JSON in un campo hash utilizzando la libreria CJSON Lua e Lua:

Inserisci :

local items = cjson.decode(redis.call('HGET', KEYS[1], 'items'))
table.insert(items, ARGV[1])
return redis.call('HSET', KEYS[1], 'items', cjson.encode(items))

Rimuovi per valore :

local items = cjson.decode(redis.call('HGET', KEYS[1], 'items'))
local pos = -1;
for i, v in ipairs(items) do
    if ARGV[1] == v then
        pos = i
        break
    end
end
if pos == -1 then
    return -1
else
    table.remove(items, pos)
    return redis.call('HSET', KEYS[1], 'items', cjson.encode(items))
end

Esempio di utilizzo :

> HGETALL meta_key
1) "user"
2) "12345"
3) "tag"
4) "D12321341234123"
5) "items"
6) "{}"
> EVAL "local items = cjson.decode(redis.call('HGET', KEYS[1], 'items')) \n table.insert(items, ARGV[1]) \n return redis.call('HSET', KEYS[1], 'items', cjson.encode(items))" 1 meta_key value1
(integer) 0
> HGETALL meta_key
1) "user"
2) "12345"
3) "tag"
4) "D12321341234123"
5) "items"
6) "[\"value1\"]"
> EVAL "local items = cjson.decode(redis.call('HGET', KEYS[1], 'items')) \n table.insert(items, ARGV[1]) \n return redis.call('HSET', KEYS[1], 'items', cjson.encode(items))" 1 meta_key value2
(integer) 0
> HGETALL meta_key
1) "user"
2) "12345"
3) "tag"
4) "D12321341234123"
5) "items"
6) "[\"value1\",\"value2\"]"
> EVAL "local items = cjson.decode(redis.call('HGET', KEYS[1], 'items')) \n local pos = -1; \n for i, v in ipairs(items) do \n     if ARGV[1] == v then \n     pos = i \n     break \n end \n end \n if pos == -1 then \n     return -1 \n else \n     table.remove(items, pos) \n return redis.call('HSET', KEYS[1], 'items', cjson.encode(items)) \n end" 1 meta_key value1
(integer) 0
> HGETALL meta_key
1) "user"
2) "12345"
3) "tag"
4) "D12321341234123"
5) "items"
6) "[\"value2\"]"
> EVAL "local items = cjson.decode(redis.call('HGET', KEYS[1], 'items')) \n local pos = -1; \n for i, v in ipairs(items) do \n     if ARGV[1] == v then \n     pos = i \n     break \n end \n end \n if pos == -1 then \n     return -1 \n else \n     table.remove(items, pos) \n return redis.call('HSET', KEYS[1], 'items', cjson.encode(items)) \n end" 1 meta_key value3
(integer) -1
> HGETALL meta_key
1) "user"
2) "12345"
3) "tag"
4) "D12321341234123"
5) "items"
6) "[\"value2\"]"