LoginSignup
20
17

More than 5 years have passed since last update.

Railsで使うRedisのコマンドについてまとめてみた(Part1: Sets)

Last updated at Posted at 2015-10-30

概要

Redisのメソッドはhttp://redis.io/commands/ にあるように大量にあるので1つずつ和訳して見た。
ついでにrailsでそのコマンドをどう使うかについても記す。
英語に不自由ない方は、直接ドキュメント見ていただいた方が正確かと。

Redisの導入については、Rails + Redis + AWSでPV数を保存を参照していただきたく。

Part1ではSetsのコマンド郡についてまとめる。

Setsの主な用途

  • (key,value)のペアに対して、valueの方に値を重複なく突っ込みたい場合
    • 「お気に入りリスト」などに使う場合
  • とりあえず集合知(配列)状のデータを扱いたい場合

コマンド詳細

基本的には、http://redis.io/commands/#set に載っているものを翻訳してみただけです。

SADD(値の追加)

計算量:O(N) Nは挿入される要素の数
(key,value)のkeyに対し、値を追加するときに使う。一度追加されたものは、重複して追加されない。(重複関係なしにデータが)うまく追加できなかった時にエラーを返す。
(railseのラッパーでは1つしか挿入できない)

戻り値

Integer:新規で挿入できた値の個数を返す。
重複した値を挿入しようとし、新規で追加されない場合、0を返す。
(railsのラッパーを通すとtrue,falseで返る)

使用例

