2017-06-15 274 views
0

我想交叉多個集合(2個或更多)。要相交的集合的數量作爲ARGV從命令行傳遞。因爲數量正在從命令行傳遞。所以redis.call()函數中的參數數量是不確定的。使用redis.call(「sinter」,...)命令與lua腳本相交多個集合

如何使用Lua腳本中的redis.call()函數來執行此操作。

然而,我已經寫具有ALGO像的腳本:

  • 接受的組的數目中的鍵要相交[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 

此腳本工作正常時,我通過使用命令行兩個集合。

EG:

redic-cli --eval scriptfile.lua 2 , points:Above20 points:Above30 

output:- 

1) "playerid:1" 

2) "playerid:2" 

3) "playerid:7" 

points:Above20points:Above30是集。這一次,它不通過去循環,從我開始= 3

但是當我通過3臺,然後我總是得到輸出:

(空列表或設置)

因此,我已經寫了一些循環來找到交集。

我哪裏錯了?有沒有優化的方式,我可以直接找到多個集合的交集?

+0

是否有一個特別的原因,你正在使用一個Lua腳本,而不是直接創建一個多集作爲參數的SINTER命令? –

回答

1

您可能要查找的是難以捉摸的unpack() Lua command,它與其他語言中稱爲「Splat」的操作符相同。

在代碼中,使用以下命令:

local intersectedVal = redis.call("sinter", unpack(setsTable)) 

也就是說,SINTER是可變參數,並且可以接受多個鍵作爲參數。除非你的腳本除了intesects外還有其他的東西,否則你最好使用它。