Redis:如何将"普通"集与排序集相交?

use*_*529 19 redis

假设我有一个集合(或排序集或列表,如果那样会更好)A 100到1000个字符串.

然后我有一个更多字符串的排序集B,比如一百万.

现在C应该是AB(当然是字符串)的交集.

我希望得到每个元组(X,SCORE_OF_X_IN_B),其中X在C中.

任何的想法?

我有两个想法:

  1. Interstore
    • store一个排序集,每个得分为0
    • interstore到D.
    • 得到D的每一项
    • 删除D.
  2. 客户端的简单循环
    • 在我的客户端程序中循环A.
    • 获得每个字符串的zscore

虽然1.在redis方面有太多的开销(例如,必须写.重写页面表明相当高的时间复杂度,也是http://redis.io/commands/zinterstore),2.会有| A | 数据库连接并不是一个好的选择.

也许我可以编写一个redis/lua脚本,它可以像zscore一样工作但是有任意数量的字符串,但我不确定我的主机是否允许脚本...

所以我只想问问,如果有一个优雅而快速的解决方案,没有脚本!

Lin*_*iel 39

您的问题有一个简单的解决方案:ZINTERSTORE将使用a SET和a ZSET.尝试:

redis> sadd foo a
(integer) 1
redis> zadd bar 1 a
(integer) 1
redis> zadd bar 2 b
(integer) 1
redis> zinterstore baz 2 foo bar AGGREGATE MAX
(integer) 1
redis> zrange baz 0 -1 withscores
1) "a"
2) "1"
Run Code Online (Sandbox Code Playgroud)

编辑:我在AGGREGATE MAX上面添加了,因为redis会给(未排序的)集合foo的每个成员一个默认分数1,并且SUM它具有(排序)集合中的任何分数bar.

  • 这几乎就是我在我的问题中所写的内容(见上文第1点).我也写过,我认为这个解决方案太慢了.注意我要求一个优雅而快速的解决方案,而不是简单的解决方案!不知道你可以用套装和排序套装做直接的zinterstore.谢谢你的回答,很抱歉显然选择了糟糕的标题...... (2认同)