RedisのZUNIONSTORE、ZINTERSTORE を理解する
公式ドキュメントのZUNIONSTOREとZINTERSTOREに書いてあるけれど、図解しないとわかりにくいと思います。
前提
私のSortedSetに対する理解の仕方について
私は、SortedSetをこのように理解しているので、そのつもりでお願いします。
このページで使用する、サンプルデータ
説明用に、事前に以下のように2つのSortedSetレコードを準備したことにします。
ZADD zset1 1 "one"
ZADD zset1 2 "two"
ZADD zset1 3 "three"
ZADD zset2 11 "one"
ZADD zset2 33 "three"
ZADD zset2 44 "four"
表にすると、各レコード(変数)は以下のようになってます。
縦軸にkey
、横軸にmember
、値がScore
です。
↓member\key→ | zset1 | zset2 |
---|---|---|
one | 1 | 11 |
two | 2 | (nil) |
three | 3 | 33 |
four | (nil) | 44 |
基本
Union(和集合)とかIntersect(共通集合)をして、Store(保存)します。デフォだと、各レコードにあるScore
を足し算します。
ミニマルな文法は、以下の通りです。
ZUNIONSTORE destination numkeys key [key ...]
ZINTERSTORE destination numkeys key [key ...]
-
distination
は、出力先のkey
名 -
num
は、Union・IntersectしたいSortedSet
の数 -
key
は、Union・IntersectしたいSortedSet
のKey名
ZUNIONSTORE(和集合)の例
ZUNIONSTORE union1 2 zset1 zset2
これをやると、以下の表のようになります。
↓member\key→ | zset1 | zset2 | union1 |
---|---|---|---|
one | 1 | 11 | → 12 |
two | 2 | (nil) | → 2 |
three | 3 | 33 | → 39 |
four | (nil) | 44 | → 44 |
SortedSet
は常にScore
でソートされるので、以下のようになります。
ZRANGE union1 0 -1 WITHSCORES
1) "two"
2) "2"
3) "one"
4) "12"
5) "three"
6) "36"
7) "four"
8) "44"
ZINTERSTORE(共通集合)の例
ZINTERSTORE inter1 2 zset1 zset2
これをやると、以下の表のようになります。
↓member\key→ | zset1 | zset2 | inter1 |
---|---|---|---|
one | 1 | 11 | → 12 |
two | 2 | (nil) | → (nil) |
three | 3 | 33 | → 39 |
four | (nil) | 4 | → (nil) |
どうなってるか、確認してみます。
ZRANGE inter1 0 -1 WITHSCORES
1) "one"
2) "12"
3) "three"
4) "36"
各種オプション
UNIONとINTERSECTが何かはわかったと思うので、オプションはUNIONで説明します。(公式ドキュメントも、INTERSECTの方には「UNIONのほう見て」って書いてあるし。)
WEIGHTSオプション
各key
に対するWEIGHTS
(重み)オプションです。(この説明わかるのか…?)
ZUNIONSTORE
とZINTERSTORE
に対するWEIGHTS
の文法は、以下の通りです。
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]]
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]]
…まぁ、同じですな。
-
weight
は、key
と同じ数になります。
WEIGHTSオプションを使うとどうなるか
以下のようにやってみましょう。
ZUNIONSTORE union2 2 zset1 zset2 WEIGHTS 2 7
これをやると、以下の表のようになります。
↓member\key→ | zset1(×2) | zset2(×7) | union2 |
---|---|---|---|
one | 1×2 | 11×7 | → 79 |
two | 2×2 | (nil) | → 4 |
three | 3×2 | 33×7 | → 237 |
four | (nil) | 44×7 | → 308 |
SortedSetは、Score
で常にソートされるので、以下のようになります。
ZRANGE union2 0 -1 WITHSCORES
1) "two"
2) "4"
3) "one"
4) "79"
5) "three"
6) "237"
7) "four"
8) "308"
AGGREGATEオプション
「基本」の説明で、以下のように書きました。
デフォだと、各レコードにあるScoreを足し算します。
この挙動を変更するオプションです。
このオプションの文法は、以下の通りです。
ZINTERSTORE destination numkeys key [key ...] [AGGREGATE SUM|MIN|MAX]
ZUNIONSTORE destination numkeys key [key ...] [AGGREGATE SUM|MIN|MAX]
例によって、同じです。
AGGREGATEオプションを使うとどうなるか
以下のようにやってみましょう。
ZUNIONSTORE union3 2 zset1 zset2 AGGREGATE MIN
AGGREGATE MIN
としているので、小さいほうが選ばれます。
↓member\key→ | zset1(×2) | zset2(×7) | union2 |
---|---|---|---|
one | 1 | 11 | → 1 |
two | 2 | (nil) | → 2 |
three | 3 | 33 | → 3 |
four | (nil) | 44 | → 44 |
ZRANGE union3 0 -1 WITHSCORES
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
7) "four"
8) "44"
全部合わせてみる
最後に、4つのSortedSet
に対して、適当にWEIGHTS
とAGGREGATE MAX
を使った場合の例を載せておきます。
ZADD zset1 1 "one"
ZADD zset1 2 "two"
ZADD zset1 3 "three"
ZADD zset2 11 "one"
ZADD zset2 33 "three"
ZADD zset2 44 "four"
ZADD zset3 12 "one"
ZADD zset3 inf "three"
ZADD zset3 0 "four"
ZADD zset4 inf "one"
ZADD zset4 33 "three"
ZINTERSTORE inter4 4 zset1 zset2 zset3 zset4 WEIGHTS 13 1 1 0 AGGREGATE MAX
↓member\key→ | zset1(×13) | zset2(×1) | zset3(×1) | zset4(×0) | inter4 |
---|---|---|---|---|---|
one | 1×13 | 11×1 | 12×1 | inf×0 | →13 |
two | 2×13 | (nil) | (nil) | (nil) | →(nil) |
three | 3×13 | 33×1 | inf×1 | 33×0 | → inf |
four | (nil) | 44×13 | 0×1 | (nil) | →(nil) |
ZRANGE inter4 0 -1 WITHSCORES
1) "one"
2) "13"
3) "three"
4) "inf"
なるほど、WEIGHTS
の演算結果で、Score
の大きさを比較するんですね。
おわり
Author And Source
この問題について(RedisのZUNIONSTORE、ZINTERSTORE を理解する), 我々は、より多くの情報をここで見つけました https://qiita.com/ndxbn/items/c39c52497e488d2d68cd著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .