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.1'

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



3364
3365
3366
3367
3368
# File 'lib/redis.rb', line 3364

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



1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
# File 'lib/redis.rb', line 1212

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



2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
# File 'lib/redis.rb', line 2584

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



2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
# File 'lib/redis.rb', line 2647

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:



3336
3337
3338
# File 'lib/redis.rb', line 3336

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



1257
1258
1259
# File 'lib/redis.rb', line 1257

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:



1273
1274
1275
# File 'lib/redis.rb', line 1273

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



1288
1289
1290
1291
1292
1293
1294
# File 'lib/redis.rb', line 1288

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



1721
1722
1723
1724
1725
# File 'lib/redis.rb', line 1721

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



1742
1743
1744
1745
1746
# File 'lib/redis.rb', line 1742

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:



3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
# File 'lib/redis.rb', line 3308

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



3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
# File 'lib/redis.rb', line 3352

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:



2530
2531
2532
2533
2534
# File 'lib/redis.rb', line 2530

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



3348
3349
3350
# File 'lib/redis.rb', line 3348

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:



2618
2619
2620
# File 'lib/redis.rb', line 2618

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:



2643
2644
2645
# File 'lib/redis.rb', line 2643

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:



2516
2517
2518
2519
2520
# File 'lib/redis.rb', line 2516

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



2871
2872
2873
2874
2875
# File 'lib/redis.rb', line 2871

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.



2942
2943
2944
2945
2946
# File 'lib/redis.rb', line 2942

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



2882
2883
2884
2885
2886
# File 'lib/redis.rb', line 2882

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



2930
2931
2932
2933
2934
# File 'lib/redis.rb', line 2930

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`



2898
2899
2900
2901
2902
2903
2904
# File 'lib/redis.rb', line 2898

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`



2916
2917
2918
2919
2920
2921
2922
# File 'lib/redis.rb', line 2916

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



2247
2248
2249
2250
2251
# File 'lib/redis.rb', line 2247

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



2258
2259
2260
2261
2262
# File 'lib/redis.rb', line 2258

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)


2198
2199
2200
2201
2202
# File 'lib/redis.rb', line 2198

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>)


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

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



2270
2271
2272
2273
2274
# File 'lib/redis.rb', line 2270

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



2282
2283
2284
2285
2286
# File 'lib/redis.rb', line 2282

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>)


2292
2293
2294
2295
2296
# File 'lib/redis.rb', line 2292

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



2126
2127
2128
2129
2130
# File 'lib/redis.rb', line 2126

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:



2215
2216
2217
2218
2219
# File 'lib/redis.rb', line 2215

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:



2172
2173
2174
2175
2176
# File 'lib/redis.rb', line 2172

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



2725
2726
2727
2728
2729
# File 'lib/redis.rb', line 2725

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



2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
# File 'lib/redis.rb', line 2742

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



2141
2142
2143
2144
2145
2146
2147
# File 'lib/redis.rb', line 2141

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



2155
2156
2157
2158
2159
# File 'lib/redis.rb', line 2155

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>)


2302
2303
2304
2305
2306
# File 'lib/redis.rb', line 2302

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

#idObject



3340
3341
3342
# File 'lib/redis.rb', line 3340

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



3344
3345
3346
# File 'lib/redis.rb', line 3344

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)


1301
1302
1303
1304
1305
# File 'lib/redis.rb', line 1301

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



1315
1316
1317
1318
1319
# File 'lib/redis.rb', line 1315

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, count = nil) ⇒ String+

Remove and get the first elements in a list.

Parameters:

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

    number of elements to remove

Returns:

  • (String, Array<String>)

    the values of the first elements



1180
1181
1182
1183
1184
1185
1186
# File 'lib/redis.rb', line 1180

def lpop(key, count = nil)
  synchronize do |client|
    command = [:lpop, key]
    command << count if count
    client.call(command)
  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>)


1327
1328
1329
1330
1331
# File 'lib/redis.rb', line 1327

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



1342
1343
1344
1345
1346
# File 'lib/redis.rb', line 1342

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`



1354
1355
1356
1357
1358
# File 'lib/redis.rb', line 1354

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`



1366
1367
1368
1369
1370
# File 'lib/redis.rb', line 1366

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:



2232
2233
2234
2235
2236
2237
2238
2239
2240
# File 'lib/redis.rb', line 2232

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:



2189
2190
2191
# File 'lib/redis.rb', line 2189

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:



2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
# File 'lib/redis.rb', line 2490

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.



2835
2836
2837
2838
2839
# File 'lib/redis.rb', line 2835

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)


2848
2849
2850
2851
2852
# File 'lib/redis.rb', line 2848

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)


2860
2861
2862
2863
2864
# File 'lib/redis.rb', line 2860

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



2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
# File 'lib/redis.rb', line 2448

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.



2356
2357
2358
2359
2360
# File 'lib/redis.rb', line 2356

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.



2364
2365
2366
2367
2368
# File 'lib/redis.rb', line 2364

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.



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

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.



2381
2382
2383
2384
2385
# File 'lib/redis.rb', line 2381

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.



2371
2372
2373
2374
2375
2376
2377
# File 'lib/redis.rb', line 2371

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, count = nil) ⇒ String+

Remove and get the last elements in a list.

