如何更新Redis中另一个排序集的排序集?

鱼云

我是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文档,似乎将他的SET命令与XX选项一起使用可能会有所帮助:

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

现在,我们准备更新set_1,并进行以下操作的并集:

  • pre_set_1set_1除了那些也set_2设置为零的分数。
  • intersect_set_2:的交点set_1set_2与的得分set_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

此解决方案不是最佳方案,因为它使用了多个中间步骤,存在成员之间添加到原始集中的风险,并且它使用了不必要的内存。

最佳解决方案是Lua脚本

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

这循环进行set_2,更新set_1注意XXZADD命令中的使用在存在时进行更新。

用于:

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脚本是原子的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在Redis中创建一个空的排序集

根据另一个表中的信息对结果集进行排序

根据另一个查询集的长度排序查询集

(如何)迭代Redis排序集是一个好主意吗?

Django如何从模板中的另一个查询集获取查询集

我可以指定因子水平作为另一个数据集的排序变量吗?

如何在保持排序的同时将排序的链表插入另一个排序的链表?

根据如何对另一个未排序的arrayList进行排序java对arrayList进行排序

根据另一个图表中动态更新的轴顺序对图表轴进行排序

如何对另一个列表进行排序?

如何在Kotlin中将一个集过滤到另一个集

从另一个适配器中更新适配器数据集

如何根据另一个表中的索引序列对列中的名称进行排序?

如何在ssrs中引用表中的另一个数据集?

排序基于排序另一个阵列的

排序字典,然后用另一个排序

如何根据mysql中的另一个表对结果进行排序

如何在Matlab中使用另一个向量中的值对矩阵进行排序?

如何从另一个表中按平均评分对产品进行排序?

在numpy中,如何对另一个数组按相同顺序排序?

如何通过另一个json值对json中的键进行排序

如何用Java中的另一个对象的属性对对象列表进行排序?

如何根据另一个文件中的列对文件排序?

如何基于Python中的另一个集合对集合进行排序?

如何基于Angular JS中的另一个数组重新排序

如何对向量进行重新排序,使其与R中另一个向量的顺序匹配?

如何按 Ruby 中另一个数组的值对哈希进行排序?

如何在Lodash中对另一个列表进行排序

如何在另一个孩子Firebase中按孩子排序