1. 程式人生 > >一個Lua指令碼操作Redis的簡單例子

一個Lua指令碼操作Redis的簡單例子

本例子的lua指令碼實現 遍歷 Redis中指定模式的鍵,然後替換每個鍵中與模式匹配的值,使之變為指定的值。
Redis中的鍵如下所示:

127.0.0.1:6379> keys *
1) "string.tmd.2"
2) "test"
3) "string.tmd.1"

Redis 鍵對應的值為: 很明顯客戶端獲取到的是一個序列化了的String 值,但是avata欄位http連線依然呈現規則。

get "string.tmd.1"
"{\"bad\":106,\"comment\":{\"avata\":\"http://tmd2.ghost.com/comment/images/20.png\"
, \"bc\":\"\xe4\xb8\x8d\xe5\x8f\xaf\xe8\x83\xbd\xef\xbc\x81\xef\xbc\x81\xef\xbc\x81\xe6\x88\x91\xe4\xb8\x80\xe8\x88\xac\xe7\x9d\xa1\xe8\xa7\x89\xe6\x97\xb6\xe9\x83\xbd\xe4\xbc\x9a\xe6\x8a\x8a\xe6\xb0\x94\xe6\x94\xbe\xe4\xba\x86\xe7\x9a\x84\", \"nick\":\"\xe5\x8f\xb6\xe9\x9a\x8f\xe9\x9b\xa8\xe8\x90\xbda
8\", siz\"total\":7}, \"gif\":\"2498/1498187979040_39bcc0ad-737b-4fe9-8c59-4dd6318d64f0.gif\", good\":768,\"height\":174,\"id\":1,\"img\":\"2498/1498187979040_39bcc0ad-737b-4fe9-8c59-4dd6318d64f0.jpg\", \"ra\":\"1/1.jpg\", \"rn\":\"\xe5\x85\xb0\xe6\xba\xaa\", \"src\":\"http://neihanshequ.com/p62324851262/\", \"title\"
:\"\xe8\xbf\x99\xe5\xb0\xb1\xe6\x98\xaf\xe4\xbd\xa0\xe7\x9d\xa1\xe8\xa7\x89\xe6\x97\xb6\xe5\x80\x99\xe4\xbd\xa0\xe5\xa5\xb3\xe6\x9c\x8b\xe5\x8f\x8b\xe7\x9a\x84\xe5\x8f\x8d\xe5\xba\x94\xe3\x80\x82\", \"type\":2, \"weight\":0, \"width\":310}"

現在我們要將 avata 欄位裡面的連線 替換為另一種模式的連結 。

Lua指令碼如下: –表示註釋; myKeyList用於獲取所有的指定模式的鍵值, 即為上面的
“string.tmd.1”
“string.tmd.2”。

–獲取到的資料為一個table型別 即陣列

local myKeyList=redis.call("keys","string.tmd.*") 
        local count=0
        local tempStrlocal str  --experience all the keys 遍歷陣列 有多種方法遍歷陣列 網上很容易找到
        for index,line in pairs(myKeyList) 
        do  --通過Redis API呼叫 獲取line的值 line即為鍵 
        str=redis.call("get",line)
        --string.sub() match() gmatch() len() 對字串操作的函式 
        local matchStr=string.match(str,"http://tmd2.ghost.com/comment/images/%d+.png") --匹配到http連結
        --下面註釋掉的函式可以在"伺服器"端列印變數的值
        print(matchStr)
        local reserveStr=matchStr.sub(matchStr,40,string.len(matchStr)); --將連結截斷,並替換成指定的模式
        --print(reserveStr) 
        -- .. 用於連線字串 不像java中用 + 此處替換 str為源 中間為模式 右邊為目標 
        tempStr=string.gsub(str,"http://tmd2.ghost.com/comment/images/%d+.png","http://tmd2-img.ghost.com/1/"..reserveStr) 
        --print(tempStr) --替換完後將之重新設定到Redis中 redis.call("set",line,tempStr) 
        --print(redis.call("get",line))
        end
        --這個返回值在客戶端可以打印出來
        return "Success"

Lua指令碼搞完後 用eval 或者evalsha 執行

redis-cli --eval changeAvataLua

伺服器輸出如下:

{"bad":106,"comment":{"avata":"http://tmd2-img.ghost.com/1/20.png",
           "bc":"不可能!!!我一般睡覺時都會把氣放了的","nick":"葉隨雨落a8","total":7},
           "gif":"2498/1498187979040_39bcc0ad-737b-4fe9-8c59-4dd6318d64f0.gif",
           "good":768,"height":174,"id":1,"img":"2498/1498187979040_39bcc0ad-737b-4fe9-8c59-4dd6318d64f0.jpg",
           "ra":"1/1.jpg",
           "rn":"蘭溪",
           "src":"http://neihanshequ.com/p62324851262/",
           "title":"這就是你睡覺時候你女朋友的反應。",
           "type":2,
           "weight":0,
           "width":310}

以下Lua指令碼則反向替換上面的功能。

local myKeyList=redis.call("keys","string.joke.*")
            local count=0
            local tempStrlocal str
            --experience all the keys
            for index,line in pairs(myKeyList)
            do 
            str=redis.call("get",line)
            local matchStr=string.match(str,"http://tmd2\\--img.ghost.com/1/%d+.png")
            print(matchStr) 
            local reserveStr=matchStr.sub(matchStr,31,string.len(matchStr)); 
            print(reserveStr) 
            tempStr=string.gsub(str, "http://tmd2\\--
            img.ghost.com/1/%d+.png","http://tmd2.ghost.com/comment/images/"..reserveStr)
            print(tempStr) 
            redis.call("set",line,tempStr)
            end
            return "Success"