Class: Redis

Inherits:
Object
  • Object
show all
Includes:
MonitorMixin
Defined in:
lib/redis.rb,
lib/redis/client.rb,
lib/redis/errors.rb,
lib/redis/cluster.rb,
lib/redis/version.rb,
lib/redis/pipeline.rb,
lib/redis/hash_ring.rb,
lib/redis/subscribe.rb,
lib/redis/distributed.rb,
lib/redis/cluster/node.rb,
lib/redis/cluster/slot.rb,
lib/redis/cluster/option.rb,
lib/redis/cluster/command.rb,
lib/redis/connection/ruby.rb,
lib/redis/cluster/node_key.rb,
lib/redis/connection/hiredis.rb,
lib/redis/cluster/node_loader.rb,
lib/redis/cluster/slot_loader.rb,
lib/redis/connection/registry.rb,
lib/redis/connection/synchrony.rb,
lib/redis/cluster/command_loader.rb,
lib/redis/connection/command_helper.rb,
lib/redis/cluster/key_slot_converter.rb

Defined Under Namespace

Modules: Connection Classes: BaseConnectionError, BaseError, CannotConnectError, Client, Cluster, CommandError, ConnectionError, Distributed, Future, FutureNotReady, HashRing, InheritedError, InvalidClientOptionError, Pipeline, ProtocolError, SubscribedClient, Subscription, TimeoutError

Constant Summary collapse

VERSION =
'4.3.0'

Class Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Redis

Create a new client instance

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :url (String) — default: value of the environment variable REDIS_URL

    a Redis URL, for a TCP connection: ‘redis://:@[hostname]:/[db]` (password, port and database are optional), for a unix socket

    connection: `unix://[path to Redis socket]`. This overrides all other options.
    
  • :host (String) — default: "127.0.0.1"

    server hostname

  • :port (Integer) — default: 6379

    server port

  • :path (String)

    path to server socket (overrides host and port)

  • :timeout (Float) — default: 5.0

    timeout in seconds

  • :connect_timeout (Float) — default: same as timeout

    timeout for initial connect in seconds

  • :username (String)

    Username to authenticate against server

  • :password (String)

    Password to authenticate against server

  • :db (Integer) — default: 0

    Database to select after initial connect

  • :driver (Symbol)

    Driver to use, currently supported: ‘:ruby`, `:hiredis`, `:synchrony`

  • :id (String)

    ID for the client connection, assigns name to current connection by sending ‘CLIENT SETNAME`

  • :tcp_keepalive (Hash, Integer)

    Keepalive values, if Integer ‘intvl` and `probe` are calculated based on the value, if Hash `time`, `intvl` and `probes` can be specified as a Integer

  • :reconnect_attempts (Integer)

    Number of attempts trying to connect

  • :inherit_socket (Boolean) — default: false

    Whether to use socket in forked process or not

  • :sentinels (Array)

    List of sentinels to contact

  • :role (Symbol) — default: :master

    Role to fetch via Sentinel, either ‘:master` or `:slave`

  • :cluster (Array<String, Hash{Symbol => String, Integer}>)

    List of cluster nodes to contact

  • :replica (Boolean)

    Whether to use readonly replica nodes in Redis Cluster or not

  • :connector (Class)

    Class of custom connector



59
60
61
62
63
64
65
66
67
# File 'lib/redis.rb', line 59

def initialize(options = {})
  @options = options.dup
  @cluster_mode = options.key?(:cluster)
  client = @cluster_mode ? Cluster : Client
  @original_client = @client = client.new(options)
  @queue = Hash.new { |h, k| h[k] = [] }

  super() # Monitor#initialize
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(command, *args) ⇒ Object

rubocop:disable Style/MissingRespondToMissing



3358
3359
3360
3361
3362
# File 'lib/redis.rb', line 3358

def method_missing(command, *args) # rubocop:disable Style/MissingRespondToMissing
  synchronize do |client|
    client.call([command] + args)
  end
end

Class Attribute Details

.currentObject



25
26
27
# File 'lib/redis.rb', line 25

def self.current
  @current ||= Redis.new
end

.exists_returns_integerObject

Returns the value of attribute exists_returns_integer.



8
9
10
# File 'lib/redis.rb', line 8

def exists_returns_integer
  @exists_returns_integer
end

Instance Method Details

#_bpop(cmd, args, &blk) ⇒ Object



1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
# File 'lib/redis.rb', line 1206

def _bpop(cmd, args, &blk)
  timeout = if args.last.is_a?(Hash)
    options = args.pop
    options[:timeout]
  elsif args.last.respond_to?(:to_int)
    # Issue deprecation notice in obnoxious mode...
    args.pop.to_int
  end

  timeout ||= 0

  if args.size > 1
    # Issue deprecation notice in obnoxious mode...
  end

  keys = args.flatten

  synchronize do |client|
    command = [cmd, keys, timeout]
    timeout += client.timeout if timeout > 0
    client.call_with_timeout(command, timeout, &blk)
  end
end

#_clientObject



141
142
143
# File 'lib/redis.rb', line 141

def _client
  @client
end

#_eval(cmd, args) ⇒ Object



2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
# File 'lib/redis.rb', line 2578

def _eval(cmd, args)
  script = args.shift
  options = args.pop if args.last.is_a?(Hash)
  options ||= {}

  keys = args.shift || options[:keys] || []
  argv = args.shift || options[:argv] || []

  synchronize do |client|
    client.call([cmd, script, keys.length] + keys + argv)
  end
end

#_exists(*keys) ⇒ Object



595
596
597
598
599
# File 'lib/redis.rb', line 595

def _exists(*keys)
  synchronize do |client|
    client.call([:exists, *keys])
  end
end

#_scan(command, cursor, args, match: nil, count: nil, type: nil, &block) ⇒ Object



2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
# File 'lib/redis.rb', line 2641

def _scan(command, cursor, args, match: nil, count: nil, type: nil, &block)
  # SSCAN/ZSCAN/HSCAN already prepend the key to +args+.

  args << cursor
  args << "MATCH" << match if match
  args << "COUNT" << count if count
  args << "TYPE" << type if type

  synchronize do |client|
    client.call([command] + args, &block)
  end
end

#append(key, value) ⇒ Integer

Append a value to a key.

Parameters:

  • key (String)
  • value (String)

    value to append

Returns:

  • (Integer)

    length of the string after appending



1049
1050
1051
1052
1053
# File 'lib/redis.rb', line 1049

def append(key, value)
  synchronize do |client|
    client.call([:append, key, value])
  end
end

#askingString

Sends ‘ASKING` command to random node and returns its reply.

Returns:

  • (String)

    ‘’OK’‘

See Also:



3330
3331
3332
# File 'lib/redis.rb', line 3330

def asking
  synchronize { |client| client.call(%i[asking]) }
end

#auth(*args) ⇒ String

Authenticate to the server.

Parameters:

  • args (Array<String>)

    includes both username and password or only password

Returns:

  • (String)

    ‘OK`

See Also:



151
152
153
154
155
# File 'lib/redis.rb', line 151

def auth(*args)
  synchronize do |client|
    client.call([:auth, *args])
  end
end

#bgrewriteaofString

Asynchronously rewrite the append-only file.

Returns:

  • (String)

    ‘OK`



205
206
207
208
209
# File 'lib/redis.rb', line 205

def bgrewriteaof
  synchronize do |client|
    client.call([:bgrewriteaof])
  end
end

#bgsaveString

Asynchronously save the dataset to disk.

Returns:

  • (String)

    ‘OK`



214
215
216
217
218
# File 'lib/redis.rb', line 214

def bgsave
  synchronize do |client|
    client.call([:bgsave])
  end
end

#bitcount(key, start = 0, stop = -1)) ⇒ Integer

Count the number of set bits in a range of the string value stored at key.

Parameters:

  • key (String)
  • start (Integer) (defaults to: 0)

    start index

  • stop (Integer) (defaults to: -1))

    stop index

Returns:

  • (Integer)

    the number of bits set to 1



1061
1062
1063
1064
1065
# File 'lib/redis.rb', line 1061

def bitcount(key, start = 0, stop = -1)
  synchronize do |client|
    client.call([:bitcount, key, start, stop])
  end
end

#bitop(operation, destkey, *keys) ⇒ Integer

Perform a bitwise operation between strings and store the resulting string in a key.

Parameters:

  • operation (String)

    e.g. ‘and`, `or`, `xor`, `not`

  • destkey (String)

    destination key

  • keys (String, Array<String>)

    one or more source keys to perform ‘operation`

Returns:

  • (Integer)

    the length of the string stored in ‘destkey`



1073
1074
1075
1076
1077
# File 'lib/redis.rb', line 1073

def bitop(operation, destkey, *keys)
  synchronize do |client|
    client.call([:bitop, operation, destkey, *keys])
  end
end

#bitpos(key, bit, start = nil, stop = nil) ⇒ Integer

Return the position of the first bit set to 1 or 0 in a string.

Parameters:

  • key (String)
  • bit (Integer)

    whether to look for the first 1 or 0 bit

  • start (Integer) (defaults to: nil)

    start index

  • stop (Integer) (defaults to: nil)

    stop index

Returns:

  • (Integer)

    the position of the first 1/0 bit. -1 if looking for 1 and it is not found or start and stop are given.

Raises:

  • (ArgumentError)


1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
# File 'lib/redis.rb', line 1087

def bitpos(key, bit, start = nil, stop = nil)
  raise(ArgumentError, 'stop parameter specified without start parameter') if stop && !start

  synchronize do |client|
    command = [:bitpos, key, bit]
    command << start if start
    command << stop if stop
    client.call(command)
  end
end

#blpop(*args) ⇒ nil, [String, String]

Remove and get the first element in a list, or block until one is available.

Examples:

With timeout

list, element = redis.blpop("list", :timeout => 5)
  # => nil on timeout
  # => ["list", "element"] on success

Without timeout

list, element = redis.blpop("list")
  # => ["list", "element"]

Blocking pop on multiple lists

list, element = redis.blpop(["list", "another_list"])
  # => ["list", "element"]

Parameters:

  • keys (String, Array<String>)

    one or more keys to perform the blocking pop on

  • options (Hash)
    • ‘:timeout => Integer`: timeout in seconds, defaults to no timeout

Returns:

  • (nil, [String, String])
    • ‘nil` when the operation timed out

    • tuple of the list that was popped from and element was popped otherwise



1251
1252
1253
# File 'lib/redis.rb', line 1251

def blpop(*args)
  _bpop(:blpop, args)
end

#brpop(*args) ⇒ nil, [String, String]

Remove and get the last element in a list, or block until one is available.

Parameters:

  • keys (String, Array<String>)

    one or more keys to perform the blocking pop on

  • options (Hash)
    • ‘:timeout => Integer`: timeout in seconds, defaults to no timeout

Returns:

  • (nil, [String, String])
    • ‘nil` when the operation timed out

    • tuple of the list that was popped from and element was popped otherwise

See Also:



1267
1268
1269
# File 'lib/redis.rb', line 1267

def brpop(*args)
  _bpop(:brpop, args)
end

#brpoplpush(source, destination, deprecated_timeout = 0, timeout: deprecated_timeout) ⇒ nil, String

Pop a value from a list, push it to another list and return it; or block until one is available.

Parameters:

  • source (String)

    source key

  • destination (String)

    destination key

  • options (Hash)
    • ‘:timeout => Integer`: timeout in seconds, defaults to no timeout

Returns:

  • (nil, String)
    • ‘nil` when the operation timed out

    • the element was popped and pushed otherwise



1282
1283
1284
1285
1286
1287
1288
# File 'lib/redis.rb', line 1282

def brpoplpush(source, destination, deprecated_timeout = 0, timeout: deprecated_timeout)
  synchronize do |client|
    command = [:brpoplpush, source, destination, timeout]
    timeout += client.timeout if timeout > 0
    client.call_with_timeout(command, timeout)
  end
end

#bzpopmax(*args) ⇒ Array<String, String, Float>?

Removes and returns up to count members with the highest scores in the sorted set stored at keys,

or block until one is available.

Examples:

Popping a member from a sorted set

redis.bzpopmax('zset', 1)
#=> ['zset', 'b', 2.0]

Popping a member from multiple sorted sets

redis.bzpopmax('zset1', 'zset2', 1)
#=> ['zset1', 'b', 2.0]

Returns:

  • (Array<String, String, Float>)

    a touple of key, member and score

  • (nil)

    when no element could be popped and the timeout expired



1715
1716
1717
1718
1719
# File 'lib/redis.rb', line 1715

def bzpopmax(*args)
  _bpop(:bzpopmax, args) do |reply|
    reply.is_a?(Array) ? [reply[0], reply[1], Floatify.call(reply[2])] : reply
  end
end

#bzpopmin(*args) ⇒ Array<String, String, Float>?

Removes and returns up to count members with the lowest scores in the sorted set stored at keys,

or block until one is available.

Examples:

Popping a member from a sorted set

redis.bzpopmin('zset', 1)
#=> ['zset', 'a', 1.0]

Popping a member from multiple sorted sets

redis.bzpopmin('zset1', 'zset2', 1)
#=> ['zset1', 'a', 1.0]

Returns:

  • (Array<String, String, Float>)

    a touple of key, member and score

  • (nil)

    when no element could be popped and the timeout expired



1736
1737
1738
1739
1740
# File 'lib/redis.rb', line 1736

def bzpopmin(*args)
  _bpop(:bzpopmin, args) do |reply|
    reply.is_a?(Array) ? [reply[0], reply[1], Floatify.call(reply[2])] : reply
  end
end

#call(*command) ⇒ Object

Sends a command to Redis and returns its reply.

Replies are converted to Ruby objects according to the RESP protocol, so you can expect a Ruby array, integer or nil when Redis sends one. Higher level transformations, such as converting an array of pairs into a Ruby hash, are up to consumers.

Redis error replies are raised as Ruby exceptions.



104
105
106
107
108
# File 'lib/redis.rb', line 104

def call(*command)
  synchronize do |client|
    client.call(command)
  end
end

#client(subcommand = nil, *args) ⇒ String, Hash

Manage client connections.

Parameters:

  • subcommand (String, Symbol) (defaults to: nil)

    e.g. ‘kill`, `list`, `getname`, `setname`

Returns:

  • (String, Hash)

    depends on subcommand



241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/redis.rb', line 241

def client(subcommand = nil, *args)
  synchronize do |client|
    client.call([:client, subcommand] + args) do |reply|
      if subcommand.to_s == "list"
        reply.lines.map do |line|
          entries = line.chomp.split(/[ =]/)
          Hash[entries.each_slice(2).to_a]
        end
      else
        reply
      end
    end
  end
end

#closeObject Also known as: disconnect!

Disconnect the client as quickly and silently as possible.



91
92
93
# File 'lib/redis.rb', line 91

def close
  @original_client.disconnect
end

#cluster(subcommand, *args) ⇒ Object

Sends ‘CLUSTER *` command to random node and returns its reply.

Parameters:

  • subcommand (String, Symbol)

    the subcommand of cluster command e.g. ‘:slots`, `:nodes`, `:slaves`, `:info`

