2013-02-12 15 views
3

我有一个有序集合 - 我已经通过了创业板redis的“得分,并添加到我的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查找范围和集合的交集的最佳方法?

+0

我是有Redis的2.2.5中的问题。当我试图调用zinterstore命令时,我会得到这个错误。 “无法连接到Redis 127.0.0.1:6379:连接被拒绝。”升级到Redis 2.4.13后,这个错误消失了。 – Swards 2013-02-12 19:10:37

+0

另一个说明 - 关于redis 2.4.13,我无法使用zionterstore中的sunionstore的结果。升级再次解决了这个问题。现在在版本2.6.10上运行良好。 – Swards 2013-02-16 19:20:41

回答

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 
+0

感谢您删除临时商店的提示 – Swards 2013-02-12 19:09:46

1

我不知道有一种方法先获取范围,然后再相交。你可以做什么,虽然是使集的交集,然后执行范围:

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

我明白了 - 这很有道理。 – Swards 2013-02-12 19:02:31