Redis:找到范围和无序集的交集

时间:2013-02-12 01:04:20

标签: ruby-on-rails redis

我有一个有序的设置 - 我已经得分并通过gem'redis'添加到我的redis数据库中的项目如下:

Item.each { |item|
  $redis.zadd("scores", item.score, item.id)
}

一整套带有基于标签ID的密钥的项目。

Tag.each { |tag|
  tag.items.each { |item|
     $redis.sadd("tag_#{tag.id}", item.id)
  }
}

我正在尝试获得分数为 x或更高的所有项目,并将其与具有特定标记的所有项目相交。我不需要对结果进行排序。我不确定我是否需要首先使用有序集,但它似乎是存储和检索结果的有效方法。

使用Redis查找范围和集合的交集的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

关键点是有序集合命令也接受正常集合作为参数。因此,您可以先与集合相交,然后使用正常范围命令根据分数进行过滤。

示例:

# Populate some sorted set and set
./redis-cli zadd scores 1 a 2 b 3 c 4 d 5 e 6 f 7 g 8 h
(integer) 8
./redis-cli sadd tag_1 a c d g h
(integer) 5

# Here you need to use a weight clause to avoid altering the score
./redis-cli zinterstore res 2 scores tag_1 weights 1 0
(integer) 5

# Now fetch the expected items (here we want items with score >= 4)
./redis-cli zrangebyscore res 4 +inf withscores
1) "d"
2) "4"
3) "g"
4) "7"
5) "h"
6) "8"

# Finally drop the temporary result
./redis-cli del res
(integer) 1

答案 1 :(得分:1)

我不知道有办法先获得一个范围,然后再交叉。但是,您可以做的是制作集合的交集,然后执行范围:

ZINTERSTORE items_with_tag_foo 2 items tag_foo AGGREGATE MAX
ZRANGEBYSCORE items_with_tag_foo 17 +inf