Returns:

  • (Object)

    depends on the subcommand

See Also:



3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
# File 'lib/redis.rb', line 3302

def cluster(subcommand, *args)
  subcommand = subcommand.to_s.downcase
  block = case subcommand
  when 'slots'
    HashifyClusterSlots
  when 'nodes'
    HashifyClusterNodes
  when 'slaves'
    HashifyClusterSlaves
  when 'info'
    HashifyInfo
  else
    Noop
  end

  # @see https://github.com/antirez/redis/blob/unstable/src/redis-trib.rb#L127 raw reply expected
  block = Noop unless @cluster_mode

  synchronize do |client|
    client.call([:cluster, subcommand] + args, &block)
  end
end

#commitObject

Sends all commands in the queue.

See redis.io/topics/pipelining for more details.



126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/redis.rb', line 126

def commit
  synchronize do |client|
    begin
      pipeline = Pipeline.new(client)
      @queue[Thread.current.object_id].each do |command|
        pipeline.call(command)
      end

      client.call_pipelined(pipeline)
    ensure
      @queue.delete(Thread.current.object_id)
    end
  end
end

#config(action, *args) ⇒ String, Hash

Get or set server configuration parameters.

Parameters:

  • action (Symbol)

    e.g. ‘:get`, `:set`, `:resetstat`

Returns:

  • (String, Hash)

    string reply, or hash when retrieving more than one property with ‘CONFIG GET`



225
226
227
228
229
230
231
232
233
234
235
# File 'lib/redis.rb', line 225

def config(action, *args)
  synchronize do |client|
    client.call([:config, action] + args) do |reply|
      if reply.is_a?(Array) && action == :get
        Hashify.call(reply)
      else
        reply
      end
    end
  end
end

#connected?Boolean

Test whether or not the client is connected

Returns:

  • (Boolean)


86
87
88
# File 'lib/redis.rb', line 86

def connected?
  @original_client.connected?
end

#connectionObject



3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
# File 'lib/redis.rb', line 3346

def connection
  return @original_client.connection_info if @cluster_mode

  {
    host: @original_client.host,
    port: @original_client.port,
    db: @original_client.db,
    id: @original_client.id,
    location: @original_client.location
  }
end

#dbsizeInteger

Return the number of keys in the selected database.

Returns:

  • (Integer)


259
260
261
262
263
# File 'lib/redis.rb', line 259

def dbsize
  synchronize do |client|
    client.call([:dbsize])
  end
end

#debug(*args) ⇒ Object



265
266
267
268
269
# File 'lib/redis.rb', line 265

def debug(*args)
  synchronize do |client|
    client.call([:debug] + args)
  end
end

#decr(key) ⇒ Integer

Decrement the integer value of a key by one.

Examples:

redis.decr("value")
  # => 4

Parameters:

  • key (String)

Returns:

  • (Integer)

    value after decrementing it



762
763
764
765
766
# File 'lib/redis.rb', line 762

def decr(key)
  synchronize do |client|
    client.call([:decr, key])
  end
end

#decrby(key, decrement) ⇒ Integer

Decrement the integer value of a key by the given number.

Examples:

redis.decrby("value", 5)
  # => 0

Parameters:

  • key (String)
  • decrement (Integer)

Returns:

  • (Integer)

    value after decrementing it



777
778
779
780
781
# File 'lib/redis.rb', line 777

def decrby(key, decrement)
  synchronize do |client|
    client.call([:decrby, key, decrement])
  end
end

#del(*keys) ⇒ Integer

Delete one or more keys.

Parameters:

  • keys (String, Array<String>)

Returns:

  • (Integer)

    number of keys that were deleted



557
558
559
560
561
# File 'lib/redis.rb', line 557

def del(*keys)
  synchronize do |client|
    client.call([:del] + keys)
  end
end

#discardString

Discard all commands issued after MULTI.

Only call this method when ‘#multi` was called without a block.

Returns:

  • (String)

    ‘“OK”`

See Also:



2524
2525
2526
2527
2528
# File 'lib/redis.rb', line 2524

def discard
  synchronize do |client|
    client.call([:discard])
  end
end

#dump(key) ⇒ String

Return a serialized version of the value stored at a key.

Parameters:

  • key (String)

Returns:

  • (String)

    serialized_value



504
505
506
507
508
# File 'lib/redis.rb', line 504

def dump(key)
  synchronize do |client|
    client.call([:dump, key])
  end
end

#dupObject



3342
3343
3344
# File 'lib/redis.rb', line 3342

def dup
  self.class.new(@options)
end

#echo(value) ⇒ String

Echo the given string.

Parameters:

  • value (String)

Returns:

  • (String)


182
183
184
185
186
# File 'lib/redis.rb', line 182

def echo(value)
  synchronize do |client|
    client.call([:echo, value])
  end
end

#eval(*args) ⇒ Object

Evaluate Lua script.

Examples:

EVAL without KEYS nor ARGV

redis.eval("return 1")
  # => 1

EVAL with KEYS and ARGV as array arguments

redis.eval("return { KEYS, ARGV }", ["k1", "k2"], ["a1", "a2"])
  # => [["k1", "k2"], ["a1", "a2"]]

EVAL with KEYS and ARGV in a hash argument

redis.eval("return { KEYS, ARGV }", :keys => ["k1", "k2"], :argv => ["a1", "a2"])
  # => [["k1", "k2"], ["a1", "a2"]]

Parameters:

  • keys (Array<String>)

    optional array with keys to pass to the script

  • argv (Array<String>)

    optional array with arguments to pass to the script

  • options (Hash)
    • ‘:keys => Array<String>`: optional array with keys to pass to the script

    • ‘:argv => Array<String>`: optional array with arguments to pass to the script

Returns:

  • depends on the script

See Also:



2612
2613
2614
# File 'lib/redis.rb', line 2612

def eval(*args)
  _eval(:eval, args)
end

#evalsha(*args) ⇒ Object

Evaluate Lua script by its SHA.

Examples:

EVALSHA without KEYS nor ARGV

redis.evalsha(sha)
  # => <depends on script>

EVALSHA with KEYS and ARGV as array arguments

redis.evalsha(sha, ["k1", "k2"], ["a1", "a2"])
  # => <depends on script>

EVALSHA with KEYS and ARGV in a hash argument

redis.evalsha(sha, :keys => ["k1", "k2"], :argv => ["a1", "a2"])
  # => <depends on script>

Parameters:

  • keys (Array<String>)

    optional array with keys to pass to the script

  • argv (Array<String>)

    optional array with arguments to pass to the script

  • options (Hash)
    • ‘:keys => Array<String>`: optional array with keys to pass to the script

    • ‘:argv => Array<String>`: optional array with arguments to pass to the script

Returns:

  • depends on the script

See Also:



2637
2638
2639
# File 'lib/redis.rb', line 2637

def evalsha(*args)
  _eval(:evalsha, args)
end

#execnil, Array<...>

Execute all commands issued after MULTI.

Only call this method when ‘#multi` was called without a block.

Returns:

  • (nil, Array<...>)
    • when commands were not executed, ‘nil`

    • when commands were executed, an array with their replies

See Also:



2510
2511
2512
2513
2514
# File 'lib/redis.rb', line 2510

def exec
  synchronize do |client|
    client.call([:exec])
  end
end

#exists(*keys) ⇒ Integer

Determine how many of the keys exists.

Parameters:

  • keys (String, Array<String>)

Returns:

  • (Integer)


577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
# File 'lib/redis.rb', line 577

def exists(*keys)
  if !Redis.exists_returns_integer && keys.size == 1
    if Redis.exists_returns_integer.nil?
      message = "`Redis#exists(key)` will return an Integer in redis-rb 4.3. `exists?` returns a boolean, you " \
        "should use it instead. To opt-in to the new behavior now you can set Redis.exists_returns_integer =  " \
        "true. To disable this message and keep the current (boolean) behaviour of 'exists' you can set " \
        "`Redis.exists_returns_integer = false`, but this option will be removed in 5.0. " \
        "(#{::Kernel.caller(1, 1).first})\n"

      ::Kernel.warn(message)
    end

    exists?(*keys)
  else
    _exists(*keys)
  end
end

#exists?(*keys) ⇒ Boolean

Determine if any of the keys exists.

Parameters:

  • keys (String, Array<String>)

Returns:

  • (Boolean)


605
606
607
608
609
610
611
# File 'lib/redis.rb', line 605

def exists?(*keys)
  synchronize do |client|
    client.call([:exists, *keys]) do |value|
      value > 0
    end
  end
end

#expire(key, seconds) ⇒ Boolean

Set a key’s time to live in seconds.

Parameters:

  • key (String)
  • seconds (Integer)

    time to live

Returns:

  • (Boolean)

    whether the timeout was set or not



426
427
428
429
430
# File 'lib/redis.rb', line 426

def expire(key, seconds)
  synchronize do |client|
    client.call([:expire, key, seconds], &Boolify)
  end
end

#expireat(key, unix_time) ⇒ Boolean

Set the expiration for a key as a UNIX timestamp.

Parameters:

  • key (String)
  • unix_time (Integer)

    expiry time specified as a UNIX timestamp

Returns:

  • (Boolean)

    whether the timeout was set or not



437
438
439
440
441
# File 'lib/redis.rb', line 437

def expireat(key, unix_time)
  synchronize do |client|
    client.call([:expireat, key, unix_time], &Boolify)
  end
end

#flushall(options = nil) ⇒ String

Remove all keys from all databases.

Parameters:

  • options (Hash) (defaults to: nil)
    • ‘:async => Boolean`: async flush (default: false)

Returns:

  • (String)

    ‘OK`



276
277
278
279
280
281
282
283
284
# File 'lib/redis.rb', line 276

def flushall(options = nil)
  synchronize do |client|
    if options && options[:async]
      client.call(%i[flushall async])
    else
      client.call([:flushall])
    end
  end
end

#flushdb(options = nil) ⇒ String

Remove all keys from the current database.

Parameters:

  • options (Hash) (defaults to: nil)
    • ‘:async => Boolean`: async flush (default: false)

Returns:

  • (String)

    ‘OK`



291
292
293
294
295
296
297
298
299
# File 'lib/redis.rb', line 291

def flushdb(options = nil)
  synchronize do |client|
    if options && options[:async]
      client.call(%i[flushdb async])
    else
      client.call([:flushdb])
    end
  end
end

#geoadd(key, *member) ⇒ Integer

Adds the specified geospatial items (latitude, longitude, name) to the specified key

Parameters:

  • key (String)
  • member (Array)

    arguemnts for member or members: longitude, latitude, name

Returns:

  • (Integer)

    number of elements added to the sorted set



2865
2866
2867
2868
2869
# File 'lib/redis.rb', line 2865

def geoadd(key, *member)
  synchronize do |client|
    client.call([:geoadd, key, *member])
  end
end

#geodist(key, member1, member2, unit = 'm') ⇒ String?

Returns the distance between two members of a geospatial index

Parameters:

  • key (String)
  • members (Array<String>)
  • unit ('m', 'km', 'mi', 'ft') (defaults to: 'm')

Returns:

  • (String, nil)

    returns distance in spefied unit if both members present, nil otherwise.



2936
2937
2938
2939
2940
# File 'lib/redis.rb', line 2936

def geodist(key, member1, member2, unit = 'm')
  synchronize do |client|
    client.call([:geodist, key, member1, member2, unit])
  end
end

#geohash(key, member) ⇒ Array<String, nil>

Returns geohash string representing position for specified members of the specified key.

Parameters:

  • key (String)
  • member (String, Array<String>)

    one member or array of members

Returns:

  • (Array<String, nil>)

    returns array containg geohash string if member is present, nil otherwise



2876
2877
2878
2879
2880
# File 'lib/redis.rb', line 2876

def geohash(key, member)
  synchronize do |client|
    client.call([:geohash, key, member])
  end
end

#geopos(key, member) ⇒ Array<Array<String>, nil>

Returns longitude and latitude of members of a geospatial index

Parameters:

  • key (String)
  • member (String, Array<String>)

    one member or array of members

Returns:

  • (Array<Array<String>, nil>)

    returns array of elements, where each element is either array of longitude and latitude or nil



2924
2925
2926
2927
2928
# File 'lib/redis.rb', line 2924

def geopos(key, member)
  synchronize do |client|
    client.call([:geopos, key, member])
  end
end

#georadius(*args, **geoptions) ⇒ Array<String>

Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from a point

Parameters:

  • args (Array)

    key, longitude, latitude, radius, unit(m|km|ft|mi)

  • sort ('asc', 'desc')

    sort returned items from the nearest to the farthest or the farthest to the nearest relative to the center

  • count (Integer)

    limit the results to the first N matching items

  • options ('WITHDIST', 'WITHCOORD', 'WITHHASH')

    to return additional information

Returns:

  • (Array<String>)

    may be changed with ‘options`



2892
2893
2894
2895
2896
2897
2898
# File 'lib/redis.rb', line 2892

def georadius(*args, **geoptions)
  geoarguments = _geoarguments(*args, **geoptions)

  synchronize do |client|
    client.call([:georadius, *geoarguments])
  end
end

#georadiusbymember(*args, **geoptions) ⇒ Array<String>

Query a sorted set representing a geospatial index to fetch members matching a given maximum distance from an already existing member

Parameters:

  • args (Array)

    key, member, radius, unit(m|km|ft|mi)

  • sort ('asc', 'desc')

    sort returned items from the nearest to the farthest or the farthest to the nearest relative to the center

  • count (Integer)

    limit the results to the first N matching items

  • options ('WITHDIST', 'WITHCOORD', 'WITHHASH')

    to return additional information

Returns:

  • (Array<String>)

    may be changed with ‘options`



2910
2911
2912
2913
2914
2915
2916
# File 'lib/redis.rb', line 2910

def georadiusbymember(*args, **geoptions)
  geoarguments = _geoarguments(*args, **geoptions)

  synchronize do |client|
    client.call([:georadiusbymember, *geoarguments])
  end
end

#get(key) ⇒ String

Get the value of a key.

Parameters:

  • key (String)

Returns:

  • (String)


954
955
956
957
958
# File 'lib/redis.rb', line 954

def get(key)
  synchronize do |client|
    client.call([:get, key])
  end
end

#getbit(key, offset) ⇒ Integer

Returns the bit value at offset in the string value stored at key.

Parameters:

  • key (String)
  • offset (Integer)

    bit offset

Returns:

  • (Integer)

    ‘0` or `1`



1038
1039
1040
1041
1042
# File 'lib/redis.rb', line 1038

def getbit(key, offset)
  synchronize do |client|
    client.call([:getbit, key, offset])
  end
end

#getrange(key, start, stop) ⇒ Integer

Get a substring of the string stored at a key.

Parameters:

  • key (String)
  • start (Integer)

    zero-based start offset

  • stop (Integer)

    zero-based end offset. Use -1 for representing the end of the string

Returns:

  • (Integer)

    ‘0` or `1`



1015
1016
1017
1018
1019
# File 'lib/redis.rb', line 1015

def getrange(key, start, stop)
  synchronize do |client|
    client.call([:getrange, key, start, stop])
  end