Parameters:

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

    number of elements to remove

Returns:

  • (String, Array<String>)

    the values of the last elements



1193
1194
1195
1196
1197
1198
1199
# File 'lib/redis.rb', line 1193

def rpop(key, count = nil)
  synchronize do |client|
    command = [:rpop, key]
    command << count if count
    client.call(command)
  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



1206
1207
1208
1209
1210
# File 'lib/redis.rb', line 1206

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



1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
# File 'lib/redis.rb', line 1390

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



2679
2680
2681
# File 'lib/redis.rb', line 2679

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



2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
# File 'lib/redis.rb', line 2703

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)


1376
1377
1378
1379
1380
# File 'lib/redis.rb', line 1376

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:



2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
# File 'lib/redis.rb', line 2560

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



1493
1494
1495
1496
1497
# File 'lib/redis.rb', line 1493

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



1504
1505
1506
1507
1508
# File 'lib/redis.rb', line 1504

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



3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
# File 'lib/redis.rb', line 3278

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



1514
1515
1516
1517
1518
# File 'lib/redis.rb', line 1514

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



1525
1526
1527
1528
1529
# File 'lib/redis.rb', line 1525

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)


1473
1474
1475
1476
1477
# File 'lib/redis.rb', line 1473

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>)


1483
1484
1485
1486
1487
# File 'lib/redis.rb', line 1483

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)


1462
1463
1464
1465
1466
# File 'lib/redis.rb', line 1462

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)


1431
1432
1433
1434
1435
1436
1437
1438
1439
# File 'lib/redis.rb', line 1431

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)


1446
1447
1448
1449
1450
1451
1452
1453
1454
# File 'lib/redis.rb', line 1446

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



1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
# File 'lib/redis.rb', line 1412

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



2804
2805
2806
# File 'lib/redis.rb', line 2804

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



2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
# File 'lib/redis.rb', line 2819

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.



2332
2333
2334
2335
2336
# File 'lib/redis.rb', line 2332

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.



2340
2341
2342
2343
2344
# File 'lib/redis.rb', line 2340

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

#subscribed?Boolean

Returns:

  • (Boolean)


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

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



1535
1536
1537
1538
1539
# File 'lib/redis.rb', line 1535

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



1546
1547
1548
1549
1550
# File 'lib/redis.rb', line 1546

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.



2347
2348
2349
2350
2351
2352
2353
# File 'lib/redis.rb', line 2347

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:



2442
2443
2444
2445
2446
# File 'lib/redis.rb', line 2442

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:



2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
# File 'lib/redis.rb', line 2417

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



3193
3194
3195
3196
# File 'lib/redis.rb', line 3193

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



2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
# File 'lib/redis.rb', line 2993

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`



3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
# File 'lib/redis.rb', line 3230

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



3033
3034
3035
3036
# File 'lib/redis.rb', line 3033

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`



3141
3142
3143
3144
# File 'lib/redis.rb', line 3141

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`



2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
# File 'lib/redis.rb', line 2964

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



3092
3093
3094
# File 'lib/redis.rb', line 3092

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



3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
# File 'lib/redis.rb', line 3259

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



3055
3056
3057
3058
3059
# File 'lib/redis.rb', line 3055

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



3113
3114
3115
3116
3117
3118
# File 'lib/redis.rb', line 3113

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



3171
3172
3173
3174
3175
3176
3177
# File 'lib/redis.rb', line 3171

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



3078
3079
3080
3081
3082
# File 'lib/redis.rb', line 3078

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



3017
3018
3019
3020
# File 'lib/redis.rb', line 3017

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.



1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
# File 'lib/redis.rb', line 1597

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)


1560
1561
1562
1563
1564
# File 'lib/redis.rb', line 1560

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



2059
2060
2061
2062
2063
# File 'lib/redis.rb', line 2059

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



1627
1628
1629
1630
1631
# File 'lib/redis.rb', line 1627

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



2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
# File 'lib/redis.rb', line 2079

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



1878
1879
1880
1881
1882
# File 'lib/redis.rb', line 1878

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



1678
1679
1680
1681
1682
1683
# File 'lib/redis.rb', line 1678

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



1699
1700
1701
1702
1703
1704
# File 'lib/redis.rb', line 1699

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



1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
# File 'lib/redis.rb', line 1781

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]>)


1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
# File 'lib/redis.rb', line 1905

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



1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
# File 'lib/redis.rb', line 1969

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)


1823
1824
1825
1826
1827
# File 'lib/redis.rb', line 1823

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



1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
# File 'lib/redis.rb', line 1650

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



1854
1855
1856
1857
1858
# File 'lib/redis.rb', line 1854

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



2036
2037
2038
2039
2040
# File 'lib/redis.rb', line 2036

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:



1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
# File 'lib/redis.rb', line 1805

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:



1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
# File 'lib/redis.rb', line 1929

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:



2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
# File 'lib/redis.rb', line 2001

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)


1835
1836
1837
1838
1839
# File 'lib/redis.rb', line 1835

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



2765
2766
2767
2768
2769
# File 'lib/redis.rb', line 2765

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



2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
# File 'lib/redis.rb', line 2782

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



1757
1758
1759
1760
1761
# File 'lib/redis.rb', line 1757

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



2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
# File 'lib/redis.rb', line 2107

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