2016-12-29 41 views
0

我有两个有序集合,我想从第一集合中分离记录,并通过从第二集集合中排除记录来存储在新列表/有序集合中。在Redis中,如何通过从第二个排序集合中排除记录来从第一个集合中分离记录。

下面是一个例子:

SET1:1,2,3,4,5 SET2:3,5,7,8,9

输出:1,2,4-

编辑:我已经想出了加载脚本并使用eval从nodejs执行脚本的方式。

奇怪的是,当我执行你的脚本时,即使是5-10个记录,它也需要1秒的时间来处理,这让我怀疑如果我有数千条记录,它有多大的可扩展性。

下面是我的示例代码的NodeJS:

hsetxx = 'redis.call("ZINTERSTORE","temp",2,"set11","set21","weights",1,0) redis.call("ZUNIONSTORE","result",2,"set11","temp","weights",1,-1) redis.call("ZREMRANGEBYSCORE","result",0,0)'; 

var redis = require('redis'); 
var client = redis.createClient('14470', connection); 

client.on('connect', function() { 
    console.log('Connected to Redis'); 
}); 

client.script('load',hsetxx,function(err, result) { 
    console.log(err+'------------'+result); 
}); 

client.zadd('set11', 1,1,1,2,1,3,1,4,1,5); 
client.zadd('set21', 1,1,1,5); 

client.evalsha(
'39c0da298cab6a6223b4d1e8222cf6d6a84e67b1', //lua source 
0, 
function(err, result) { 
    client.zrange('result', 0, -1, function(err, result) { 
      console.log(err+'------------'+result); 
     }); 
} 
); 
+1

[如何获得排序集DIFF](HTTP的可能重复:// stackoverflow.com/questions/26698179/how-to-get-diff-on-sorted-set) –

回答

0

我认为你正在寻找那么sdiff:

key1 = {a,b,c,d} 
key2 = {c} 
key3 = {a,c,e} 
SDIFF key1 key2 key3 = {b,d} 

https://redis.io/commands/sdiff

但是,有没有类似的有序集合。

+0

不,我想使用排序集。我无法找到它的ZDIFF,任何解决方法? –

+1

你可以将它写入Lua中或作为一个模块来实现它。 –

+0

@Not_a_Golfer你能详细说明一下吗?为什么选择Lua?什么模块? –

1

检查this问题:

你可以做的是首先要创建一个临时组与ZUNIONSTORE和 设置相交的得分为0,然后做一个范围不包括0, 如:

127.0.0.1:6379> ZADD all 1 one 2 two 3 three 
(integer) 3 
127.0.0.1:6379> SADD disabled two 
(integer) 1 
127.0.0.1:6379> ZUNIONSTORE tmp 2 all disabled WEIGHTS 1 0 AGGREGATE MIN 
(integer) 3 
127.0.0.1:6379> ZREVRANGEBYSCORE tmp +inf 1 WITHSCORES 
1) "three" 
2) "3" 
3) "one" 
4) "1" 
+0

以下解决方法适用于我: –

+0

以下解决方法适用于我:ZADD KEY1 1 1 1 2 1 3 1 4 1 5 ZADD KEY2 1个1 1 5 ZINTERSTORE温度2 KEY1 KEY2权重1个0 ZUNIONSTORE结果2 KEY1临时权1 -1 ZREMRANGEBYSCORE结果0 0 DEL温度 ZRANGE结果0 -1 1) “2” 2) “3” 3) “4” 你认为任何性能问题? –

+0

哈 - 这也是我的:)这将是有趣的比较这与Lua脚本 –

1

之前讨论过这很棒。如承诺的那样,应对这一挑战的另一种方法是Lua和Redis'EVAL。我不知道它将如何高性能是但这里有一个(不是太测试)脚本,模仿SDIFF但有序集合:

~/src/redis-lua-scripts$ cat zdiff.lua 
-- ZDIFF key [key ...] 
-- Returns the elements in the first key that are also present in all other keys 

local key = table.remove(KEYS,1) 
local elems = redis.call('ZRANGE', key, 0, -1) 
local reply = {} 

if #KEYS > 0 and #elems > 0 then 
    for i, e in ipairs(elems) do 
    local exists = true 
    for j, k in ipairs(KEYS) do 
     local score = redis.call('ZSCORE', k, e) 
     if not score then 
     exists = false 
     break 
     end 
    end 
    if exists then 
     reply[#reply+1] = e 
    end 
    end 
end 

return reply 
~/src/redis-lua-scripts$ redis-cli SCRIPT LOAD "`cat zdiff.lua`" 
"e25d895f05dc638be87d13aed64e8d5780f17c99" 
~/src/redis-lua-scripts$ redis-cli ZADD zset1 0 a 0 b 0 c 0 d 0 e 
(integer) 5 
~/src/redis-lua-scripts$ redis-cli ZADD zset2 0 a 
(integer) 1 
~/src/redis-lua-scripts$ redis-cli ZADD zset3 0 a 0 b 
(integer) 2 
~/src/redis-lua-scripts$ redis-cli EVALSHA e25d895f05dc638be87d13aed64e8d5780f17c99 3 zset1 zset2 zset3 
1) "a" 
+0

因为我是Redis和lua脚本的新手,我很难理解 - \t我如何可以在redislabs上部署我的lua脚本redis db。 - \t从我的节点应用程序调用lua脚本 任何参考或步骤可以帮助我很多。 JFYI:我现在正在使用免费版本的redislabs,因为我仍在评估它。 –

+0

你能给我脚本来排除set2中存在的set1的记录吗?还有我们有数百万条记录。会导致性能问题吗? –

相关问题