end

#getset(key, value) ⇒ String

Set the string value of a key and return its old value.

Parameters:

  • key (String)
  • value (String)

    value to replace the current value with

Returns:

  • (String)

    the old value stored in the key, or ‘nil` if the key did not exist



1104
1105
1106
1107
1108
# File 'lib/redis.rb', line 1104

def getset(key, value)
  synchronize do |client|
    client.call([:getset, key, value.to_s])
  end
end

#hdel(key, *fields) ⇒ Integer

Delete one or more hash fields.

Parameters:

  • key (String)
  • field (String, Array<String>)

Returns:

  • (Integer)

    the number of fields that were removed from the hash



2241
2242
2243
2244
2245
# File 'lib/redis.rb', line 2241

def hdel(key, *fields)
  synchronize do |client|
    client.call([:hdel, key, *fields])
  end
end

#hexists(key, field) ⇒ Boolean

Determine if a hash field exists.

Parameters:

  • key (String)
  • field (String)

Returns:

  • (Boolean)

    whether or not the field exists in the hash



2252
2253
2254
2255
2256
# File 'lib/redis.rb', line 2252

def hexists(key, field)
  synchronize do |client|
    client.call([:hexists, key, field], &Boolify)
  end
end

#hget(key, field) ⇒ String

Get the value of a hash field.

Parameters:

  • key (String)
  • field (String)

Returns:

  • (String)


2192
2193
2194
2195
2196
# File 'lib/redis.rb', line 2192

def hget(key, field)
  synchronize do |client|
    client.call([:hget, key, field])
  end
end

#hgetall(key) ⇒ Hash<String, String>

Get all the fields and values in a hash.

Parameters:

  • key (String)

Returns:

  • (Hash<String, String>)


2306
2307
2308
2309
2310
# File 'lib/redis.rb', line 2306

def hgetall(key)
  synchronize do |client|
    client.call([:hgetall, key], &Hashify)
  end
end

#hincrby(key, field, increment) ⇒ Integer

Increment the integer value of a hash field by the given integer number.

Parameters:

  • key (String)
  • field (String)
  • increment (Integer)

Returns:

  • (Integer)

    value of the field after incrementing it



2264
2265
2266
2267
2268
# File 'lib/redis.rb', line 2264

def hincrby(key, field, increment)
  synchronize do |client|
    client.call([:hincrby, key, field, increment])
  end
end

#hincrbyfloat(key, field, increment) ⇒ Float

Increment the numeric value of a hash field by the given float number.

Parameters:

  • key (String)
  • field (String)
  • increment (Float)

Returns:

  • (Float)

    value of the field after incrementing it



2276
2277
2278
2279
2280
# File 'lib/redis.rb', line 2276

def hincrbyfloat(key, field, increment)
  synchronize do |client|
    client.call([:hincrbyfloat, key, field, increment], &Floatify)
  end
end

#hkeys(key) ⇒ Array<String>

Get all the fields in a hash.

Parameters:

  • key (String)

Returns:

  • (Array<String>)


2286
2287
2288
2289
2290
# File 'lib/redis.rb', line 2286

def hkeys(key)
  synchronize do |client|
    client.call([:hkeys, key])
  end
end

#hlen(key) ⇒ Integer

Get the number of fields in a hash.

Parameters:

  • key (String)

Returns:

  • (Integer)

    number of fields in the hash



2120
2121
2122
2123
2124
# File 'lib/redis.rb', line 2120

def hlen(key)
  synchronize do |client|
    client.call([:hlen, key])
  end
end

#hmget(key, *fields, &blk) ⇒ Array<String>

Get the values of all the given hash fields.

Examples:

redis.hmget("hash", "f1", "f2")
  # => ["v1", "v2"]

Parameters:

  • key (String)
  • fields (Array<String>)

    array of fields

Returns:

  • (Array<String>)

    an array of values for the specified fields

See Also:



2209
2210
2211
2212
2213
# File 'lib/redis.rb', line 2209

def hmget(key, *fields, &blk)
  synchronize do |client|
    client.call([:hmget, key] + fields, &blk)
  end
end

#hmset(key, *attrs) ⇒ String

Set one or more hash values.

Examples:

redis.hmset("hash", "f1", "v1", "f2", "v2")
  # => "OK"

Parameters:

  • key (String)
  • attrs (Array<String>)

    array of fields and values

Returns:

  • (String)

    ‘“OK”`

See Also:



2166
2167
2168
2169
2170
# File 'lib/redis.rb', line 2166

def hmset(key, *attrs)
  synchronize do |client|
    client.call([:hmset, key] + attrs)
  end
end

#hscan(key, cursor, **options) ⇒ String, Array<[String, String]>

Scan a hash

Examples:

Retrieve the first batch of key/value pairs in a hash

redis.hscan("hash", 0)

Parameters:

  • cursor (String, Integer)

    the cursor of the iteration

  • options (Hash)
    • ‘:match => String`: only return keys matching the pattern

    • ‘:count => Integer`: return count keys at most per iteration

Returns:

  • (String, Array<[String, String]>)

    the next cursor and all found keys



2719
2720
2721
2722
2723
# File 'lib/redis.rb', line 2719

def hscan(key, cursor, **options)
  _scan(:hscan, cursor, [key], **options) do |reply|
    [reply[0], reply[1].each_slice(2).to_a]
  end
end

#hscan_each(key, **options, &block) ⇒ Enumerator

Scan a hash

Examples:

Retrieve all of the key/value pairs in a hash

redis.hscan_each("hash").to_a
# => [["key70", "70"], ["key80", "80"]]

Parameters:

  • options (Hash)
    • ‘:match => String`: only return keys matching the pattern

    • ‘:count => Integer`: return count keys at most per iteration

Returns:

  • (Enumerator)

    an enumerator for all found keys



2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
# File 'lib/redis.rb', line 2736

def hscan_each(key, **options, &block)
  return to_enum(:hscan_each, key, **options) unless block_given?

  cursor = 0
  loop do
    cursor, values = hscan(key, cursor, **options)
    values.each(&block)
    break if cursor == "0"
  end
end

#hset(key, *attrs) ⇒ Integer

Set one or more hash values.

Examples:

redis.hset("hash", "f1", "v1", "f2", "v2") # => 2
redis.hset("hash", { "f1" => "v1", "f2" => "v2" }) # => 2

Parameters:

  • key (String)
  • attrs (Array<String> | Hash<String, String>)

    array or hash of fields and values

Returns:

  • (Integer)

    The number of fields that were added to the hash



2135
2136
2137
2138
2139
2140
2141
# File 'lib/redis.rb', line 2135

def hset(key, *attrs)
  attrs = attrs.first.flatten if attrs.size == 1 && attrs.first.is_a?(Hash)

  synchronize do |client|
    client.call([:hset, key, *attrs])
  end
end

#hsetnx(key, field, value) ⇒ Boolean

Set the value of a hash field, only if the field does not exist.

Parameters:

  • key (String)
  • field (String)
  • value (String)

Returns:

  • (Boolean)

    whether or not the field was added to the hash



2149
2150
2151
2152
2153
# File 'lib/redis.rb', line 2149

def hsetnx(key, field, value)
  synchronize do |client|
    client.call([:hsetnx, key, field, value], &Boolify)
  end
end

#hvals(key) ⇒ Array<String>

Get all the values in a hash.

Parameters:

  • key (String)

Returns:

  • (Array<String>)


2296
2297
2298
2299
2300
# File 'lib/redis.rb', line 2296

def hvals(key)
  synchronize do |client|
    client.call([:hvals, key])
  end
end

#idObject



3334
3335
3336
# File 'lib/redis.rb', line 3334

def id
  @original_client.id
end

#incr(key) ⇒ Integer

Increment the integer value of a key by one.

Examples:

redis.incr("value")
  # => 6

Parameters:

  • key (String)

Returns:

  • (Integer)

    value after incrementing it



791
792
793
794
795
# File 'lib/redis.rb', line 791

def incr(key)
  synchronize do |client|
    client.call([:incr, key])
  end
end

#incrby(key, increment) ⇒ Integer

Increment the integer value of a key by the given integer number.

Examples:

redis.incrby("value", 5)
  # => 10

Parameters:

  • key (String)
  • increment (Integer)

Returns:

  • (Integer)

    value after incrementing it



806
807
808
809
810
# File 'lib/redis.rb', line 806

def incrby(key, increment)
  synchronize do |client|
    client.call([:incrby, key, increment])
  end
end

#incrbyfloat(key, increment) ⇒ Float

Increment the numeric value of a key by the given float number.

Examples:

redis.incrbyfloat("value", 1.23)
  # => 1.23

Parameters:

  • key (String)
  • increment (Float)

Returns:

  • (Float)

    value after incrementing it



821
822
823
824
825
# File 'lib/redis.rb', line 821

def incrbyfloat(key, increment)
  synchronize do |client|
    client.call([:incrbyfloat, key, increment], &Floatify)
  end
end

#info(cmd = nil) ⇒ Hash<String, String>

Get information and statistics about the server.

Parameters:

  • cmd (String, Symbol) (defaults to: nil)

    e.g. “commandstats”

Returns:

  • (Hash<String, String>)


305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/redis.rb', line 305

def info(cmd = nil)
  synchronize do |client|
    client.call([:info, cmd].compact) do |reply|
      if reply.is_a?(String)
        reply = HashifyInfo.call(reply)

        if cmd && cmd.to_s == "commandstats"
          # Extract nested hashes for INFO COMMANDSTATS
          reply = Hash[reply.map do |k, v|
            v = v.split(",").map { |e| e.split("=") }
            [k[/^cmdstat_(.*)$/, 1], Hash[v]]
          end]
        end
      end

      reply
    end
  end
end

#inspectObject



3338
3339
3340
# File 'lib/redis.rb', line 3338

def inspect
  "#<Redis client v#{Redis::VERSION} for #{id}>"
end

#keys(pattern = "*") ⇒ Array<String>

Find all keys matching the given pattern.

Parameters:

  • pattern (String) (defaults to: "*")

Returns:

  • (Array<String>)


617
618
619
620
621
622
623
624
625
626
627
# File 'lib/redis.rb', line 617

def keys(pattern = "*")
  synchronize do |client|
    client.call([:keys, pattern]) do |reply|
      if reply.is_a?(String)
        reply.split(" ")
      else
        reply
      end
    end
  end
end

#lastsaveInteger

Get the UNIX time stamp of the last successful save to disk.

Returns:

  • (Integer)


328
329
330
331
332
# File 'lib/redis.rb', line 328

def lastsave
  synchronize do |client|
    client.call([:lastsave])
  end
end

#lindex(key, index) ⇒ String

Get an element from a list by its index.

Parameters:

  • key (String)
  • index (Integer)

Returns:

  • (String)


1295
1296
1297
1298
1299
# File 'lib/redis.rb', line 1295

def lindex(key, index)
  synchronize do |client|
    client.call([:lindex, key, index])
  end
end

#linsert(key, where, pivot, value) ⇒ Integer

Insert an element before or after another element in a list.

Parameters:

  • key (String)
  • where (String, Symbol)

    ‘BEFORE` or `AFTER`

  • pivot (String)

    reference element

  • value (String)

Returns:

  • (Integer)

    length of the list after the insert operation, or ‘-1` when the element `pivot` was not found



1309
1310
1311
1312
1313
# File 'lib/redis.rb', line 1309

def linsert(key, where, pivot, value)
  synchronize do |client|
    client.call([:linsert, key, where, pivot, value])
  end
end

#llen(key) ⇒ Integer

Get the length of a list.

Parameters:

  • key (String)

Returns:

  • (Integer)


1125
1126
1127
1128
1129
# File 'lib/redis.rb', line 1125

def llen(key)
  synchronize do |client|
    client.call([:llen, key])
  end
end

#lpop(key) ⇒ String

Remove and get the first element in a list.

Parameters:

  • key (String)

Returns:

  • (String)


1179
1180
1181
1182
1183
# File 'lib/redis.rb', line 1179

def lpop(key)
  synchronize do |client|
    client.call([:lpop, key])
  end
end

#lpush(key, value) ⇒ Integer

Prepend one or more values to a list, creating the list if it doesn’t exist

Parameters:

  • key (String)
  • value (String, Array<String>)

    string value, or array of string values to push

Returns:

  • (Integer)

    the length of the list after the push operation



1136
1137
1138
1139
1140
# File 'lib/redis.rb', line 1136

def lpush(key, value)
  synchronize do |client|
    client.call([:lpush, key, value])
  end
end

#lpushx(key, value) ⇒ Integer

Prepend a value to a list, only if the list exists.

Parameters:

  • key (String)
  • value (String)

Returns:

  • (Integer)

    the length of the list after the push operation



1147
1148
1149
1150
1151
# File 'lib/redis.rb', line 1147

def lpushx(key, value)
  synchronize do |client|
    client.call([:lpushx, key, value])
  end
end

#lrange(key, start, stop) ⇒ Array<String>

Get a range of elements from a list.

Parameters:

  • key (String)
  • start (Integer)

    start index

  • stop (Integer)

    stop index

Returns:

  • (Array<String>)


1321
1322
1323
1324
1325
# File 'lib/redis.rb', line 1321

def lrange(key, start, stop)
  synchronize do |client|
    client.call([:lrange, key, start, stop])
  end
end

#lrem(key, count, value) ⇒ Integer

Remove elements from a list.

Parameters:

  • key (String)
  • count (Integer)

    number of elements to remove. Use a positive value to remove the first ‘count` occurrences of `value`. A negative value to remove the last `count` occurrences of `value`. Or zero, to remove all occurrences of `value` from the list.

  • value (String)

Returns:

  • (Integer)

    the number of removed elements



1336
1337
1338
1339
1340
# File 'lib/redis.rb', line 1336

def lrem(key, count, value)
  synchronize do |client|
    client.call([:lrem, key, count, value])
  end
end

#lset(key, index, value) ⇒ String

Set the value of an element in a list by its index.

Parameters:

  • key (String)
  • index (Integer)
  • value (String)

Returns:

  • (String)

    ‘OK`



1348
1349
1350
1351
1352
# File 'lib/redis.rb', line 1348

def lset(key, index, value)
  synchronize do |client|
    client.call([:lset, key, index, value])
  end
end

#ltrim(key, start, stop) ⇒ String

Trim a list to the specified range.

Parameters:

  • key (String)
  • start (Integer)

    start index

  • stop (Integer)

    stop index

Returns:

  • (String)

    ‘OK`



1360
1361
1362
1363
1364
# File 'lib/redis.rb', line 1360

def ltrim(key, start, stop)
  synchronize do |client|
    client.call([:ltrim, key, start, stop])
  end
end

#mapped_hmget(key, *fields) ⇒ Hash

Get the values of all the given hash fields.

Examples:

redis.mapped_hmget("hash", "f1", "f2")
  # => { "f1" => "v1", "f2" => "v2" }

Parameters:

  • key (String)
  • fields (Array<String>)

    array of fields

Returns:

  • (Hash)

    a hash mapping the specified fields to their values

See Also:



2226
2227
2228
2229
2230
2231
2232
2233
2234
# File 'lib/redis.rb', line 2226

def mapped_hmget(key, *fields)
  hmget(key, *fields) do |reply|
    if reply.is_a?(Array)
      Hash[fields.zip(reply)]
    else
      reply
    end
  end
end

#mapped_hmset(key, hash) ⇒ String

Set one or more hash values.

Examples:

redis.mapped_hmset("hash", { "f1" => "v1", "f2" => "v2" })
  # => "OK"

Parameters:

  • key (String)
  • hash (Hash)

    a non-empty hash with fields mapping to values

Returns:

  • (String)

    ‘“OK”`

