Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Redis中通过另一个排序集更新排序集?_Redis_Jedis - Fatal编程技术网

如何在Redis中通过另一个排序集更新排序集?

如何在Redis中通过另一个排序集更新排序集?,redis,jedis,Redis,Jedis,我是Redis的新手,现在如果密钥存在于另一个排序集中,我需要更新排序集 我认为通过一个例子来解释可能更清楚,假设有两个排序集,如下所示: set_1 {key_1:val_1, key_2:val_2, key_3:val_3} set_2 {key_1:val_new_1, key_3:val_new_3, key_4:val_new_4} 现在,如果第二个集合中存在密钥,我将尝试更新第一个集合,因此结果应该是: set_1 {key_1:val_new_1, key_2:val_2,

我是Redis的新手,现在如果密钥存在于另一个排序集中,我需要更新排序集

我认为通过一个例子来解释可能更清楚,假设有两个排序集,如下所示:

set_1
{key_1:val_1, key_2:val_2, key_3:val_3}

set_2
{key_1:val_new_1, key_3:val_new_3, key_4:val_new_4}
现在,如果第二个集合中存在密钥,我将尝试更新第一个集合,因此结果应该是:

set_1
{key_1:val_new_1, key_2:val_2, key_3:val_new_3}
我阅读Redis文档已经有一段时间了,使用带有XX选项的SET命令可能会有所帮助:

SET命令支持修改其行为的一组选项: XX——仅当密钥已存在时设置该密钥


但是,是否可以避免在第一组中的每个条目上运行此操作?可能使用zunionstore?

之类的命令,
SET
命令仅适用于常规键,而不适用于排序集

在排序集中,您有分数成员对,因此示例中的键值对命名法有点混乱。我假设
key_1,key_2,key_3,…
是成员,
val_1,val_2,…
是分数

让我们按如下方式创建排序集以查看解决方案:

> ZADD set_1 1 key_1 2 key_2 3 key_3
(integer) 3
> ZADD set_2 1001 key_1 1003 key_3 1004 key_4
(integer) 3
默认的
AGGREGATE
SUM
,这是我们将在整个系统中使用的

我们将创建两个具有两者交集的排序集,一个分数为
set_1
,另一个分数为
set_2

> ZINTERSTORE intersect_set_1 2 set_1 set_2 WEIGHTS 1 0
(integer) 2
> ZINTERSTORE intersect_set_2 2 set_1 set_2 WEIGHTS 0 1
(integer) 2
现在,我们为
set_1
创建一个中间步骤集,其中
set_2
中的那些步骤的分数也设置为零:

> ZUNIONSTORE pre_set_1 2 set_1 intersect_set_1 WEIGHTS 1 -1
(integer) 3
现在,我们已经准备好更新集合_1,进行以下并集:

  • pre_set_1
    :所有
    设置_1
    ,但也将
    中的设置_2
    设置为零分
  • intersect\u set\u 2
    set\u 1
    set\u 2
    的交点,分数为
    set\u 2
这是最后一个命令:

> ZUNIONSTORE set_1 2 pre_set_1 intersect_set_2
(integer) 3
让我们看看结果:

> ZRANGE set_1 0 -1 WITHSCORES
1) "key_2"
2) "2"
3) "key_1"
4) "1001"
5) "key_3"
6) "1003"
别忘了清理:

> UNLINK pre_set_1 intersect_set_1 intersect_set_2
此解决方案不是最优的,因为它使用多个中间步骤,中间添加到原始集合的成员存在风险,并且它使用的内存超过了需要的内存

最佳解决方案是:

这将循环通过
set_2
,更新
set_1
。请注意在
ZADD
命令中使用
XX
,以仅更新(如果存在)

用作:

EVAL "local set2 = redis.call('ZRANGE', KEYS[1], '0', '-1', 'WITHSCORES') \n local set2length = table.getn(set2) \n for i=1,set2length,2 do print(1) redis.call('ZADD', KEYS[2], 'XX', set2[i+1], set2[i]) end \n return set2length/2" 2 set_2 set_1

由于Redis的单线程特性,Lua脚本是原子的。

SET命令仅适用于常规键,而不适用于排序集

在排序集中,您有分数成员对,因此示例中的键值对命名法有点混乱。我假设
key_1,key_2,key_3,…
是成员,
val_1,val_2,…
是分数

让我们按如下方式创建排序集以查看解决方案:

> ZADD set_1 1 key_1 2 key_2 3 key_3
(integer) 3
> ZADD set_2 1001 key_1 1003 key_3 1004 key_4
(integer) 3
默认的
AGGREGATE
SUM
,这是我们将在整个系统中使用的

我们将创建两个具有两者交集的排序集,一个分数为
set_1
,另一个分数为
set_2

> ZINTERSTORE intersect_set_1 2 set_1 set_2 WEIGHTS 1 0
(integer) 2
> ZINTERSTORE intersect_set_2 2 set_1 set_2 WEIGHTS 0 1
(integer) 2
现在,我们为
set_1
创建一个中间步骤集,其中
set_2
中的那些步骤的分数也设置为零:

> ZUNIONSTORE pre_set_1 2 set_1 intersect_set_1 WEIGHTS 1 -1
(integer) 3
现在,我们已经准备好更新集合_1,进行以下并集:

  • pre_set_1
    :所有
    设置_1
    ,但也将
    中的设置_2
    设置为零分
  • intersect\u set\u 2
    set\u 1
    set\u 2
    的交点,分数为
    set\u 2
这是最后一个命令:

> ZUNIONSTORE set_1 2 pre_set_1 intersect_set_2
(integer) 3
让我们看看结果:

> ZRANGE set_1 0 -1 WITHSCORES
1) "key_2"
2) "2"
3) "key_1"
4) "1001"
5) "key_3"
6) "1003"
别忘了清理:

> UNLINK pre_set_1 intersect_set_1 intersect_set_2
此解决方案不是最优的,因为它使用多个中间步骤,中间添加到原始集合的成员存在风险,并且它使用的内存超过了需要的内存

最佳解决方案是:

这将循环通过
set_2
,更新
set_1
。请注意在
ZADD
命令中使用
XX
,以仅更新(如果存在)

用作:

EVAL "local set2 = redis.call('ZRANGE', KEYS[1], '0', '-1', 'WITHSCORES') \n local set2length = table.getn(set2) \n for i=1,set2length,2 do print(1) redis.call('ZADD', KEYS[2], 'XX', set2[i+1], set2[i]) end \n return set2length/2" 2 set_2 set_1
由于Redis的单线程特性,Lua脚本是原子的