redis有序集合求差集 zdiff?


我们知道redis集合计算差集的命令是 sdiff。那么有序集合的差集是用 zdiff 命令吗?redis api目前是不支持这个命令的。其实有序集合求差集还是有使用场景的。

使用场景例子

有序集合记录了英语兴趣课(key=english)、数学兴趣课(key=math)的学员及成绩。

```

127.0.0.1:6379> zadd english 98 user1 85 user2 88 user3

(integer) 3

127.0.0.1:6379> zadd math 77 user2 69 user4 100 user5

(integer) 3

```

需要计算出只参加了英语兴趣课的学员

redis有序集合求差集 zdiff?_第1张图片

解决思路

A)使用集合diff

客户端程序把有序集合的学员数据导入到无序集合,通过集合的diff计算出结果

B)利用有序集合里已有命令

* ZUNIONSTORE 计算并集,并设置并集后元素计分权重

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

* ZREMRANGEBYSCORE 去除计分为0的元素

> ZREMRANGEBYSCORE key min max

redis命令实现

```

127.0.0.1:6379> zunionstore result 2 english math weights 1 0 aggregate min

(integer) 5

127.0.0.1:6379> zremrangebyscore result 0 0

(integer) 3

127.0.0.1:6379> zrange result 0 -1

1) "user3"

2) "user1"

```

进一步优化,命令合并

```

redis-zset-diff.lua 文件

local zsetKey1=KEYS[1];

local zsetKey2=KEYS[2];

local zsetKeyResult=ARGV[1];

redis.call("zunionstore", zsetKeyResult, 2, zsetKey1, zsetKey2, "weights", 1, 0, "aggregate", "min");

redis.call("zremrangebyscore", zsetKeyResult, 0, 0);

return redis.call("zrange", zsetKeyResult, 0, -1);

执行命令

~ redis-cli --eval redis-zset-diff.lua english math , result

1) "user3"

2) "user1"

```

或者执行合并的lua脚本

```

127.0.0.1:6379> eval 'local zsetKey1=KEYS[1];local zsetKey2=KEYS[2];local zsetKeyResult=ARGV[1];redis.call("zunionstore", zsetKeyResult, 2, zsetKey1, zsetKey2, "weights", 1, 0, "aggregate", "min");redis.call("zremrangebyscore", zsetKeyResult, 0, 0);return redis.call("zrange", zsetKeyResult, 0, -1);' 2 english math reslut

1) "user3"

2) "user1"

```

你可能感兴趣的:(redis有序集合求差集 zdiff?)