See Also:



2183
2184
2185
# File 'lib/redis.rb', line 2183

def mapped_hmset(key, hash)
  hmset(key, hash.to_a.flatten)
end

#mapped_mget(*keys) ⇒ Hash

Get the values of all the given keys.

Examples:

redis.mapped_mget("key1", "key2")
  # => { "key1" => "v1", "key2" => "v2" }

Parameters:

  • keys (Array<String>)

    array of keys

Returns:

  • (Hash)

    a hash mapping the specified keys to their values

See Also:



986
987
988
989
990
991
992
993
994
# File 'lib/redis.rb', line 986

def mapped_mget(*keys)
  mget(*keys) do |reply|
    if reply.is_a?(Array)
      Hash[keys.zip(reply)]
    else
      reply
    end
  end
end

#mapped_mset(hash) ⇒ String

Set one or more values.

Examples:

redis.mapped_mset({ "f1" => "v1", "f2" => "v2" })
  # => "OK"

Parameters:

  • hash (Hash)

    keys mapping to values

Returns:

  • (String)

    ‘“OK”`

See Also:



916
917
918
# File 'lib/redis.rb', line 916

def mapped_mset(hash)
  mset(hash.to_a.flatten)
end

#mapped_msetnx(hash) ⇒ Boolean

Set one or more values, only if none of the keys exist.

Examples:

redis.mapped_msetnx({ "key1" => "v1", "key2" => "v2" })
  # => true

Parameters:

  • hash (Hash)

    keys mapping to values

Returns:

  • (Boolean)

    whether or not all values were set

See Also:



946
947
948
# File 'lib/redis.rb', line 946

def mapped_msetnx(hash)
  msetnx(hash.to_a.flatten)
end

#mget(*keys, &blk) ⇒ Array<String>

Get the values of all the given keys.

Examples:

redis.mget("key1", "key2")
  # => ["v1", "v2"]

Parameters:

  • keys (Array<String>)

Returns:

  • (Array<String>)

    an array of values for the specified keys

See Also:



970
971
972
973
974
# File 'lib/redis.rb', line 970

def mget(*keys, &blk)
  synchronize do |client|
    client.call([:mget, *keys], &blk)
  end
end

#migrate(key, options) ⇒ String

Transfer a key from the connected instance to another instance.

Parameters:

  • key (String, Array<String>)
  • options (Hash)
    • ‘:host => String`: host of instance to migrate to

    • ‘:port => Integer`: port of instance to migrate to

    • ‘:db => Integer`: database to migrate to (default: same as source)

    • ‘:timeout => Integer`: timeout (default: same as connection timeout)

    • ‘:copy => Boolean`: Do not remove the key from the local instance.

    • ‘:replace => Boolean`: Replace existing key on the remote instance.

Returns:

  • (String)

    ‘“OK”`



539
540
541
542
543
544
545
546
547
548
549
550
551
# File 'lib/redis.rb', line 539

def migrate(key, options)
  args = [:migrate]
  args << (options[:host] || raise(':host not specified'))
  args << (options[:port] || raise(':port not specified'))
  args << (key.is_a?(String) ? key : '')
  args << (options[:db] || @client.db).to_i
  args << (options[:timeout] || @client.timeout).to_i
  args << 'COPY' if options[:copy]
  args << 'REPLACE' if options[:replace]
  args += ['KEYS', *key] if key.is_a?(Array)

  synchronize { |client| client.call(args) }
end

#monitor {|line| ... } ⇒ Object

Listen for all requests received by the server in real time.

There is no way to interrupt this command.

Yields:

  • a block to be called for every line of output

Yield Parameters:

  • line (String)

    timestamp and command that was executed



340
341
342
343
344
# File 'lib/redis.rb', line 340

def monitor(&block)
  synchronize do |client|
    client.call_loop([:monitor], &block)
  end
end

#move(key, db) ⇒ Boolean

Move a key to another database.

Examples:

Move a key to another database

redis.set "foo", "bar"
  # => "OK"
redis.move "foo", 2
  # => true
redis.exists "foo"
  # => false
redis.select 2
  # => "OK"
redis.exists "foo"
  # => true
redis.get "foo"
  # => "bar"

Parameters:

  • key (String)
  • db (Integer)

Returns:

  • (Boolean)

    whether the key was moved or not



648
649
650
651
652
# File 'lib/redis.rb', line 648

def move(key, db)
  synchronize do |client|
    client.call([:move, key, db], &Boolify)
  end
end

#mset(*args) ⇒ String

Set one or more values.

Examples:

redis.mset("key1", "v1", "key2", "v2")
  # => "OK"

Parameters:

  • args (Array<String>)

    array of keys and values

Returns:

  • (String)

    ‘“OK”`

See Also:



900
901
902
903
904
# File 'lib/redis.rb', line 900

def mset(*args)
  synchronize do |client|
    client.call([:mset] + args)
  end
end

#msetnx(*args) ⇒ Boolean

Set one or more values, only if none of the keys exist.

Examples:

redis.msetnx("key1", "v1", "key2", "v2")
  # => true

Parameters:

  • args (Array<String>)

    array of keys and values

Returns:

  • (Boolean)

    whether or not all values were set

See Also:



930
931
932
933
934
# File 'lib/redis.rb', line 930

def msetnx(*args)
  synchronize do |client|
    client.call([:msetnx, *args], &Boolify)
  end
end

#multi {|multi| ... } ⇒ String, Array<...>

Mark the start of a transaction block.

Passing a block is optional.

Examples:

With a block

redis.multi do |multi|
  multi.set("key", "value")
  multi.incr("counter")
end # => ["OK", 6]

Without a block

redis.multi
  # => "OK"
redis.set("key", "value")
  # => "QUEUED"
redis.incr("counter")
  # => "QUEUED"
redis.exec
  # => ["OK", 6]

Yields:

  • (multi)

    the commands that are called inside this block are cached and written to the server upon returning from it

Yield Parameters:

  • multi (Redis)

    ‘self`

Returns:

  • (String, Array<...>)
    • when a block is not given, ‘OK`

    • when a block is given, an array with replies

See Also:



2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
# File 'lib/redis.rb', line 2484

def multi
  synchronize do |prior_client|
    if !block_given?
      prior_client.call([:multi])
    else
      begin
        @client = Pipeline::Multi.new(prior_client)
        yield(self)
        prior_client.call_pipeline(@client)
      ensure
        @client = prior_client
      end
    end
  end
end

#object(*args) ⇒ Object



654
655
656
657
658
# File 'lib/redis.rb', line 654

def object(*args)
  synchronize do |client|
    client.call([:object] + args)
  end
end

#persist(key) ⇒ Boolean

Remove the expiration from a key.

Parameters:

  • key (String)

Returns:

  • (Boolean)

    whether the timeout was removed or not



415
416
417
418
419
# File 'lib/redis.rb', line 415

def persist(key)
  synchronize do |client|
    client.call([:persist, key], &Boolify)
  end
end

#pexpire(key, milliseconds) ⇒ Boolean

Set a key’s time to live in milliseconds.

Parameters:

  • key (String)
  • milliseconds (Integer)

    time to live

Returns:

  • (Boolean)

    whether the timeout was set or not



466
467
468
469
470
# File 'lib/redis.rb', line 466

def pexpire(key, milliseconds)
  synchronize do |client|
    client.call([:pexpire, key, milliseconds], &Boolify)
  end
end

#pexpireat(key, ms_unix_time) ⇒ Boolean

Set the expiration for a key as number of milliseconds from UNIX Epoch.

Parameters:

  • key (String)
  • ms_unix_time (Integer)

    expiry time specified as number of milliseconds from UNIX Epoch.

Returns:

  • (Boolean)

    whether the timeout was set or not



477
478
479
480
481
# File 'lib/redis.rb', line 477

def pexpireat(key, ms_unix_time)
  synchronize do |client|
    client.call([:pexpireat, key, ms_unix_time], &Boolify)
  end
end

#pfadd(key, member) ⇒ Boolean

Add one or more members to a HyperLogLog structure.

Parameters:

  • key (String)
  • member (String, Array<String>)

    one member, or array of members

Returns:

  • (Boolean)

    true if at least 1 HyperLogLog internal register was altered. false otherwise.



2829
2830
2831
2832
2833
# File 'lib/redis.rb', line 2829

def pfadd(key, member)
  synchronize do |client|
    client.call([:pfadd, key, member], &Boolify)
  end
end

#pfcount(*keys) ⇒ Integer

Get the approximate cardinality of members added to HyperLogLog structure.

If called with multiple keys, returns the approximate cardinality of the union of the HyperLogLogs contained in the keys.

Parameters:

  • keys (String, Array<String>)

Returns:

  • (Integer)


2842
2843
2844
2845
2846
# File 'lib/redis.rb', line 2842

def pfcount(*keys)
  synchronize do |client|
    client.call([:pfcount] + keys)
  end
end

#pfmerge(dest_key, *source_key) ⇒ Boolean

Merge multiple HyperLogLog values into an unique value that will approximate the cardinality of the union of the observed Sets of the source HyperLogLog structures.

Parameters:

  • dest_key (String)

    destination key

  • source_key (String, Array<String>)

    source key, or array of keys

Returns:

  • (Boolean)


2854
2855
2856
2857
2858
# File 'lib/redis.rb', line 2854

def pfmerge(dest_key, *source_key)
  synchronize do |client|
    client.call([:pfmerge, dest_key, *source_key], &BoolifySet)
  end
end

#ping(message = nil) ⇒ String

Ping the server.

Parameters:

  • message (optional, String) (defaults to: nil)

Returns:

  • (String)

    ‘PONG`



172
173
174
175
176
# File 'lib/redis.rb', line 172

def ping(message = nil)
  synchronize do |client|
    client.call([:ping, message].compact)
  end
end

#pipelinedObject



2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
# File 'lib/redis.rb', line 2442

def pipelined
  synchronize do |prior_client|
    begin
      @client = Pipeline.new(prior_client)
      yield(self)
      prior_client.call_pipeline(@client)
    ensure
      @client = prior_client
    end
  end
end

#psetex(key, ttl, value) ⇒ String

Set the time to live in milliseconds of a key.

Parameters:

  • key (String)
  • ttl (Integer)
  • value (String)

Returns:

  • (String)

    ‘“OK”`



873
874
875
876
877
# File 'lib/redis.rb', line 873

def psetex(key, ttl, value)
  synchronize do |client|
    client.call([:psetex, key, ttl, value.to_s])
  end
end

#psubscribe(*channels, &block) ⇒ Object

Listen for messages published to channels matching the given patterns.



2350
2351
2352
2353
2354
# File 'lib/redis.rb', line 2350

def psubscribe(*channels, &block)
  synchronize do |_client|
    _subscription(:psubscribe, 0, channels, block)
  end
end

#psubscribe_with_timeout(timeout, *channels, &block) ⇒ Object

Listen for messages published to channels matching the given patterns. Throw a timeout error if there is no messages for a timeout period.



2358
2359
2360
2361
2362
# File 'lib/redis.rb', line 2358

def psubscribe_with_timeout(timeout, *channels, &block)
  synchronize do |_client|
    _subscription(:psubscribe_with_timeout, timeout, channels, block)
  end
end

#pttl(key) ⇒ Integer

Get the time to live (in milliseconds) for a key.

In Redis 2.6 or older the command returns -1 if the key does not exist or if the key exist but has no associated expire.

Starting with Redis 2.8 the return value in case of error changed:

- The command returns -2 if the key does not exist.
- The command returns -1 if the key exists but has no associated expire.

Parameters:

  • key (String)

Returns:

  • (Integer)

    remaining time to live in milliseconds



494
495
496
497
498
# File 'lib/redis.rb', line 494

def pttl(key)
  synchronize do |client|
    client.call([:pttl, key])
  end
end

#publish(channel, message) ⇒ Object

Post a message to a channel.



2313
2314
2315
2316
2317
# File 'lib/redis.rb', line 2313

def publish(channel, message)
  synchronize do |client|
    client.call([:publish, channel, message])
  end
end

#pubsub(subcommand, *args) ⇒ Object

Inspect the state of the Pub/Sub subsystem. Possible subcommands: channels, numsub, numpat.



2375
2376
2377
2378
2379
# File 'lib/redis.rb', line 2375

def pubsub(subcommand, *args)
  synchronize do |client|
    client.call([:pubsub, subcommand] + args)
  end
end

#punsubscribe(*channels) ⇒ Object

Stop listening for messages posted to channels matching the given patterns.



2365
2366
2367
2368
2369
2370
2371
# File 'lib/redis.rb', line 2365

def punsubscribe(*channels)
  synchronize do |client|
    raise "Can't unsubscribe if not subscribed." unless subscribed?

    client.punsubscribe(*channels)
  end
end

#queue(*command) ⇒ Object

Queues a command for pipelining.

Commands in the queue are executed with the Redis#commit method.

See redis.io/topics/pipelining for more details.



116
117
118
119
120
# File 'lib/redis.rb', line 116

def queue(*command)
  synchronize do
    @queue[Thread.current.object_id] << command
  end
end

#quitString

Close the connection.

Returns:

  • (String)

    ‘OK`



191
192
193
194
195
196
197
198
199
200
# File 'lib/redis.rb', line 191

def quit
  synchronize do |client|
    begin
      client.call([:quit])
    rescue ConnectionError
    ensure
      client.disconnect
    end
  end
end

#randomkeyString

Return a random key from the keyspace.

Returns:

  • (String)


663
664
665
666
667
# File 'lib/redis.rb', line 663

def randomkey
  synchronize do |client|
    client.call([:randomkey])
  end
end

#rename(old_name, new_name) ⇒ String

Rename a key. If the new key already exists it is overwritten.

Parameters:

  • old_name (String)
  • new_name (String)

Returns:

  • (String)

    ‘OK`



674
675
676
677
678
# File 'lib/redis.rb', line 674

def rename(old_name, new_name)
  synchronize do |client|
    client.call([:rename, old_name, new_name])
  end
end

#renamenx(old_name, new_name) ⇒ Boolean

Rename a key, only if the new key does not exist.

Parameters:

  • old_name (String)
  • new_name (String)

Returns:

  • (Boolean)

    whether the key was renamed or not



685
686
687
688
689
# File 'lib/redis.rb', line 685

def renamenx(old_name, new_name)
  synchronize do |client|
    client.call([:renamenx, old_name, new_name], &Boolify)
  end
end

#restore(key, ttl, serialized_value, replace: nil) ⇒ String

Create a key using the serialized value, previously obtained using DUMP.

Parameters:

  • key (String)
  • ttl (String)
  • serialized_value (String)
  • options (Hash)
    • ‘:replace => Boolean`: if false, raises an error if key already exists

