2013-01-23 11 views

Antwort

3

Eine Möglichkeit, dieses Problem zu beheben, ist die serverseitige Lua-Skripterstellung.

Betrachten Sie das folgende Skript:

local res = {} 
local result = {} 
local tmp = redis.call('zrange', KEYS[1], 0, -1, 'withscores') 
for i=1,#tmp,2 do 
    res[tmp[i+1]]=true 
end 
for k,_ in pairs(res) do 
    table.insert(result,k) 
end 
return result 

Sie können es ausführen, indem Sie den EVAL Befehl.

Er verwendet den Befehl zrange, um den Inhalt des Zsets (mit Scores) zu extrahieren, dann erstellt er eine Menge (dargestellt mit einer Tabelle in Lua), um überflüssige Scores zu entfernen und schließlich die Antworttabelle zu erstellen. Daher werden die Werte von zset niemals über das Netzwerk gesendet.

Dieses Skript weist einen Fehler auf, wenn die Anzahl der Elemente im ZSet wirklich hoch ist, da es das gesamte Zset in ein Lua-Objekt kopiert (also Speicher benötigt). Es ist jedoch einfach, es so zu ändern, dass das Zset inkrementell durchlaufen wird (20 Elemente pro 20 Elemente). Zum Beispiel:

local res = {} 
local result = {} 
local n = redis.call('zcard', KEYS[1]) 
local i=0 
while i<n do 
    local tmp = redis.call('zrange', KEYS[1], i, i+20, 'withscores') 
    for j=1,#tmp,2 do 
     res[tmp[j+1]]=true 
     i = i + 1 
    end 
end 
for k,_ in pairs(res) do 
    table.insert(result,k) 
end 
return result 

Bitte beachten Sie, ich bin ein absoluter Neuling in Lua, so gibt es vielleicht elegantere Möglichkeiten, um das Gleiche zu erreichen.

7

BEARBEITEN: Da Ihr Problem mit der Größe der Werte vorher nicht offensichtlich war, habe ich einige zusätzliche Nachforschungen angestellt.

Es gibt nach der aktuellen Dokumentation keine Möglichkeit, nur die Noten aus einem sortierten Set zu bekommen.

Was Sie tun müssen, um nur die Punkte zu erhalten, ist, sie gleichzeitig zu einem separaten Satz hinzuzufügen und sie von dort zu holen, wenn sie benötigt werden.

Was Sie wahrscheinlich zuerst tun sollten, ist zu versuchen, Ihr Problem anders in Datenstrukturen abzubilden. Ich kann nicht anhand Ihrer Frage feststellen, warum Sie die Noten erhalten müssen, aber es gibt möglicherweise andere Möglichkeiten, das Problem zu strukturieren, das besser zu Redis passt.

-

Ich bin nicht sicher, ob es eine Möglichkeit ist, alle Noten zu bekommen, ohne die Schlüssel zu bekommen, aber ZRANGE zumindest die Informationen, die Sie suchen bekommen;

redis> ZADD myzset 10 "one" 
(integer) 1 

redis> ZADD myzset 20 "two" 
(integer) 1 

redis> ZADD myzset 30 "three" 
(integer) 1 

redis> ZRANGE myzset 0 -1 WITHSCORES 
["one","10","two","20","three","30"] 
+0

ich weiß, dass, aber das Problem ist, dass die v In meinem Fall sind die Werte so groß, dass es problematisch ist, nur die Noten zu verfolgen. – biztiger

+0

@biztiger Aktualisiert. Offensichtlich nicht die perfekte Lösung, aber eine praktikable, wenn Sie wirklich die Funktionalität brauchen. –

1

Sie müssen das optionale Argument HIGHSCORES übergeben.Siehe Dokumentation here:

ZREVRANGE Taste Start-Stopp [WITHSCORES] Gibt eine Reihe von Mitgliedern in einem sortierte Satz, durch den Index, mit Noten von hohen bestellt niedrigen

0

Wenn es folgenden ruby ​​kommt Befehl tun

redis.zrange("zset", 0, -1, :with_scores => true) 
# => [["a", 32.0], ["b", 64.0]] 

Quelle Ruby Docs

Verwandte Themen