4

注文したセットがあります-スコアを付けて、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との共通部分を見つけるための最良の方法は何ですか?

4

2 に答える 2

3

重要な点は、ソートされたセットコマンドが通常のセットをパラメーターとして受け入れることです。したがって、最初にセットと交差してから、通常の範囲コマンドを使用してスコアに基づいてフィルタリングできます。

例:

# 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
于 2013-02-12T11:22:28.043 に答える
2

最初に範囲を取得し、後で交差する方法を知りません。ただし、できることは、セットを交差させてから、次の範囲を実行することです。

ZINTERSTORE items_with_tag_foo 2 items tag_foo AGGREGATE MAX
ZRANGEBYSCORE items_with_tag_foo 17 +inf
于 2013-02-12T11:06:09.740 に答える