Returns:

  • (String)

    ‘“OK”`

Raises:



519
520
521
522
523
524
525
526
# File 'lib/redis.rb', line 519

def restore(key, ttl, serialized_value, replace: nil)
  args = [:restore, key, ttl, serialized_value]
  args << 'REPLACE' if replace

  synchronize do |client|
    client.call(args)
  end
end

#rpop(key) ⇒ String

Remove and get the last element in a list.

Parameters:

  • key (String)

Returns:

  • (String)


1189
1190
1191
1192
1193
# File 'lib/redis.rb', line 1189

def rpop(key)
  synchronize do |client|
    client.call([:rpop, key])
  end
end

#rpoplpush(source, destination) ⇒ nil, String

Remove the last element in a list, append it to another list and return it.

Parameters:

  • source (String)

    source key

  • destination (String)

    destination key

Returns:

  • (nil, String)

    the element, or nil when the source key does not exist



1200
1201
1202
1203
1204
# File 'lib/redis.rb', line 1200

def rpoplpush(source, destination)
  synchronize do |client|
    client.call([:rpoplpush, source, destination])
  end
end

#rpush(key, value) ⇒ Integer

Append one or more values to a list, creating the list if it doesn’t exist

Parameters:

  • key (String)
  • value (String, Array<String>)

    string value, or array of string values to push

Returns:

  • (Integer)

    the length of the list after the push operation



1158
1159
1160
1161
1162
# File 'lib/redis.rb', line 1158

def rpush(key, value)
  synchronize do |client|
    client.call([:rpush, key, value])
  end
end

#rpushx(key, value) ⇒ Integer

Append a value to a list, only if the list exists.

Parameters:

  • key (String)
  • value (String)

Returns:

  • (Integer)

    the length of the list after the push operation



1169
1170
1171
1172
1173
# File 'lib/redis.rb', line 1169

def rpushx(key, value)
  synchronize do |client|
    client.call([:rpushx, key, value])
  end
end

#sadd(key, member) ⇒ Boolean, Integer

Add one or more members to a set.

Parameters:

  • key (String)
  • member (String, Array<String>)

    one member, or array of members

Returns:

  • (Boolean, Integer)

    ‘Boolean` when a single member is specified, holding whether or not adding the member succeeded, or `Integer` when an array of members is specified, holding the number of members that were successfully added



1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
# File 'lib/redis.rb', line 1384

def sadd(key, member)
  synchronize do |client|
    client.call([:sadd, key, member]) do |reply|
      if member.is_a? Array
        # Variadic: return integer
        reply
      else
        # Single argument: return boolean
        Boolify.call(reply)
      end
    end
  end
end

#saveString

Synchronously save the dataset to disk.

Returns:

  • (String)


349
350
351
352
353
# File 'lib/redis.rb', line 349

def save
  synchronize do |client|
    client.call([:save])
  end
end

#scan(cursor, **options) ⇒ String+

Scan the keyspace

Examples:

Retrieve the first batch of keys

redis.scan(0)
  # => ["4", ["key:21", "key:47", "key:42"]]

Retrieve a batch of keys matching a pattern

redis.scan(4, :match => "key:1?")
  # => ["92", ["key:13", "key:18"]]

Retrieve a batch of keys of a certain type

redis.scan(92, :type => "zset")
  # => ["173", ["sortedset:14", "sortedset:78"]]

Parameters:

  • cursor (String, Integer)

    the cursor of the iteration

  • options (Hash)
    • ‘:match => String`: only return keys matching the pattern

    • ‘:count => Integer`: return count keys at most per iteration

    • ‘:type => String`: return keys only of the given type

Returns:

  • (String, Array<String>)

    the next cursor and all found keys



2673
2674
2675
# File 'lib/redis.rb', line 2673

def scan(cursor, **options)
  _scan(:scan, cursor, [], **options)
end

#scan_each(**options, &block) ⇒ Enumerator

Scan the keyspace

Examples:

Retrieve all of the keys (with possible duplicates)

redis.scan_each.to_a
  # => ["key:21", "key:47", "key:42"]

Execute block for each key matching a pattern

redis.scan_each(:match => "key:1?") {|key| puts key}
  # => key:13
  # => key:18

Execute block for each key of a type

redis.scan_each(:type => "hash") {|key| puts redis.type(key)}
  # => "hash"
  # => "hash"

Parameters:

  • options (Hash)
    • ‘:match => String`: only return keys matching the pattern

    • ‘:count => Integer`: return count keys at most per iteration

    • ‘:type => String`: return keys only of the given type

Returns:

  • (Enumerator)

    an enumerator for all found keys



2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
# File 'lib/redis.rb', line 2697

def scan_each(**options, &block)
  return to_enum(:scan_each, **options) unless block_given?

  cursor = 0
  loop do
    cursor, keys = scan(cursor, **options)
    keys.each(&block)
    break if cursor == "0"
  end
end

#scard(key) ⇒ Integer

Get the number of members in a set.

Parameters:

  • key (String)

Returns:

  • (Integer)


1370
1371
1372
1373
1374
# File 'lib/redis.rb', line 1370

def scard(key)
  synchronize do |client|
    client.call([:scard, key])
  end
end

#script(subcommand, *args) ⇒ String, ...

Control remote script registry.

Examples:

Load a script

sha = redis.script(:load, "return 1")
  # => <sha of this script>

Check if a script exists

redis.script(:exists, sha)
  # => true

Check if multiple scripts exist

redis.script(:exists, [sha, other_sha])
  # => [true, false]

Flush the script registry

redis.script(:flush)
  # => "OK"

Kill a running script

redis.script(:kill)
  # => "OK"

Parameters:

  • subcommand (String)

    e.g. ‘exists`, `flush`, `load`, `kill`

  • args (Array<String>)

    depends on subcommand

Returns:

  • (String, Boolean, Array<Boolean>, ...)

    depends on subcommand

See Also:



2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
# File 'lib/redis.rb', line 2554

def script(subcommand, *args)
  subcommand = subcommand.to_s.downcase

  if subcommand == "exists"
    synchronize do |client|
      arg = args.first

      client.call([:script, :exists, arg]) do |reply|
        reply = reply.map { |r| Boolify.call(r) }

        if arg.is_a?(Array)
          reply
        else
          reply.first
        end
      end
    end
  else
    synchronize do |client|
      client.call([:script, subcommand] + args)
    end
  end
end

#sdiff(*keys) ⇒ Array<String>

Subtract multiple sets.

Parameters:

  • keys (String, Array<String>)

    keys pointing to sets to subtract

Returns:

  • (Array<String>)

    members in the difference



1487
1488
1489
1490
1491
# File 'lib/redis.rb', line 1487

def sdiff(*keys)
  synchronize do |client|
    client.call([:sdiff, *keys])
  end
end

#sdiffstore(destination, *keys) ⇒ Integer

Subtract multiple sets and store the resulting set in a key.

Parameters:

  • destination (String)

    destination key

  • keys (String, Array<String>)

    keys pointing to sets to subtract

Returns:

  • (Integer)

    number of elements in the resulting set



1498
1499
1500
1501
1502
# File 'lib/redis.rb', line 1498

def sdiffstore(destination, *keys)
  synchronize do |client|
    client.call([:sdiffstore, destination, *keys])
  end
end

#select(db) ⇒ String

Change the selected database for the current connection.

Parameters:

  • db (Integer)

    zero-based index of the DB to use (0 to 15)

Returns:

  • (String)

    ‘OK`



161
162
163
164
165
166
# File 'lib/redis.rb', line 161

def select(db)
  synchronize do |client|
    client.db = db
    client.call([:select, db])
  end
end

#sentinel(subcommand, *args) ⇒ Array<String>, ...

Interact with the sentinel command (masters, master, slaves, failover)

Parameters:

  • subcommand (String)

    e.g. ‘masters`, `master`, `slaves`

  • args (Array<String>)

    depends on subcommand

Returns:

  • (Array<String>, Hash<String, String>, String)

    depends on subcommand



3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
# File 'lib/redis.rb', line 3272

def sentinel(subcommand, *args)
  subcommand = subcommand.to_s.downcase
  synchronize do |client|
    client.call([:sentinel, subcommand] + args) do |reply|
      case subcommand
      when "get-master-addr-by-name"
        reply
      else
        if reply.is_a?(Array)
          if reply[0].is_a?(Array)
            reply.map(&Hashify)
          else
            Hashify.call(reply)
          end
        else
          reply
        end
      end
    end
  end
end

#set(key, value, ex: nil, px: nil, nx: nil, xx: nil, keepttl: nil) ⇒ String, Boolean

Set the string value of a key.

Parameters:

  • key (String)
  • value (String)
  • options (Hash)
    • ‘:ex => Integer`: Set the specified expire time, in seconds.

    • ‘:px => Integer`: Set the specified expire time, in milliseconds.

    • ‘:nx => true`: Only set the key if it does not already exist.

    • ‘:xx => true`: Only set the key if it already exist.

    • ‘:keepttl => true`: Retain the time to live associated with the key.

Returns:

  • (String, Boolean)

    ‘“OK”` or true, false if `:nx => true` or `:xx => true`



838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
# File 'lib/redis.rb', line 838

def set(key, value, ex: nil, px: nil, nx: nil, xx: nil, keepttl: nil)
  args = [:set, key, value.to_s]
  args << "EX" << ex if ex
  args << "PX" << px if px
  args << "NX" if nx
  args << "XX" if xx
  args << "KEEPTTL" if keepttl

  synchronize do |client|
    if nx || xx
      client.call(args, &BoolifySet)
    else
      client.call(args)
    end
  end
end

#setbit(key, offset, value) ⇒ Integer

Sets or clears the bit at offset in the string value stored at key.

Parameters:

  • key (String)
  • offset (Integer)

    bit offset

  • value (Integer)

    bit value ‘0` or `1`

Returns:

  • (Integer)

    the original bit value stored at ‘offset`



1027
1028
1029
1030
1031
# File 'lib/redis.rb', line 1027

def setbit(key, offset, value)
  synchronize do |client|
    client.call([:setbit, key, offset, value])
  end
end

#setex(key, ttl, value) ⇒ String

Set the time to live in seconds of a key.

Parameters:

  • key (String)
  • ttl (Integer)
  • value (String)

Returns:

  • (String)

    ‘“OK”`



861
862
863
864
865
# File 'lib/redis.rb', line 861

def setex(key, ttl, value)
  synchronize do |client|
    client.call([:setex, key, ttl, value.to_s])
  end
end

#setnx(key, value) ⇒ Boolean

Set the value of a key, only if the key does not exist.

Parameters:

  • key (String)
  • value (String)

Returns:

  • (Boolean)

    whether the key was set or not



884
885
886
887
888
# File 'lib/redis.rb', line 884

def setnx(key, value)
  synchronize do |client|
    client.call([:setnx, key, value.to_s], &Boolify)
  end
end

#setrange(key, offset, value) ⇒ Integer

Overwrite part of a string at key starting at the specified offset.

Parameters:

  • key (String)
  • offset (Integer)

    byte offset

  • value (String)

Returns:

  • (Integer)

    length of the string after it was modified



1002
1003
1004
1005
1006
# File 'lib/redis.rb', line 1002

def setrange(key, offset, value)
  synchronize do |client|
    client.call([:setrange, key, offset, value.to_s])
  end
end

#shutdownObject

Synchronously save the dataset to disk and then shut down the server.



356
357
358
359
360
361
362
363
364
365
366
367
# File 'lib/redis.rb', line 356

def shutdown
  synchronize do |client|
    client.with_reconnect(false) do
      begin
        client.call([:shutdown])
      rescue ConnectionError
        # This means Redis has probably exited.
        nil
      end
    end
  end
end

#sinter(*keys) ⇒ Array<String>

Intersect multiple sets.

Parameters:

  • keys (String, Array<String>)

    keys pointing to sets to intersect

Returns:

  • (Array<String>)

    members in the intersection



1508
1509
1510
1511
1512
# File 'lib/redis.rb', line 1508

def sinter(*keys)
  synchronize do |client|
    client.call([:sinter, *keys])
  end
end

#sinterstore(destination, *keys) ⇒ Integer

Intersect multiple sets and store the resulting set in a key.

Parameters:

  • destination (String)

    destination key

  • keys (String, Array<String>)

    keys pointing to sets to intersect

Returns:

  • (Integer)

    number of elements in the resulting set



1519
1520
1521
1522
1523
# File 'lib/redis.rb', line 1519

def sinterstore(destination, *keys)
  synchronize do |client|
    client.call([:sinterstore, destination, *keys])
  end
end

#sismember(key, member) ⇒ Boolean

Determine if a given value is a member of a set.

Parameters:

  • key (String)
  • member (String)

Returns:

  • (Boolean)


1467
1468
1469
1470
1471
# File 'lib/redis.rb', line 1467

def sismember(key, member)
  synchronize do |client|
    client.call([:sismember, key, member], &Boolify)
  end
end

#slaveof(host, port) ⇒ Object

Make the server a slave of another instance, or promote it as master.



370
371
372
373
374
# File 'lib/redis.rb', line 370

def slaveof(host, port)
  synchronize do |client|
    client.call([:slaveof, host, port])
  end
end

#slowlog(subcommand, length = nil) ⇒ Array<String>, ...

Interact with the slowlog (get, len, reset)

Parameters:

  • subcommand (String)

    e.g. ‘get`, `len`, `reset`

  • length (Integer) (defaults to: nil)

    maximum number of entries to return

Returns:

  • (Array<String>, Integer, String)

    depends on subcommand



381
382
383
384
385
386
387
# File 'lib/redis.rb', line 381

def slowlog(subcommand, length = nil)
  synchronize do |client|
    args = [:slowlog, subcommand]
    args << length if length
    client.call args
  end
end

#smembers(key) ⇒ Array<String>

Get all the members in a set.

Parameters:

  • key (String)

Returns:

  • (Array<String>)


1477
1478
1479
1480
1481
# File 'lib/redis.rb', line 1477

def smembers(key)
  synchronize do |client|
    client.call([:smembers, key])
  end
end

#smove(source, destination, member) ⇒ Boolean

Move a member from one set to another.

Parameters:

  • source (String)

    source key

  • destination (String)

    destination key

  • member (String)

    member to move from ‘source` to `destination`

Returns:

  • (Boolean)


1456
1457
1458
1459
1460
# File 'lib/redis.rb', line 1456

def smove(source, destination, member)
  synchronize do |client|
    client.call([:smove, source, destination, member], &Boolify)
  end
end

#sort(key, by: nil, limit: nil, get: nil, order: nil, store: nil) ⇒ Array<String>, ...

Sort the elements in a list, set or sorted set.

Examples:

Retrieve the first 2 elements from an alphabetically sorted “list”

redis.sort("list", :order => "alpha", :limit => [0, 2])
  # => ["a", "b"]

Store an alphabetically descending list in “target”

redis.sort("list", :order => "desc alpha", :store => "target")
  # => 26

