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.
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
@biztiger Aktualisiert. Offensichtlich nicht die perfekte Lösung, aber eine praktikable, wenn Sie wirklich die Funktionalität brauchen. –