pry(main)> Redis.current.sadd('key', 'yamada')
=> true
pry(main)> Redis.current.sadd('key', 'genki')
=> true
pry(main)> Redis.current.sadd('key', 'yamada')
=> false
pry(main)> Redis.current.sadd('key', 'yamada')
=> false
pry(main)> Redis.current.smembers('key')
=> ["yamada", "genki"]
pry(main)> Redis.current.sadd('key', 'yamada', 'owata')
ArgumentError: wrong number of arguments (3 for 2)
from /vagrant/www/job-medley/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis.rb:1230:in `sadd'

SCARD(値の個数確認)

計算量:O(1)
(key,value)のkeyに対し、保存されている値の個数を返す。

戻り値

Integer:keyに保存されている値の個数を返す。keyがなければ0を返す。

使用例

pry(main)> Redis.current.sadd('key', 'yamada')
=> true
pry(main)> Redis.current.sadd('key', 'genki')
=> true
pry(main)> Redis.current.sadd('key', 'yamada')
=> false
pry(main)> Redis.current.scard('key')
=> 2
pry(main)> Redis.current.scard('yamada')
=> 0

SDIFF(データの差分)

計算量:O(N) Nは渡されるすべての要素の数
複数の(key,value)データに対して、そのvalueの差を返す。
比較はいくつでもでき、1つめに指定したkeyにしか含まれないvalueが返る。

戻り値

Array: 差分となるリストを返す(1つ目に指定したkeyにのみ含まれるものを返す)

使用例

pry(main)> Redis.current.smembers('a')
=> ["1", "2", "4", "5"]
pry(main)> Redis.current.smembers('b')
=> ["1", "3"]
pry(main)> Redis.current.smembers('c')
=> ["1", "4"]
pry(main)> Redis.current.sdiff('a','b')
=> ["2", "4", "5"]
pry(main)> Redis.current.sdiff('a','b','c')
=> ["2", "5"]

SDIFFSTORE(データの差分を保存)

計算量:O(N) Nは渡されるすべての要素の数
基本的にはSDIFF(データの差分)と同じ。
新しいkeyを指定し、そのkeyに差分となるデータを保存してくれる。
keyが既に存在していた場合は、上書きされる。

戻り値

Integer: 差分となるリストに含まれる要素の個数

使用例

pry(main)> Redis.current.smembers('a')
=> ["1", "2", "4", "5"]
pry(main)> Redis.current.smembers('b')
=> ["1", "3"]
pry(main)> Redis.current.smembers('c')
=> ["1", "4"]
pry(main)> Redis.current.sdiffstore('ab', 'a','b')
=> 3
pry(main)> Redis.current.sdiffstore('abc', 'a','b', 'c')
=> 2
pry(main)> Redis.current.smembers('ab')
=> ["2", "4", "5"]
pry(main)> Redis.current.smembers('abc')
=> ["2", "5"]

SINTER(重複した要素)

計算量:O(N*M) 基本的に1つずつ比較するので、最悪N*M
渡された(key,value)のデータ間で、重複した要素を配列で返してくれる。
keyが存在しない場合は、空のデータとして認識される。
その場合、戻り値も空の配列。

戻り値

Array: 重複した要素の配列を返す。

使用例

pry(main)> Redis.current.smembers('a')
=> ["1", "2", "3", "4", "5"]
pry(main)> Redis.current.smembers('b')
=> ["1", "3"]
pry(main)> Redis.current.smembers('c')
=> ["1", "4"]
pry(main)> Redis.current.sinter('a','b')
=> ["1", "3"]
pry(main)> Redis.current.sinter('a','c')
=> ["1", "4"]
pry(main)> Redis.current.sinter('a','b','c')
=> ["1"]
pry(main)> Redis.current.sinter('a','b','yamadagenki')
=> []

SINTERSTORE(重複した要素の保存)

計算量:O(N*M) 基本的に1つずつ比較するので、最悪N*M
SDIFF(データの差分)SDIFFSTORE(データの差分を保存)の関係と同じ。
SINTER(重複した要素)の結果を新しいkeyに保存する。
keyが既に存在していた場合は、上書きされる。

戻り値

Integer: 共通となる要素リストに含まれる要素の個数

使用例

pry(main)> Redis.current.smembers('a')
=> ["1", "2", "3", "4", "5"]
pry(main)> Redis.current.smembers('b')
=> ["1", "3"]
pry(main)> Redis.current.smembers('c')
=> ["1", "4"]
pry(main)> Redis.current.sinterstore('ab', 'a','b')
=> 2
pry(main)> Redis.current.sinterstore('abc', 'a','b','c')
=> 1
pry(main)> Redis.current.smembers('ab')
=> ["1", "3"]
pry(main)> Redis.current.smembers('abc')
=> ["1"]

SISMEMBER(要素の存在確認)

計算量:O(1)
指定された要素が、指定されたkeyのvalueに含まれるかどうかを返す

戻り値

Integer:
含まれる場合→1(railsのラッパーを使った場合はtrue)
含まれない場合→0(railsのラッパーを使った場合はfalse)

使用例

pry(main)> Redis.current.smembers('a')
=> ["1", "2", "3", "4", "5"]
pry(main)> Redis.current.sismember('a', '2')
=> true
pry(main)> Redis.current.sismember('a', '6')
=> false

SMEMBERS(すべての要素抽出)

計算量:O(N) Nはkeyに含まれる要素数
指定されたkeyに含まれる要素

戻り値

Integer:
含まれる場合→1(railsのラッパーを使った場合はtrue)
含まれない場合→0(railsのラッパーを使った場合はfalse)

使用例

pry(main)> Redis.current.sadd('a', '1')
=> true
pry(main)> Redis.current.sadd('a', '2')
=> true
pry(main)> Redis.current.smembers('a')
=> ["1", "2"]

SPOP(1要素のランダム抽出・削除)

計算量:O(1)
指定されたkeyに含まれる1つないし、複数の要素を削除する。
(ドキュメント読む限り)LIFOではなく、ランダムな要素が削除される
SRANDMEMBER(要素のランダム抽出)とは違い、削除まで行う。

(railsのラッパーでは、一つずつしか取り出せない)

戻り値

STRING:要素がある場合は要素を、ない場合はnil

使用例

pry(main)> Redis.current.smembers('a')
=> ["1", "2", "3", "4"]
pry(main)> Redis.current.spop('a')
=> "2"
pry(main)> Redis.current.spop('a')
=> "3"
pry(main)> Redis.current.spop('a', 4)
ArgumentError: wrong number of arguments (2 for 1)
from /vagrant/www/job-medley/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis.rb:1270:in `spop'
pry(main)> Redis.current.spop('a')
=> "1"
pry(main)> Redis.current.spop('a')
=> "4"
pry(main)> Redis.current.spop('a')
=> nil