Parameters:

  • key (String)
  • options (Hash)
    • ‘:by => String`: use external key to sort elements by

    • ‘:limit => [offset, count]`: skip `offset` elements, return a maximum

    of ‘count` elements

    • ‘:get => [String, Array<String>]`: single key or array of keys to

    retrieve per element in the result

    • ‘:order => String`: combination of `ASC`, `DESC` and optionally `ALPHA`

    • ‘:store => String`: key to store the result at

Returns:

  • (Array<String>, Array<Array<String>>, Integer)
    • when ‘:get` is not specified, or holds a single element, an array of elements

    • when ‘:get` is specified, and holds more than one element, an array of

    elements where every element is an array with the result for every element specified in ‘:get`

    • when ‘:store` is specified, the number of elements in the stored result



716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
# File 'lib/redis.rb', line 716

def sort(key, by: nil, limit: nil, get: nil, order: nil, store: nil)
  args = [:sort, key]
  args << "BY" << by if by

  if limit
    args << "LIMIT"
    args.concat(limit)
  end

  get = Array(get)
  get.each do |item|
    args << "GET" << item
  end

  args.concat(order.split(" ")) if order
  args << "STORE" << store if store

  synchronize do |client|
    client.call(args) do |reply|
      if get.size > 1 && !store
        reply.each_slice(get.size).to_a if reply
      else
        reply
      end
    end
  end
end

#spop(key, count = nil) ⇒ String

Remove and return one or more random member from a set.

Parameters:

  • key (String)
  • count (Integer) (defaults to: nil)

Returns:

  • (String)


1425
1426
1427
1428
1429
1430
1431
1432
1433
# File 'lib/redis.rb', line 1425

def spop(key, count = nil)
  synchronize do |client|
    if count.nil?
      client.call([:spop, key])
    else
      client.call([:spop, key, count])
    end
  end
end

#srandmember(key, count = nil) ⇒ String

Get one or more random members from a set.

Parameters:

  • key (String)
  • count (Integer) (defaults to: nil)

Returns:

  • (String)


1440
1441
1442
1443
1444
1445
1446
1447
1448
# File 'lib/redis.rb', line 1440

def srandmember(key, count = nil)
  synchronize do |client|
    if count.nil?
      client.call([:srandmember, key])
    else
      client.call([:srandmember, key, count])
    end
  end
end

#srem(key, member) ⇒ Boolean, Integer

Remove one or more members from a set.

Parameters:

  • key (String)
  • member (String, Array<String>)

    one member, or array of members

Returns:

  • (Boolean, Integer)

    ‘Boolean` when a single member is specified, holding whether or not removing the member succeeded, or `Integer` when an array of members is specified, holding the number of members that were successfully removed



1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
# File 'lib/redis.rb', line 1406

def srem(key, member)
  synchronize do |client|
    client.call([:srem, key, member]) do |reply|
      if member.is_a? Array
        # Variadic: return integer
        reply
      else
        # Single argument: return boolean
        Boolify.call(reply)
      end
    end
  end
end

#sscan(key, cursor, **options) ⇒ String+

Scan a set

Examples:

Retrieve the first batch of keys in a set

redis.sscan("set", 0)

Parameters:

  • cursor (String, Integer)

    the cursor of the iteration

  • options (Hash)
    • ‘:match => String`: only return keys matching the pattern

    • ‘:count => Integer`: return count keys at most per iteration

Returns:

  • (String, Array<String>)

    the next cursor and all found members



2798
2799
2800
# File 'lib/redis.rb', line 2798

def sscan(key, cursor, **options)
  _scan(:sscan, cursor, [key], **options)
end

#sscan_each(key, **options, &block) ⇒ Enumerator

Scan a set

Examples:

Retrieve all of the keys in a set

redis.sscan_each("set").to_a
# => ["key1", "key2", "key3"]

Parameters:

  • options (Hash)
    • ‘:match => String`: only return keys matching the pattern

    • ‘:count => Integer`: return count keys at most per iteration

Returns:

  • (Enumerator)

    an enumerator for all keys in the set



2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
# File 'lib/redis.rb', line 2813

def sscan_each(key, **options, &block)
  return to_enum(:sscan_each, key, **options) unless block_given?

  cursor = 0
  loop do
    cursor, keys = sscan(key, cursor, **options)
    keys.each(&block)
    break if cursor == "0"
  end
end

#strlen(key) ⇒ Integer

Get the length of the value stored in a key.

Parameters:

  • key (String)

Returns:

  • (Integer)

    the length of the value stored in the key, or 0 if the key does not exist



1115
1116
1117
1118
1119
# File 'lib/redis.rb', line 1115

def strlen(key)
  synchronize do |client|
    client.call([:strlen, key])
  end
end

#subscribe(*channels, &block) ⇒ Object

Listen for messages published to the given channels.



2326
2327
2328
2329
2330
# File 'lib/redis.rb', line 2326

def subscribe(*channels, &block)
  synchronize do |_client|
    _subscription(:subscribe, 0, channels, block)
  end
end

#subscribe_with_timeout(timeout, *channels, &block) ⇒ Object

Listen for messages published to the given channels. Throw a timeout error if there is no messages for a timeout period.



2334
2335
2336
2337
2338
# File 'lib/redis.rb', line 2334

def subscribe_with_timeout(timeout, *channels, &block)
  synchronize do |_client|
    _subscription(:subscribe_with_timeout, timeout, channels, block)
  end
end

#subscribed?Boolean

Returns:

  • (Boolean)


2319
2320
2321
2322
2323
# File 'lib/redis.rb', line 2319

def subscribed?
  synchronize do |client|
    client.is_a? SubscribedClient
  end
end

#sunion(*keys) ⇒ Array<String>

Add multiple sets.

Parameters:

  • keys (String, Array<String>)

    keys pointing to sets to unify

Returns:

  • (Array<String>)

    members in the union



1529
1530
1531
1532
1533
# File 'lib/redis.rb', line 1529

def sunion(*keys)
  synchronize do |client|
    client.call([:sunion, *keys])
  end
end

#sunionstore(destination, *keys) ⇒ Integer

Add multiple sets and store the resulting set in a key.

Parameters:

  • destination (String)

    destination key

  • keys (String, Array<String>)

    keys pointing to sets to unify

Returns:

  • (Integer)

    number of elements in the resulting set



1540
1541
1542
1543
1544
# File 'lib/redis.rb', line 1540

def sunionstore(destination, *keys)
  synchronize do |client|
    client.call([:sunionstore, destination, *keys])
  end
end

#syncObject

Internal command used for replication.



390
391
392
393
394
# File 'lib/redis.rb', line 390

def sync
  synchronize do |client|
    client.call([:sync])
  end
end

#synchronizeObject



69
70
71
# File 'lib/redis.rb', line 69

def synchronize
  mon_synchronize { yield(@client) }
end

#timeArray<Integer>

Return the server time.

Examples:

r.time # => [ 1333093196, 606806 ]

Returns:

  • (Array<Integer>)

    tuple of seconds since UNIX epoch and microseconds in the current second



403
404
405
406
407
408
409
# File 'lib/redis.rb', line 403

def time
  synchronize do |client|
    client.call([:time]) do |reply|
      reply&.map(&:to_i)
    end
  end
end

#ttl(key) ⇒ Integer

Get the time to live (in seconds) for a key.

In Redis 2.6 or older the command returns -1 if the key does not exist or if the key exist but has no associated expire.

Starting with Redis 2.8 the return value in case of error changed:

- The command returns -2 if the key does not exist.
- The command returns -1 if the key exists but has no associated expire.

Parameters:

  • key (String)

Returns:

  • (Integer)

    remaining time to live in seconds.



455
456
457
458
459
# File 'lib/redis.rb', line 455

def ttl(key)
  synchronize do |client|
    client.call([:ttl, key])
  end
end

#type(key) ⇒ String

Determine the type stored at key.

Parameters:

  • key (String)

Returns:

  • (String)

    ‘string`, `list`, `set`, `zset`, `hash` or `none`



748
749
750
751
752
# File 'lib/redis.rb', line 748

def type(key)
  synchronize do |client|
    client.call([:type, key])
  end
end

Unlink one or more keys.

Parameters:

  • keys (String, Array<String>)

Returns:

  • (Integer)

    number of keys that were unlinked



567
568
569
570
571
# File 'lib/redis.rb', line 567

def unlink(*keys)
  synchronize do |client|
    client.call([:unlink] + keys)
  end
end

#unsubscribe(*channels) ⇒ Object

Stop listening for messages posted to the given channels.



2341
2342
2343
2344
2345
2346
2347
# File 'lib/redis.rb', line 2341

def unsubscribe(*channels)
  synchronize do |client|
    raise "Can't unsubscribe if not subscribed." unless subscribed?

    client.unsubscribe(*channels)
  end
end

#unwatchString

Forget about all watched keys.

Returns:

  • (String)

    ‘OK`

See Also:



2436
2437
2438
2439
2440
# File 'lib/redis.rb', line 2436

def unwatch
  synchronize do |client|
    client.call([:unwatch])
  end
end

#watch(*keys) ⇒ Object, String

Watch the given keys to determine execution of the MULTI/EXEC block.

Using a block is optional, but is necessary for thread-safety.

An ‘#unwatch` is automatically issued if an exception is raised within the block that is a subclass of StandardError and is not a ConnectionError.

Examples:

With a block

redis.watch("key") do
  if redis.get("key") == "some value"
    redis.multi do |multi|
      multi.set("key", "other value")
      multi.incr("counter")
    end
  else
    redis.unwatch
  end
end
  # => ["OK", 6]

Without a block

redis.watch("key")
  # => "OK"

Parameters:

  • keys (String, Array<String>)

    one or more keys to watch

Returns:

  • (Object)

    if using a block, returns the return value of the block

  • (String)

    if not using a block, returns ‘OK`

See Also:



2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
# File 'lib/redis.rb', line 2411

def watch(*keys)
  synchronize do |client|
    res = client.call([:watch, *keys])

    if block_given?
      begin
        yield(self)
      rescue ConnectionError
        raise
      rescue StandardError
        unwatch
        raise
      end
    else
      res
    end
  end
end

#with_reconnect(val = true, &blk) ⇒ Object

Run code with the client reconnecting



74
75
76
77
78
# File 'lib/redis.rb', line 74

def with_reconnect(val = true, &blk)
  synchronize do |client|
    client.with_reconnect(val, &blk)
  end
end

#without_reconnect(&blk) ⇒ Object

Run code without the client reconnecting



81
82
83
# File 'lib/redis.rb', line 81

def without_reconnect(&blk)
  with_reconnect(false, &blk)
end

#xack(key, group, *ids) ⇒ Integer

Removes one or multiple entries from the pending entries list of a stream consumer group.

Examples:

With a entry id

redis.xack('mystream', 'mygroup', '1526569495631-0')

With splatted entry ids

redis.xack('mystream', 'mygroup', '0-1', '0-2')

With arrayed entry ids

redis.xack('mystream', 'mygroup', %w[0-1 0-2])

Parameters:

  • key (String)

    the stream key

  • group (String)

    the consumer group name

  • ids (Array<String>)

    one or multiple entry ids

Returns:

  • (Integer)

    the number of entries successfully acknowledged



3187
3188
3189
3190
# File 'lib/redis.rb', line 3187

def xack(key, group, *ids)
  args = [:xack, key, group].concat(ids.flatten)
  synchronize { |client| client.call(args) }
end

#xadd(key, entry, approximate: nil, maxlen: nil, id: '*') ⇒ String

Add new entry to the stream.

Examples:

Without options

redis.xadd('mystream', f1: 'v1', f2: 'v2')

With options

redis.xadd('mystream', { f1: 'v1', f2: 'v2' }, id: '0-0', maxlen: 1000, approximate: true)

Parameters:

  • key (String)

    the stream key

  • entry (Hash)

    one or multiple field-value pairs

  • opts (Hash)

    several options for ‘XADD` command

Returns:

  • (String)

    the entry id



2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
# File 'lib/redis.rb', line 2987

def xadd(key, entry, approximate: nil, maxlen: nil, id: '*')
  args = [:xadd, key]
  if maxlen
    args << "MAXLEN"
    args << "~" if approximate
    args << maxlen
  end
  args << id
  args.concat(entry.to_a.flatten)
  synchronize { |client| client.call(args) }
end

#xclaim(key, group, consumer, min_idle_time, *ids, **opts) ⇒ Hash{String => Hash}, Array<String>

Changes the ownership of a pending entry

Examples:

With splatted entry ids

redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, '0-1', '0-2')

With arrayed entry ids

redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, %w[0-1 0-2])

With idle option

redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, %w[0-1 0-2], idle: 1000)

With time option

redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, %w[0-1 0-2], time: 1542866959000)

With retrycount option

redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, %w[0-1 0-2], retrycount: 10)

With force option

redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, %w[0-1 0-2], force: true)

With justid option

redis.xclaim('mystream', 'mygroup', 'consumer1', 3600000, %w[0-1 0-2], justid: true)

Parameters:

  • key (String)

    the stream key

  • group (String)

    the consumer group name

  • consumer (String)

    the consumer name

  • min_idle_time (Integer)

    the number of milliseconds

  • ids (Array<String>)

    one or multiple entry ids

  • opts (Hash)

    several options for ‘XCLAIM` command

Options Hash (**opts):

  • :idle (Integer)

    the number of milliseconds as last time it was delivered of the entry

  • :time (Integer)

    the number of milliseconds as a specific Unix Epoch time

  • :retrycount (Integer)

    the number of retry counter

  • :force (Boolean)

    whether to create the pending entry to the pending entries list or not

  • :justid (Boolean)

    whether to fetch just an array of entry ids or not

Returns:

  • (Hash{String => Hash})

    the entries successfully claimed

  • (Array<String>)

    the entry ids successfully claimed if justid option is ‘true`



3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
# File 'lib/redis.rb', line 3224

def xclaim(key, group, consumer, min_idle_time, *ids, **opts)
  args = [:xclaim, key, group, consumer, min_idle_time].concat(ids.flatten)
  args.concat(['IDLE',       opts[:idle].to_i])  if opts[:idle]
  args.concat(['TIME',       opts[:time].to_i])  if opts[:time]
  args.concat(['RETRYCOUNT', opts[:retrycount]]) if opts[:retrycount]
  args << 'FORCE'                                if opts[:force]
  args << 'JUSTID'                               if opts[:justid]
  blk = opts[:justid] ? Noop : HashifyStreamEntries
  synchronize { |client| client.call(args, &blk) }
end

#xdel(key, *ids) ⇒ Integer

Delete entries by entry ids.

Examples:

With splatted entry ids

redis.xdel('mystream', '0-1', '0-2')

With arrayed entry ids

redis.xdel('mystream', ['0-1', '0-2'])

Parameters:

  • key (String)

    the stream key

  • ids (Array<String>)

    one or multiple entry ids

Returns:

  • (Integer)

    the number of entries actually deleted



3027
3028
3029
3030
# File 'lib/redis.rb', line 3027

def xdel(key, *ids)
  args = [:xdel, key].concat(ids.flatten)
  synchronize { |client| client.call(args) }
