Пересечение нескольких множеств с помощью скрипта lua с помощью команды redis.call("sinter", ...)
Я хочу пересечь несколько наборов (2 или более). Количество наборов, которые должны быть пересечены, передаются как ARGV из командной строки. Поскольку количество наборов передается из командной строки. Таким образом, количество аргументов в функции redis.call() является неопределенным.
Как я могу сделать это, используя redis.call()
функция в Lua
скрипт.
Тем не менее, я написал сценарий, который имеет, как:
- Принятие количества наборов для пересечения в ключах [1].
- Пересекая первые два набора с помощью
setIntersected = redis.call(ARGV[1], ARGV[2])
, - Запуск цикла и использование
setIntersected = redis.call("sinter", tostring(setIntersected), set[i])
- Тогда наконец я должен получить пересекающийся набор.
Код для вышеуказанного алгоритма:
local noOfArgs = KEYS[1] -- storing the number of arguments that will get passed from cli
--[[
run a loop noOfArgs time and initialize table elements, since we don't know the number of sets to be intersected so we will use Table (arrays)
--]]
local setsTable = {}
for i = 1, noOfArgs, 1 do
setsTable[i] = tostring(ARGV[i])
end
-- now find intersection
local intersectedVal = redis.call("sinter", setsTable[1], setsTable[2]) -- finding first intersection because atleast we will have two sets
local new_updated_set = ""
for i = 3, noOfArgs, 1 do
new_updated_set = tostring(intersectedVal)
intersectedVal = redis.call("sinter", new_updated_set, setsTable[i])
end
return intersectedVal
Этот скрипт прекрасно работает, когда я передаю два набора с использованием командной строки.
НАПРИМЕР:
redic-cli --eval scriptfile.lua 2 , points:Above20 points:Above30
output:-
1) "playerid:1"
2) "playerid:2"
3) "playerid:7"
куда points:Above20
а также points:Above30
наборы. На этот раз он не проходит через цикл for, который начинается с i = 3.
Но когда я прохожу 3 сета, я всегда получаю вывод как:
(пустой список или набор)
Так что есть некоторая проблема с циклом, который я написал, чтобы найти пересечение множеств.
Куда я иду не так? Есть ли оптимизированный способ, с помощью которого я могу найти пересечение нескольких множеств напрямую?
1 ответ
То, что вы, вероятно, ищете, неуловимый unpack()
Команда Lua, которая эквивалентна тому, что известно как оператор "Splat" в других языках.
В своем коде используйте следующее:
local intersectedVal = redis.call("sinter", unpack(setsTable))
Это сказало, SINTER
является переменным и может принимать несколько ключей в качестве аргументов. Если ваш сценарий не делает что-то помимо просто пересечений, вам лучше использовать это вместо этого.