redis sortコマンドの使い方まとめ
redis sortコマンドの使い方についてまとめました。
この記事で説明する内容は下記の環境で動作確認を行いました。
- Windows7 (64bit)
- redis 2.8.19
sortコマンドの仕様
sortコマンドは、リスト、セット、ソート済みセットのメンバーや外部データを使って要素のソートを行います。
SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]
参考
[redis command - sort] (http://redis.io/commands/sort)
使い方の確認方法
次のサンプルデータを使用してsortコマンドの使い方を確認します。
サンプルデータ
果物データ
「果物データ」は果物の名前、重量、糖度などをハッシュで格納します。
ハッシュのキー名はfruits:
に続けて果物の名前を付加します。
例えば、りんごのハッシュキーは下記のようになります。
fruits:apple
果物データの内容
id | weight | sugar | name | desc |
---|---|---|---|---|
1 | 300 | 14 | apple | バラ科リンゴ属の落葉高木樹。またはその果実のこと |
2 | 180 | 12 | orange | ミカン科ミカン属の常緑小高木、またはその果実のこと |
3 | 140 | 10 | grape | ブドウ科のつる性落葉低木である。またその果実のこと |
5 | 200 | 12 | peach | バラ科モモ属の落葉小高木。またその果実のこと |
4 | 300 | 10 | mango | ウルシ科マンゴー属の果樹、またその果実 |
6 | 190 | 13 | melon | 果肉色は、主に赤肉種・青肉種・白肉種に分類される |
7 | 15 | 7 | lemon | ミカン科ミカン属の常緑低木、またはその果実のこと |
8 | 95 | 21 | banana | バショウ科バショウ属のうち、果実を食用とする品種群の総称 |
9 | 3000 | 12 | watermelon | 果実を食用にするために栽培されるウリ科のつる性一年草、またその果実のこと |
10 | 44 | 13 | strawberry | バラ科の多年草 |
11 | 300 | 13 | pear | 果肉は白色で、甘く果汁が多い |
- id: 管理No
- weight : 平均重量(g)
- sugar : 平均糖度(%)
- name : 名称(ハッシュのキー名の一部にもなります)
果物の人気ランキング
「果物の人気ランキング」は人気ポイントをスコアとするソート済みセットで管理します。
ソート済みセットのキー名はpopular
とします。
人気ランキングの内容
member | point (score) | メモ |
---|---|---|
strawberry | 75 | |
orange | 68 | |
peach | 68 | |
pear | 65 | |
apple | 64 | |
grape | 61 | |
melon | 59 | |
watermelon | 58 | |
banana | 56 | |
mango | 0 | ランキング外なので0ポイント |
lemon | 0 | ランキング外なので0ポイント |
好きな果物データ
好きな果物を持ったセットです。上記のハッシュやランキングには無い果物もあります。
セットのキー名はmyfavorite
とします。
member | メモ |
---|---|
apple | |
orange | |
peach | |
pear | |
pineapple | パイナップルは上記の果物データにも人気ランキングにもありません |
サンプルデータの準備
果物データの登録 (ハッシュ)
> hmset fruits:apple id 1 weight 300 sugar 14 name "apple" desc "バラ科リンゴ属の落葉高木樹。またはその果実のこと"
> hmset fruits:orange id 2 weight 180 sugar 12 name "orange" desc "ミカン科ミカン属の常緑小高木、またはその果実のこと"
> hmset fruits:grape id 3 weight 140 sugar 10 name "grape" desc "ブドウ科のつる性落葉低木である。またその果実のこと"
> hmset fruits:peach id 4 weight 200 sugar 12 name "peach" desc "バラ科モモ属の落葉小高木。またその果実のこと"
> hmset fruits:mango id 5 weight 300 sugar 10 name "mango" desc "ウルシ科マンゴー属の果樹、またその果実"
> hmset fruits:melon id 6 weight 190 sugar 13 name "melon" desc "果肉色は、主に赤肉種・青肉種・白肉種に分類される"
> hmset fruits:lemon id 7 weight 15 sugar 7 name "lemon" desc "ミカン科ミカン属の常緑低木、またはその果実のこと"
> hmset fruits:banana id 8 weight 95 sugar 21 name "banana" desc "バショウ科バショウ属のうち、果実を食用とする品種群の総称"
> hmset fruits:watermelon id 9 weight 3000 sugar 12 name "watermelon" desc "果実を食用にするために栽培されるウリ科のつる性一年草、またその果実のこと"
> hmset fruits:strawberry id 10 weight 44 sugar 13 name "strawberry" desc "バラ科の多年草"
> hmset fruits:pear id 11 weight 300 sugar 13 name "pear" desc "果肉は白色で、甘く果汁が多い"
果物の人気ランキングの登録 (ソート済みセット)
> zadd popular 75 strawberry 68 orange 68 peach 65 pear 64 apple 61 grape 59 melon 58 watermelon 56 banana 0 mango 0 lemon
(integer) 11
好きな果物データの登録 (セット)
> sadd myfavorite apple orange peach pear pineapple
(integer) 5
使い方の確認
外部データを使ったソート(その1)
「果物の人気ランキング」をハッシュ型の「果物データ」を使ってソートします。
この例では「果物データ」が持つweightフィールドの降順でソートします。
> sort popular by fruits:*->weight get # get fruits:*->id get fruits:*->weight desc
1) "watermelon"
2) "9"
3) "3000"
4) "pear"
5) "11"
6) "300"
7) "mango"
8) "5"
9) "300"
10) "apple"
11) "1"
12) "300"
13) "peach"
14) "4"
15) "200"
16) "melon"
17) "6"
18) "190"
19) "orange"
20) "2"
21) "180"
22) "grape"
23) "3"
24) "140"
25) "banana"
26) "8"
27) "95"
28) "strawberry"
29) "10"
30) "44"
31) "lemon"
32) "7"
33) "15"
確認点
byオプションでソートに使用するフィールドを指定します。
この例では、fruits:*
ハッシュのweightフィールドを使用しています。
by fruits:*->weight
*
はpopular
の各メンバーが当てはめられるワイルドカードの役目を果たします。
たとえば、メンバーが"apple"のときは次のように解釈することができます。
by fruits:apple->weight
getオプションの#
は、キーに指定したpopular
のメンバーを取得します。
get #
->
は、ハッシュのフィールドを指します。
この例では、fruits:*
ハッシュのidフィールドを取得しています。
get fruits:*->id
外部データを使ったソート(その2)
nameフィールドでソートしようとするとエラーが発生します。
ソートに使用するフィールドの値が数値として表現できない場合は下記のエラーとなります。
> sort popular by fruits:*->name get # get fruits:*->id get fruits:*->weight asc
(error) ERR One or more scores can't be converted into double
確認点
文字列でソートする場合は、alpha
修飾子を使用します。
> sort popular by fruits:*->name get # get fruits:*->id get fruits:*->weight asc alpha
1) "apple"
2) "1"
3) "300"
4) "banana"
5) "8"
6) "95"
7) "grape"
8) "3"
9) "140"
10) "lemon"
11) "7"
12) "15"
13) "mango"
14) "5"
15) "300"
16) "melon"
17) "6"
18) "190"
19) "orange"
20) "2"
21) "180"
22) "peach"
23) "4"
24) "200"
25) "pear"
26) "11"
27) "300"
28) "strawberry"
29) "10"
30) "44"
31) "watermelon"
32) "9"
33) "3000"
複数の外部データを利用する
各果物の在庫を管理するため文字列型のキーに在庫数を登録します。
> set warehouse:apple "30"
> set warehouse:orange "50"
> set warehouse:grape "15"
> set warehouse:peach "20"
> set warehouse:mango "15"
> set warehouse:melon "5"
> set warehouse:lemon "45"
> set warehouse:banana "60"
> set warehouse:watermelon "30"
> set warehouse:strawberry "15"
> set warehouse:pear "10"
在庫数を上記の文字列型より取得します。
この例のように、複数の外部データからデータを取得することができます。
> sort popular by fruits:*->id get # get fruits:*->id get warehouse:* asc
1) "apple"
2) "1"
3) "30"
4) "orange"
5) "2"
6) "50"
7) "grape"
8) "3"
9) "15"
10) "peach"
11) "4"
12) "20"
13) "mango"
14) "5"
15) "15"
16) "melon"
17) "6"
18) "5"
19) "lemon"
20) "7"
21) "45"
22) "banana"
23) "8"
24) "60"
25) "watermelon"
26) "9"
27) "30"
28) "strawberry"
29) "10"
30) "15"
31) "pear"
32) "11"
33) "10"
確認点
文字列型の場合は->
を使用する必要はありません。
*
の部分にメンバーが当てはめられると完全なキー名となり、そのキーが持つ値を取得します。
get warehouse:*
たとえば、メンバーが"apple"のときは次のように解釈することができます。
get warehouse:apple
取得するデータ位置、件数の指定
limit修飾子を使って取得するデータ位置と件数を指定することができます。
offsetにはデータの取得位置を指定します。(offsetは0から始まります)
countには取得したい件数を指定します。
LIMIT offset count
この例では先頭から5件取得します。
> sort popular by fruits:*->weight get # get fruits:*->id get fruits:*->weight limit 0 5 desc
1) "watermelon"
2) "9"
3) "3000"
4) "pear"
5) "11"
6) "300"
7) "mango"
8) "5"
9) "300"
10) "apple"
11) "1"
12) "300"
13) "peach"
14) "4"
15) "200"
該当する外部データが無い場合
sortコマンドのキーに指定したデータ(この例ではmyfavorite
のメンバー)と対応する外部データが無い場合はnil
が返ります。
この例では、pineappleに対応するハッシュが存在しないのでnil
が返ります。
> sort myfavorite by fruits:*->id get # get fruits:*->id get fruits:*->weight asc
1) "pineapple"
2) (nil)
3) (nil)
4) "apple"
5) "1"
6) "300"
7) "orange"
8) "2"
9) "180"
10) "peach"
11) "4"
12) "200"
13) "pear"
14) "11"
15) "300"
外部データを使わないソート
キーのメンバーでソートするシンプルなソートですが、セット型やリスト型もソートすることが可能です。
この例では、myfavorite
のメンバー(appleやorange)で昇順のソートを行っています。
メンバーはアルファベットなのでalpha修飾子が必要です。もしメンバーが数値であれば必要ありません。
> sort myfavorite asc alpha
1) "apple"
2) "orange"
3) "peach"
4) "pear"
5) "pineapple"
ソート済みセットもメンバーでソートすることが可能ですが、スコアでソートさせたい場合はbyオプションにnosort
を指定します。
> sort popular by nosort desc
1) "strawberry"
2) "peach"
3) "orange"
4) "pear"
5) "apple"
6) "grape"
7) "melon"
8) "watermelon"
9) "banana"
10) "mango"
11) "lemon"
ソート結果を保存する
store
オプションでソート結果をリスト形式で保存することができます。
127.0.0.1:6379> sort popular by fruits:*->id get # get fruits:*->id get fruits:*->weight get fruits:*->sugar limit 0 5 asc store dest
(integer) 20
> type dest
list
> lrange dest 0 -1
1) "apple"
2) "1"
3) "300"
4) "14"
5) "orange"
6) "2"
7) "180"
8) "12"
9) "grape"
10) "3"
11) "140"
12) "10"
13) "peach"
14) "4"
15) "200"
16) "12"
17) "mango"
18) "5"
19) "300"
20) "10"