end

#xgroup(subcommand, key, group, id_or_consumer = nil, mkstream: false) ⇒ String, Integer

Manages the consumer group of the stream.

Examples:

With ‘create` subcommand

redis.xgroup(:create, 'mystream', 'mygroup', '$')

With ‘setid` subcommand

redis.xgroup(:setid, 'mystream', 'mygroup', '$')

With ‘destroy` subcommand

redis.xgroup(:destroy, 'mystream', 'mygroup')

With ‘delconsumer` subcommand

redis.xgroup(:delconsumer, 'mystream', 'mygroup', 'consumer1')

Parameters:

  • subcommand (String)

    ‘create` `setid` `destroy` `delconsumer`

  • key (String)

    the stream key

  • group (String)

    the consumer group name

  • id_or_consumer (String) (defaults to: nil)
    • the entry id or ‘$`, required if subcommand is `create` or `setid`

    • the consumer name, required if subcommand is ‘delconsumer`

  • mkstream (Boolean) (defaults to: false)

    whether to create an empty stream automatically or not

Returns:

  • (String)

    ‘OK` if subcommand is `create` or `setid`

  • (Integer)

    effected count if subcommand is ‘destroy` or `delconsumer`



3135
3136
3137
3138
# File 'lib/redis.rb', line 3135

def xgroup(subcommand, key, group, id_or_consumer = nil, mkstream: false)
  args = [:xgroup, subcommand, key, group, id_or_consumer, (mkstream ? 'MKSTREAM' : nil)].compact
  synchronize { |client| client.call(args) }
end

#xinfo(subcommand, key, group = nil) ⇒ Hash+

Returns the stream information each subcommand.

Examples:

stream

redis.xinfo(:stream, 'mystream')

groups

redis.xinfo(:groups, 'mystream')

consumers

redis.xinfo(:consumers, 'mystream', 'mygroup')

Parameters:

  • subcommand (String)

    e.g. ‘stream` `groups` `consumers`

  • key (String)

    the stream key

  • group (String) (defaults to: nil)

    the consumer group name, required if subcommand is ‘consumers`

Returns:

  • (Hash)

    information of the stream if subcommand is ‘stream`

  • (Array<Hash>)

    information of the consumer groups if subcommand is ‘groups`

  • (Array<Hash>)

    information of the consumers if subcommand is ‘consumers`



2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
# File 'lib/redis.rb', line 2958

def xinfo(subcommand, key, group = nil)
  args = [:xinfo, subcommand, key, group].compact
  synchronize do |client|
    client.call(args) do |reply|
      case subcommand.to_s.downcase
      when 'stream'              then Hashify.call(reply)
      when 'groups', 'consumers' then reply.map { |arr| Hashify.call(arr) }
      else reply
      end
    end
  end
end

#xlen(key) ⇒ Integer

Returns the number of entries inside a stream.

Examples:

With key

redis.xlen('mystream')

Parameters:

  • key (String)

    the stream key

Returns:

  • (Integer)

    the number of entries



3086
3087
3088
# File 'lib/redis.rb', line 3086

def xlen(key)
  synchronize { |client| client.call([:xlen, key]) }
end

#xpending(key, group, *args) ⇒ Hash+

Fetches not acknowledging pending entries

Examples:

With key and group

redis.xpending('mystream', 'mygroup')

With range options

redis.xpending('mystream', 'mygroup', '-', '+', 10)

With range and consumer options

redis.xpending('mystream', 'mygroup', '-', '+', 10, 'consumer1')

Parameters:

  • key (String)

    the stream key

  • group (String)

    the consumer group name

  • start (String)

    start first entry id of range

  • end (String)

    end last entry id of range

  • count (Integer)

    count the number of entries as limit

  • consumer (String)

    the consumer name

Returns:

  • (Hash)

    the summary of pending entries

  • (Array<Hash>)

    the pending entries details if options were specified



3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
# File 'lib/redis.rb', line 3253

def xpending(key, group, *args)
  command_args = [:xpending, key, group]
  case args.size
  when 0, 3, 4
    command_args.concat(args)
  else
    raise ArgumentError, "wrong number of arguments (given #{args.size + 2}, expected 2, 5 or 6)"
  end

  summary_needed = args.empty?
  blk = summary_needed ? HashifyStreamPendings : HashifyStreamPendingDetails
  synchronize { |client| client.call(command_args, &blk) }
end

#xrange(key, start = '-', range_end = '+', count: nil) ⇒ Array<Array<String, Hash>>

Fetches entries of the stream in ascending order.

Examples:

Without options

redis.xrange('mystream')

With a specific start

redis.xrange('mystream', '0-1')

With a specific start and end

redis.xrange('mystream', '0-1', '0-3')

With count options

redis.xrange('mystream', count: 10)

Parameters:

  • key (String)

    the stream key

  • start (String) (defaults to: '-')

    first entry id of range, default value is ‘-`

  • end (String)

    last entry id of range, default value is ‘+`

  • count (Integer) (defaults to: nil)

    the number of entries as limit

Returns:

  • (Array<Array<String, Hash>>)

    the ids and entries pairs



3049
3050
3051
3052
3053
# File 'lib/redis.rb', line 3049

def xrange(key, start = '-', range_end = '+', count: nil)
  args = [:xrange, key, start, range_end]
  args.concat(['COUNT', count]) if count
  synchronize { |client| client.call(args, &HashifyStreamEntries) }
end

#xread(keys, ids, count: nil, block: nil) ⇒ Hash{String => Hash{String => Hash}}

Fetches entries from one or multiple streams. Optionally blocking.

Examples:

With a key

redis.xread('mystream', '0-0')

With multiple keys

redis.xread(%w[mystream1 mystream2], %w[0-0 0-0])

With count option

redis.xread('mystream', '0-0', count: 2)

With block option

redis.xread('mystream', '$', block: 1000)

Parameters:

  • keys (Array<String>)

    one or multiple stream keys

  • ids (Array<String>)

    one or multiple entry ids

  • count (Integer) (defaults to: nil)

    the number of entries as limit per stream

  • block (Integer) (defaults to: nil)

    the number of milliseconds as blocking timeout

Returns:

  • (Hash{String => Hash{String => Hash}})

    the entries



3107
3108
3109
3110
3111
3112
# File 'lib/redis.rb', line 3107

def xread(keys, ids, count: nil, block: nil)
  args = [:xread]
  args << 'COUNT' << count if count
  args << 'BLOCK' << block.to_i if block
  _xread(args, keys, ids, block)
end

#xreadgroup(group, consumer, keys, ids, count: nil, block: nil, noack: nil) ⇒ Hash{String => Hash{String => Hash}}

Fetches a subset of the entries from one or multiple streams related with the consumer group. Optionally blocking.

Examples:

With a key

redis.xreadgroup('mygroup', 'consumer1', 'mystream', '>')

With multiple keys

redis.xreadgroup('mygroup', 'consumer1', %w[mystream1 mystream2], %w[> >])

With count option

redis.xreadgroup('mygroup', 'consumer1', 'mystream', '>', count: 2)

With block option

redis.xreadgroup('mygroup', 'consumer1', 'mystream', '>', block: 1000)

With noack option

redis.xreadgroup('mygroup', 'consumer1', 'mystream', '>', noack: true)

Parameters:

  • group (String)

    the consumer group name

  • consumer (String)

    the consumer name

  • keys (Array<String>)

    one or multiple stream keys

  • ids (Array<String>)

    one or multiple entry ids

  • opts (Hash)

    several options for ‘XREADGROUP` command

Returns:

  • (Hash{String => Hash{String => Hash}})

    the entries



3165
3166
3167
3168
3169
3170
3171
# File 'lib/redis.rb', line 3165

def xreadgroup(group, consumer, keys, ids, count: nil, block: nil, noack: nil)
  args = [:xreadgroup, 'GROUP', group, consumer]
  args << 'COUNT' << count if count
  args << 'BLOCK' << block.to_i if block
  args << 'NOACK' if noack
  _xread(args, keys, ids, block)
end

#xrevrange(key, range_end = '+', start = '-', count: nil) ⇒ Array<Array<String, Hash>>

Fetches entries of the stream in descending order.

Examples:

Without options

redis.xrevrange('mystream')

With a specific end

redis.xrevrange('mystream', '0-3')

With a specific end and start

redis.xrevrange('mystream', '0-3', '0-1')

With count options

redis.xrevrange('mystream', count: 10)

Parameters:

  • key (String)

    the stream key

  • end (String)

    first entry id of range, default value is ‘+`

  • start (String) (defaults to: '-')

    last entry id of range, default value is ‘-`

Returns:

  • (Array<Array<String, Hash>>)

    the ids and entries pairs



3072
3073
3074
3075
3076
# File 'lib/redis.rb', line 3072

def xrevrange(key, range_end = '+', start = '-', count: nil)
  args = [:xrevrange, key, range_end, start]
  args.concat(['COUNT', count]) if count
  synchronize { |client| client.call(args, &HashifyStreamEntries) }
end

#xtrim(key, maxlen, approximate: false) ⇒ Integer

Trims older entries of the stream if needed.

Examples:

Without options

redis.xtrim('mystream', 1000)

With options

redis.xtrim('mystream', 1000, approximate: true)

Parameters:

  • key (String)

    the stream key

  • mexlen (Integer)

    max length of entries

  • approximate (Boolean) (defaults to: false)

    whether to add ‘~` modifier of maxlen or not

Returns:

  • (Integer)

    the number of entries actually deleted



3011
3012
3013
3014
# File 'lib/redis.rb', line 3011

def xtrim(key, maxlen, approximate: false)
  args = [:xtrim, key, 'MAXLEN', (approximate ? '~' : nil), maxlen].compact
  synchronize { |client| client.call(args) }
end

#zadd(key, *args, nx: nil, xx: nil, ch: nil, incr: nil) ⇒ Boolean, ...

Add one or more members to a sorted set, or update the score for members that already exist.

Examples:

Add a single ‘[score, member]` pair to a sorted set

redis.zadd("zset", 32.0, "member")

Add an array of ‘[score, member]` pairs to a sorted set

redis.zadd("zset", [[32.0, "a"], [64.0, "b"]])

Parameters:

  • key (String)
  • args ([Float, String], Array<[Float, String]>)
    • a single ‘[score, member]` pair

    • an array of ‘[score, member]` pairs

  • options (Hash)
    • ‘:xx => true`: Only update elements that already exist (never

    add elements)

    • ‘:nx => true`: Don’t update already existing elements (always

    add new elements)

    • ‘:ch => true`: Modify the return value from the number of new

    elements added, to the total number of elements changed (CH is an abbreviation of changed); changed elements are new elements added and elements already existing for which the score was updated

    • ‘:incr => true`: When this option is specified ZADD acts like

    ZINCRBY; only one score-element pair can be specified in this mode

Returns:

  • (Boolean, Integer, Float)
    • ‘Boolean` when a single pair is specified, holding whether or not it was

    added to the sorted set.

    • ‘Integer` when an array of pairs is specified, holding the number of

    pairs that were added to the sorted set.

    • ‘Float` when option :incr is specified, holding the score of the member

    after incrementing it.



1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
# File 'lib/redis.rb', line 1591

def zadd(key, *args, nx: nil, xx: nil, ch: nil, incr: nil)
  command = [:zadd, key]
  command << "NX" if nx
  command << "XX" if xx
  command << "CH" if ch
  command << "INCR" if incr

  synchronize do |client|
    if args.size == 1 && args[0].is_a?(Array)
      # Variadic: return float if INCR, integer if !INCR
      client.call(command + args[0], &(incr ? Floatify : nil))
    elsif args.size == 2
      # Single pair: return float if INCR, boolean if !INCR
      client.call(command + args, &(incr ? Floatify : Boolify))
    else
      raise ArgumentError, "wrong number of arguments"
    end
  end
end

#zcard(key) ⇒ Integer

Get the number of members in a sorted set.

Examples:

redis.zcard("zset")
  # => 4

Parameters:

  • key (String)

Returns:

  • (Integer)


1554
1555
1556
1557
1558
# File 'lib/redis.rb', line 1554

def zcard(key)
  synchronize do |client|
    client.call([:zcard, key])
  end
end

#zcount(key, min, max) ⇒ Integer

Count the members in a sorted set with scores within the given values.

Examples:

Count members with score ‘>= 5` and `< 100`

redis.zcount("zset", "5", "(100")
  # => 2

