【问题标题】:Redis: How to intersect a "normal" set with a sorted set?Redis:如何将“正常”集合与排序集合相交?
【发布时间】:2012-05-17 01:25:52
【问题描述】:

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

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

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

我想要每个元组 (X, SCORE_OF_X_IN_B) X 在 C 中。

有什么想法吗?

我有两个想法:

  1. 店间
    • 将 A 存储为每个分数为 0 的排序集
    • 中间存储到 D
    • 得到D的每一项
    • 删除D
  2. 客户端中的简单循环
    • 在我的客户端程序中循环 A
    • 获取每个字符串的 zscore

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

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

所以我只是想问一下,是否有无需编写脚本的优雅且快速的解决方案!

【问题讨论】:

    标签: redis


    【解决方案1】:

    您的问题有一个简单的解决方案:ZINTERSTORE 将与 SETZSET 一起使用。试试:

    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"
    

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

    【讨论】:

    • 这几乎正是我在问题中所写的内容(见上文,第 1 点)。我还写过我认为这个解决方案太慢了。注意我要求一个优雅而快速的解决方案,而不是一个简单的解决方案!不知道你可以用一个集合和一个排序集合做一个直接的 zinterstore。感谢您的回答,很抱歉显然选择了一个糟糕的标题...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多