SRANDMEMBER(要素のランダム抽出)

計算量:O(N) 抽出する数
指定されたkeyに含まれる1つないし、複数の要素をランダムに抽出する。
正の数が指定されたら、重複なしの値が抽出される。
負の数が指定されたら、重複する値が抽出される。

(railsのラッパーでは、一つずつしか取り出せない)

戻り値

STRING:要素がある場合は要素を、ない場合はnil

使用例

pry(main)> Redis.current.smembers('a')
=> ["1", "2", "3", "4", "5"]
pry(main)> Redis.current.srandmember('a')
=> "2"
pry(main)> Redis.current.srandmember('a')
=> "5"
pry(main)> Redis.current.srandmember('a')
=> "1"
pry(main)> Redis.current.smembers('a')
=> ["1", "2", "3", "4", "5"]
pry(main)> Redis.current.srandmember('yamadagenki')
=> nil
pry(main)> Redis.current.srandmember('a', 5)
Redis::CommandError: ERR wrong number of arguments for 'srandmember' command
from /vagrant/www/job-medley/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/client.rb:113:in `call'

SREM(指定要素の削除)

計算量:O(N) 削除する数
keyに対する特定の要素を削除する。keyが存在しない場合、空の集合とみなし、0が返却される。
keyに保存されている値が集合出ない場合エラーを返す

(railsのラッパーでは、一つずつしか削除できない)

戻り値

INTEGER:削除された要素数を返す
(railsのラッパーを通すとtrue,falseで返る)

使用例

pry(main)> Redis.current.smembers('a')
=> ["1", "2", "3", "4", "5"]
pry(main)> Redis.current.srem('a', 1)
=> true
pry(main)> Redis.current.smembers('a')
=> ["2", "3", "4", "5"]
pry(main)> Redis.current.smembers('owata')
=> []
pry(main)> Redis.current.srem('owata', 1)
=> false
pry(main)> Redis.current.srem('a', '2', '3')
ArgumentError: wrong number of arguments (3 for 2)
from /vagrant/www/job-medley/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis.rb:1252:in `srem'

SUNION(指定要素の結合)

計算量:O(N) Nは与えられた数
与えられたkeyに対する要素を一意な形で結合する

keyが存在しない場合は空のデータとして扱われる

戻り値

Array:結合されたデータ

使用例

pry(main)> Redis.current.smembers('a')
=> ["2", "3", "4", "5"]
pry(main)> Redis.current.smembers('b')
=> ["1", "3", "4"]
pry(main)> Redis.current.smembers('c')
=> ["1", "4"]
pry(main)> Redis.current.sunion('a','b','c')
=> ["1", "2", "3", "4", "5"]

SUNIONSTORE(指定要素の結合保存)

計算量:O(N) Nは与えられた数
要素を一意な形で結合したものを、改なkeyに保存

keyが既に存在する場合は上書きする

戻り値

INTEGER:結合された要素の数

使用例

pry(main)> Redis.current.smembers('a')
=> ["2", "3", "4", "5"]
pry(main)> Redis.current.smembers('b')
=> ["1", "3", "4"]
pry(main)> Redis.current.smembers('c')
=> ["1", "4"]
pry(main)> Redis.current.sunionstore('abc', 'a','b','c')
=> 5
[128] pry(main)> Redis.current.smembers('abc')
=> ["1", "2", "3", "4", "5"]

SSCAN(keyをiterateする)

集合状のデータが保存されてるkeyに対し繰り返し処理を行う
railsのラッパー上では使えない(?)っぽい

備考

以上なにか間違い等ありましたら、ご指摘いただけたら幸いですm(_ _)m

20
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
17