Пересечение нескольких множеств с помощью скрипта 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 является переменным и может принимать несколько ключей в качестве аргументов. Если ваш сценарий не делает что-то помимо просто пересечений, вам лучше использовать это вместо этого.

Другие вопросы по тегам