Wpz's Blog

闻道有先后,术业有专攻。

0%

Redis 之 有序集合差集

有序集合没有差集命令

Redis集合中提供了SINTERSUNIONSDIFF命令分别用来处理集合的交集、并集、差集运算。

有序集合中提供了ZINTERSTOREZUNIONSTORE命令分别用来处理有序集合的交集、并集运算。却没有提供用来处理有序集合差集的命令。

项目中用到Redis的有序集合来存储数据,需要对有序集合进行差集运算,在网上看到这篇文章:redis有序集合求差集 zdiff? 提供的解决方法,在此记录下。

解决思路

先使用ZUNIONSTORE计算并集,并设置并集后成员分数权重。

ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

再使用ZREMRANGEBYSCORE去除分数为0的成员。

ZREMRANGEBYSCORE key min max

栗子

先添加两个有序集合chineseenglish

127.0.0.1:6379> ZADD chinese 100 user1 99 user2 98 user3
(integer) 3
127.0.0.1:6379> ZADD english 97 user3 96 user4 95 user5
(integer) 3
127.0.0.1:6379> ZRANGE chinese 0 10 WITHSCORES
1) "user3"
2) "98"
3) "user2"
4) "99"
5) "user1"
6) "100"
127.0.0.1:6379> ZRANGE english 0 10 WITHSCORES
1) "user5"
2) "95"
3) "user4"
4) "96"
5) "user3"
6) "97"

再对有序集合chineseenglish进行并集运算:

127.0.0.1:6379> ZUNIONSTORE result 2 chinese english WEIGHTS 1 0 AGGREGATE MIN
(integer) 5
127.0.0.1:6379> ZRANGE result 0 10 WITHSCORES
1) "user3"
2) "0"
3) "user4"
4) "0"
5) "user5"
6) "0"
7) "user2"
8) "99"
9) "user1"
10) "100"

这里有必要对ZUNIONSTOREWEIGHTSAGGREGATE选项进行说明一番:

  • WEIGHTS选项可以为每个给定的有序集合分别指定一个乘法因子(Multiplication Factor)。每个给定的有序集合的所有成员的分数在传递给聚合函数(Aggregation Function)之前都要先乘以该有序集合的因子。默认值为1

  • AGGREGATE选项指定并集运算结果的聚合方式。默认值为SUM,即将所有相同成员的分数相加。当值为MINMAX时,则取所有相同成员的分数的最小值或最大值。

有序集合chinese的权重设置为1,所以合并后user1user2的分数和合并前一样。有序集合english的权重设置为0,所以合并后user4user5的分数变为0。至于user3的分数,chinese98english0,由于AGGREGATE值为MIN,所以取最小值0

最后移除有序集合result中分数为0的成员:

127.0.0.1:6379> ZREMRANGEBYSCORE result 0 0
(integer) 3
127.0.0.1:6379> ZRANGE result 0 10 WITHSCORES
1) "user2"
2) "99"
3) "user1"
4) "100"

现在有序集合result就为chineseenglish进行差集运算的结果。

----------------本文结束感谢您的阅读----------------
复制本文地址随便逛逛听听小曲破坏小飞机简繁切换昼夜更替切换鼠标右键
主站网站导航Linux命令
开往虫洞跃迁