2016-05-03 10 views
2

Ich habe Daten in Form eines Tupels (S, T), wobei S String ist und T ist Integer. Weder S noch T ist einzigartig, während ihre Kombination einzigartig ist. Ich brauche alle Tupel, wo S1 == S2 und |T1 - T2| <= C sind. Ist es möglich, effizient mit Redis zu arbeiten?Redis Intervallabfrage

+0

Ich denke, Ihre Frage würde von Vorteil sein, wenn Sie klären, ob die Tupel im Datensatz eindeutig sind. Unabhängig davon, aufgrund der 64-Bit-Anforderung, glaube ich, es wäre schwer, es zu ziehen (hart wie ineffizient) - Redis hat keinen nativen Integer-Datentyp und die größte Zahl, die es bewältigen kann, ist etwa 53 Bits ein sortierter Satz sind Doppel). –

+0

Ich entspannte Frage Bedingungen ein wenig, aber gibt es einige andere Optionen (eine andere Datenbank), die besser in dieser Aufgabe passen würde? – assp1r1n3

Antwort

1

Eine Möglichkeit wäre, die Daten in einer Liste zu speichern und den Abruf mit einem Lua-Skript durchzuführen. Zuerst für Tupel der Form (Sn,Tn), es wie folgt ein:

LPUSH myKey S1:T1 
LPUSH myKey S2:T2 
... and so on 

Verwenden Sie dann die Lua Skript unter:

local function split(div,str) 
    if (div=='') then return false end 
    local pos,arr = 0,{} 
    for st,sp in function() return string.find(str,div,pos,true) end do 
     table.insert(arr,string.sub(str,pos,st-1)) 
     pos = sp + 1 
    end 
    table.insert(arr,string.sub(str,pos)) 
    return arr 
end 

local key = KEYS[1] 
local sVal = ARGV[1] 
local tVal = tonumber(ARGV[2]) 
local cVal = tonumber(ARGV[3]) 
local length = redis.call("LLEN", key) 

if (tonumber(length) == 0) then 
    return nil 
end 

local data = redis.call("LRANGE", key, 0, tonumber(length)) 
local retval = {} 

for index,val in pairs(data) do 
    local parts = split(":", val)  
    if (parts[1] == sVal and math.abs(tonumber(parts[2]) - tVal) <= cVal) then 
     table.insert(retval, val) 
    end 
end 

return retval 

speichern es als script.lua und führen Sie es mit:

$ redis-cli "$(cat script.lua)" 1 myKey sValue tValue cValue 

Dies wird alle Tupel zurückgeben (in Sn:Tn Form), die S1 == S2 and |T1 - T2| <= C entspricht.

+0

Was ist die erwartete zeitliche Komplexität dieser Lösung? – assp1r1n3

+0

Angenommen, Sie meinen Zeitkomplexität, wäre es "O (n)", da es die gesamte Liste iterieren muss. Ich glaube nicht, dass du besser als "O (n)" mit den Datenstrukturen von Redis auskommen könntest, aber ich würde gerne daran falsch liegen :) –