Count members with scores ‘> 5`

redis.zcount("zset", "(5", "+inf")
  # => 2

Parameters:

  • key (String)
  • min (String)
    • inclusive minimum score is specified verbatim

    • exclusive minimum score is specified by prefixing ‘(`

  • max (String)
    • inclusive maximum score is specified verbatim

    • exclusive maximum score is specified by prefixing ‘(`

Returns:

  • (Integer)

    number of members in within the specified range



2053
2054
2055
2056
2057
# File 'lib/redis.rb', line 2053

def zcount(key, min, max)
  synchronize do |client|
    client.call([:zcount, key, min, max])
  end
end

#zincrby(key, increment, member) ⇒ Float

Increment the score of a member in a sorted set.

Examples:

redis.zincrby("zset", 32.0, "a")
  # => 64.0

Parameters:

  • key (String)
  • increment (Float)
  • member (String)

Returns:

  • (Float)

    score of the member after incrementing it



1621
1622
1623
1624
1625
# File 'lib/redis.rb', line 1621

def zincrby(key, increment, member)
  synchronize do |client|
    client.call([:zincrby, key, increment, member], &Floatify)
  end
end

#zinterstore(destination, keys, weights: nil, aggregate: nil) ⇒ Integer

Intersect multiple sorted sets and store the resulting sorted set in a new key.

Examples:

Compute the intersection of ‘2*zsetA` with `1*zsetB`, summing their scores

redis.zinterstore("zsetC", ["zsetA", "zsetB"], :weights => [2.0, 1.0], :aggregate => "sum")
  # => 4

Parameters:

  • destination (String)

    destination key

  • keys (Array<String>)

    source keys

  • options (Hash)
    • ‘:weights => [Float, Float, …]`: weights to associate with source

    sorted sets

    • ‘:aggregate => String`: aggregate function to use (sum, min, max, …)

Returns:

  • (Integer)

    number of elements in the resulting sorted set



2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
# File 'lib/redis.rb', line 2073

def zinterstore(destination, keys, weights: nil, aggregate: nil)
  args = [:zinterstore, destination, keys.size, *keys]

  if weights
    args << "WEIGHTS"
    args.concat(weights)
  end

  args << "AGGREGATE" << aggregate if aggregate

  synchronize do |client|
    client.call(args)
  end
end

#zlexcount(key, min, max) ⇒ Integer

Count the members, with the same score in a sorted set, within the given lexicographical range.

Examples:

Count members matching a

redis.zlexcount("zset", "[a", "[a\xff")
  # => 1

Count members matching a-z

redis.zlexcount("zset", "[a", "[z\xff")
  # => 26

Parameters:

  • key (String)
  • min (String)
    • inclusive minimum is specified by prefixing ‘(`

    • exclusive minimum is specified by prefixing ‘[`

  • max (String)
    • inclusive maximum is specified by prefixing ‘(`

    • exclusive maximum is specified by prefixing ‘[`

Returns:

  • (Integer)

    number of members within the specified lexicographical range



1872
1873
1874
1875
1876
# File 'lib/redis.rb', line 1872

def zlexcount(key, min, max)
  synchronize do |client|
    client.call([:zlexcount, key, min, max])
  end
end

#zpopmax(key, count = nil) ⇒ Array<String, Float>+

Removes and returns up to count members with the highest scores in the sorted set stored at key.

Examples:

Popping a member

redis.zpopmax('zset')
#=> ['b', 2.0]

With count option

redis.zpopmax('zset', 2)
#=> [['b', 2.0], ['a', 1.0]]

Returns:

  • (Array<String, Float>)

    element and score pair if count is not specified

  • (Array<Array<String, Float>>)

    list of popped elements and scores



1672
1673
1674
1675
1676
1677
# File 'lib/redis.rb', line 1672

def zpopmax(key, count = nil)
  synchronize do |client|
    members = client.call([:zpopmax, key, count].compact, &FloatifyPairs)
    count.to_i > 1 ? members : members.first
  end
end

#zpopmin(key, count = nil) ⇒ Array<String, Float>+

Removes and returns up to count members with the lowest scores in the sorted set stored at key.

Examples:

Popping a member

redis.zpopmin('zset')
#=> ['a', 1.0]

With count option

redis.zpopmin('zset', 2)
#=> [['a', 1.0], ['b', 2.0]]

Returns:

  • (Array<String, Float>)

    element and score pair if count is not specified

  • (Array<Array<String, Float>>)

    list of popped elements and scores



1693
1694
1695
1696
1697
1698
# File 'lib/redis.rb', line 1693

def zpopmin(key, count = nil)
  synchronize do |client|
    members = client.call([:zpopmin, key, count].compact, &FloatifyPairs)
    count.to_i > 1 ? members : members.first
  end
end

#zrange(key, start, stop, withscores: false, with_scores: withscores) ⇒ Array<String>, Array<[String, Float]>

Return a range of members in a sorted set, by index.

Examples:

Retrieve all members from a sorted set

redis.zrange("zset", 0, -1)
  # => ["a", "b"]

Retrieve all members and their scores from a sorted set

redis.zrange("zset", 0, -1, :with_scores => true)
  # => [["a", 32.0], ["b", 64.0]]

Parameters:

  • key (String)
  • start (Integer)

    start index

  • stop (Integer)

    stop index

  • options (Hash)
    • ‘:with_scores => true`: include scores in output

Returns:

  • (Array<String>, Array<[String, Float]>)
    • when ‘:with_scores` is not specified, an array of members

    • when ‘:with_scores` is specified, an array with `[member, score]` pairs



1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
# File 'lib/redis.rb', line 1775

def zrange(key, start, stop, withscores: false, with_scores: withscores)
  args = [:zrange, key, start, stop]

  if with_scores
    args << "WITHSCORES"
    block = FloatifyPairs
  end

  synchronize do |client|
    client.call(args, &block)
  end
end

#zrangebylex(key, min, max, limit: nil) ⇒ Array<String>, Array<[String, Float]>

Return a range of members with the same score in a sorted set, by lexicographical ordering

Examples:

Retrieve members matching a

redis.zrangebylex("zset", "[a", "[a\xff")
  # => ["aaren", "aarika", "abagael", "abby"]

Retrieve the first 2 members matching a

redis.zrangebylex("zset", "[a", "[a\xff", :limit => [0, 2])
  # => ["aaren", "aarika"]

Parameters:

  • key (String)
  • min (String)
    • inclusive minimum is specified by prefixing ‘(`

    • exclusive minimum is specified by prefixing ‘[`

  • max (String)
    • inclusive maximum is specified by prefixing ‘(`

    • exclusive maximum is specified by prefixing ‘[`

  • options (Hash)
    • ‘:limit => [offset, count]`: skip `offset` members, return a maximum of

    ‘count` members

Returns:

  • (Array<String>, Array<[String, Float]>)


1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
# File 'lib/redis.rb', line 1899

def zrangebylex(key, min, max, limit: nil)
  args = [:zrangebylex, key, min, max]

  if limit
    args << "LIMIT"
    args.concat(limit)
  end

  synchronize do |client|
    client.call(args)
  end
end

#zrangebyscore(key, min, max, withscores: false, with_scores: withscores, limit: nil) ⇒ Array<String>, Array<[String, Float]>

Return a range of members in a sorted set, by score.

Examples:

Retrieve members with score ‘>= 5` and `< 100`

redis.zrangebyscore("zset", "5", "(100")
  # => ["a", "b"]

Retrieve the first 2 members with score ‘>= 0`

redis.zrangebyscore("zset", "0", "+inf", :limit => [0, 2])
  # => ["a", "b"]

Retrieve members and their scores with scores ‘> 5`

redis.zrangebyscore("zset", "(5", "+inf", :with_scores => true)
  # => [["a", 32.0], ["b", 64.0]]

Parameters:

  • key (String)
  • min (String)
    • inclusive minimum score is specified verbatim

    • exclusive minimum score is specified by prefixing ‘(`

  • max (String)
    • inclusive maximum score is specified verbatim

    • exclusive maximum score is specified by prefixing ‘(`

  • options (Hash)
    • ‘:with_scores => true`: include scores in output

    • ‘:limit => [offset, count]`: skip `offset` members, return a maximum of

    ‘count` members

Returns:

  • (Array<String>, Array<[String, Float]>)
    • when ‘:with_scores` is not specified, an array of members

    • when ‘:with_scores` is specified, an array with `[member, score]` pairs



1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
# File 'lib/redis.rb', line 1963

def zrangebyscore(key, min, max, withscores: false, with_scores: withscores, limit: nil)
  args = [:zrangebyscore, key, min, max]

  if with_scores
    args << "WITHSCORES"
    block = FloatifyPairs
  end

  if limit
    args << "LIMIT"
    args.concat(limit)
  end

  synchronize do |client|
    client.call(args, &block)
  end
end

#zrank(key, member) ⇒ Integer

Determine the index of a member in a sorted set.

Parameters:

  • key (String)
  • member (String)

Returns:

  • (Integer)


1817
1818
1819
1820
1821
# File 'lib/redis.rb', line 1817

def zrank(key, member)
  synchronize do |client|
    client.call([:zrank, key, member])
  end
end

#zrem(key, member) ⇒ Boolean, Integer

Remove one or more members from a sorted set.

Examples:

Remove a single member from a sorted set

redis.zrem("zset", "a")

Remove an array of members from a sorted set

redis.zrem("zset", ["a", "b"])

Parameters:

  • key (String)
  • member (String, Array<String>)
    • a single member

    • an array of members

Returns:

  • (Boolean, Integer)
    • ‘Boolean` when a single member is specified, holding whether or not it

    was removed from the sorted set

    • ‘Integer` when an array of pairs is specified, holding the number of

    members that were removed to the sorted set



1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
# File 'lib/redis.rb', line 1644

def zrem(key, member)
  synchronize do |client|
    client.call([:zrem, key, member]) do |reply|
      if member.is_a? Array
        # Variadic: return integer
        reply
      else
        # Single argument: return boolean
        Boolify.call(reply)
      end
    end
  end
end

#zremrangebyrank(key, start, stop) ⇒ Integer

Remove all members in a sorted set within the given indexes.

Examples:

Remove first 5 members

redis.zremrangebyrank("zset", 0, 4)
  # => 5

Remove last 5 members

redis.zremrangebyrank("zset", -5, -1)
  # => 5

Parameters:

  • key (String)
  • start (Integer)

    start index

  • stop (Integer)

    stop index

Returns:

  • (Integer)

    number of members that were removed



1848
1849
1850
1851
1852
# File 'lib/redis.rb', line 1848

def zremrangebyrank(key, start, stop)
  synchronize do |client|
    client.call([:zremrangebyrank, key, start, stop])
  end
end

#zremrangebyscore(key, min, max) ⇒ Integer

Remove all members in a sorted set within the given scores.

Examples:

Remove members with score ‘>= 5` and `< 100`

redis.zremrangebyscore("zset", "5", "(100")
  # => 2

Remove members with scores ‘> 5`

redis.zremrangebyscore("zset", "(5", "+inf")
  # => 2

Parameters:

  • key (String)
  • min (String)
    • inclusive minimum score is specified verbatim

    • exclusive minimum score is specified by prefixing ‘(`

  • max (String)
    • inclusive maximum score is specified verbatim

    • exclusive maximum score is specified by prefixing ‘(`

Returns:

  • (Integer)

    number of members that were removed



2030
2031
2032
2033
2034
# File 'lib/redis.rb', line 2030

def zremrangebyscore(key, min, max)
  synchronize do |client|
    client.call([:zremrangebyscore, key, min, max])
  end
end

#zrevrange(key, start, stop, withscores: false, with_scores: withscores) ⇒ Object

Return a range of members in a sorted set, by index, with scores ordered from high to low.

Examples:

Retrieve all members from a sorted set

redis.zrevrange("zset", 0, -1)
  # => ["b", "a"]

Retrieve all members and their scores from a sorted set

redis.zrevrange("zset", 0, -1, :with_scores => true)
  # => [["b", 64.0], ["a", 32.0]]

See Also:



1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
# File 'lib/redis.rb', line 1799

def zrevrange(key, start, stop, withscores: false, with_scores: withscores)
  args = [:zrevrange, key, start, stop]

  if with_scores
    args << "WITHSCORES"
    block = FloatifyPairs
  end

  synchronize do |client|
    client.call(args, &block)
  end
end

#zrevrangebylex(key, max, min, limit: nil) ⇒ Object

Return a range of members with the same score in a sorted set, by reversed lexicographical ordering. Apart from the reversed ordering, #zrevrangebylex is similar to #zrangebylex.

Examples:

Retrieve members matching a

redis.zrevrangebylex("zset", "[a", "[a\xff")
  # => ["abbygail", "abby", "abagael", "aaren"]

Retrieve the last 2 members matching a

redis.zrevrangebylex("zset", "[a", "[a\xff", :limit => [0, 2])
  # => ["abbygail", "abby"]

See Also:



1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
# File 'lib/redis.rb', line 1923

def zrevrangebylex(key, max, min, limit: nil)
  args = [:zrevrangebylex, key, max, min]

  if limit
    args << "LIMIT"
    args.concat(limit)
  end

  synchronize do |client|
    client.call(args)
  end
end

#zrevrangebyscore(key, max, min, withscores: false, with_scores: withscores, limit: nil) ⇒ Object

Return a range of members in a sorted set, by score, with scores ordered from high to low.

Examples:

Retrieve members with score ‘< 100` and `>= 5`

redis.zrevrangebyscore("zset", "(100", "5")
  # => ["b", "a"]

Retrieve the first 2 members with score ‘<= 0`

redis.zrevrangebyscore("zset", "0", "-inf", :limit => [0, 2])
  # => ["b", "a"]

Retrieve members and their scores with scores ‘> 5`

redis.zrevrangebyscore("zset", "+inf", "(5", :with_scores => true)
  # => [["b", 64.0], ["a", 32.0]]

See Also:



1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
# File 'lib/redis.rb', line 1995

def zrevrangebyscore(key, max, min, withscores: false, with_scores: withscores, limit: nil)
  args = [:zrevrangebyscore, key, max, min]

  if with_scores
    args << "WITHSCORES"
    block = FloatifyPairs
  end

  if limit
    args << "LIMIT"
    args.concat(limit)
  end

  synchronize do |client|
    client.call(args, &block)
  end
end

#zrevrank(key, member) ⇒ Integer

Determine the index of a member in a sorted set, with scores ordered from high to low.

Parameters:

  • key (String)
  • member (String)

Returns:

  • (Integer)


1829
1830
1831
1832
1833
# File 'lib/redis.rb', line 1829

def zrevrank(key, member)
  synchronize do |client|
    client.call([:zrevrank, key, member])
  end
end

#zscan(key, cursor, **options) ⇒ String, Array<[String, Float]>

Scan a sorted set

Examples:

Retrieve the first batch of key/value pairs in a hash

redis.zscan("zset", 0)

Parameters:

  • cursor (String, Integer)

    the cursor of the iteration

  • options (Hash)
    • ‘:match => String`: only return keys matching the pattern

    • ‘:count => Integer`: return count keys at most per iteration

Returns:

  • (String, Array<[String, Float]>)

    the next cursor and all found members and scores



2759
2760
2761
2762
2763
# File 'lib/redis.rb', line 2759

def zscan(key, cursor, **options)
  _scan(:zscan, cursor, [key], **options) do |reply|
    [reply[0], FloatifyPairs.call(reply[1])]
  end
end

#zscan_each(key, **options, &block) ⇒ Enumerator

Scan a sorted set

Examples:

Retrieve all of the members/scores in a sorted set

redis.zscan_each("zset").to_a
# => [["key70", "70"], ["key80", "80"]]

Parameters:

  • options (Hash)
    • ‘:match => String`: only return keys matching the pattern

    • ‘:count => Integer`: return count keys at most per iteration

Returns:

  • (Enumerator)

    an enumerator for all found scores and members



2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
# File 'lib/redis.rb', line 2776

def zscan_each(key, **options, &block)
  return to_enum(:zscan_each, key, **options) unless block_given?

  cursor = 0
  loop do
    cursor, values = zscan(key, cursor, **options)
    values.each(&block)
    break if cursor == "0"
  end
end

#zscore(key, member) ⇒ Float

Get the score associated with the given member in a sorted set.

Examples:

Get the score for member “a”

redis.zscore("zset", "a")
  # => 32.0

Parameters:

  • key (String)
  • member (String)

Returns:

  • (Float)

    score of the member



1751
1752
1753
1754
1755
# File 'lib/redis.rb', line 1751

def zscore(key, member)
  synchronize do |client|
    client.call([:zscore, key, member], &Floatify)
  end
end

#zunionstore(destination, keys, weights: nil, aggregate: nil) ⇒ Integer

Add multiple sorted sets and store the resulting sorted set in a new key.

Examples:

Compute the union of ‘2*zsetA` with `1*zsetB`, summing their scores

redis.zunionstore("zsetC", ["zsetA", "zsetB"], :weights => [2.0, 1.0], :aggregate => "sum")
  # => 8

Parameters:

  • destination (String)

    destination key

  • keys (Array<String>)

    source keys

  • options (Hash)
    • ‘:weights => [Float, Float, …]`: weights to associate with source

    sorted sets

    • ‘:aggregate => String`: aggregate function to use (sum, min, max, …)

Returns:

  • (Integer)

    number of elements in the resulting sorted set



2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
# File 'lib/redis.rb', line 2101

def zunionstore(destination, keys, weights: nil, aggregate: nil)
  args = [:zunionstore, destination, keys.size, *keys]

  if weights
    args << "WEIGHTS"
    args.concat(weights)
  end

  args << "AGGREGATE" << aggregate if aggregate

  synchronize do |client|
    client.call(args)
  end
end