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/cluster/node_key.rb,
lib/redis/cluster/node_loader.rb,
lib/redis/cluster/slot_loader.rb,
lib/redis/cluster/command_loader.rb,
lib/redis/cluster/key_slot_converter.rb

Defined Under Namespace

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

Constant Summary collapse

VERSION =
'4.2.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://:[password]@[hostname]:[port]/[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

  • :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


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

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


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

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


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

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


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

def _client
  @client
end

#_eval(cmd, args) ⇒ Object


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

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

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

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

#_exists(*keys) ⇒ Object


593
594
595
596
597
# File 'lib/redis.rb', line 593

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

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


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

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

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

  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


1047
1048
1049
1050
1051
# File 'lib/redis.rb', line 1047

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:


3320
3321
3322
# File 'lib/redis.rb', line 3320

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

#auth(password) ⇒ String

Authenticate to the server.

Parameters:

  • password (String)

    must match the password specified in the requirepass directive in the configuration file

Returns:

  • (String)

    OK


149
150
151
152
153
# File 'lib/redis.rb', line 149

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

#bgrewriteaofString

Asynchronously rewrite the append-only file.

Returns:

  • (String)

    OK


203
204
205
206
207
# File 'lib/redis.rb', line 203

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

#bgsaveString

Asynchronously save the dataset to disk.

Returns:

  • (String)

    OK


212
213
214
215
216
# File 'lib/redis.rb', line 212

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


1059
1060
1061
1062
1063
# File 'lib/redis.rb', line 1059

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


1071
1072
1073
1074
1075
# File 'lib/redis.rb', line 1071

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)

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

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

1249
1250
1251
# File 'lib/redis.rb', line 1249

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:


1265
1266
1267
# File 'lib/redis.rb', line 1265

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

1280
1281
1282
1283
1284
1285
1286
# File 'lib/redis.rb', line 1280

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


1713
1714
1715
1716
1717
# File 'lib/redis.rb', line 1713

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


1734
1735
1736
1737
1738
# File 'lib/redis.rb', line 1734

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.


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

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


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

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.


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

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:


3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
# File 'lib/redis.rb', line 3292

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 http://redis.io/topics/pipelining for more details.


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

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


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

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)

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

def connected?
  @original_client.connected?
end

#connectionObject


3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
# File 'lib/redis.rb', line 3336

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)

257
258
259
260
261
# File 'lib/redis.rb', line 257

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

#debug(*args) ⇒ Object


263
264
265
266
267
# File 'lib/redis.rb', line 263

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


760
761
762
763
764
# File 'lib/redis.rb', line 760

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


775
776
777
778
779
# File 'lib/redis.rb', line 775

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


555
556
557
558
559
# File 'lib/redis.rb', line 555

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

#discardString

Discard all commands issued after MULTI.

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

Returns:

  • (String)

    "OK"

See Also:


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

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

#dump(key) ⇒ String

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

Parameters:

  • key (String)

Returns:

  • (String)

    serialized_value


502
503
504
505
506
# File 'lib/redis.rb', line 502

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

#dupObject


3332
3333
3334
# File 'lib/redis.rb', line 3332

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

#echo(value) ⇒ String

Echo the given string.

Parameters:

  • value (String)

Returns:

  • (String)

180
181
182
183
184
# File 'lib/redis.rb', line 180

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

#eval(*args) ⇒ Object

Evaluate Lua script.

Examples:

EVAL without KEYS nor ARGV

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

EVAL with KEYS and ARGV as array arguments

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

EVAL with KEYS and ARGV in a hash argument

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

Parameters:

  • keys (Array<String>)

    optional array with keys to pass to the script

  • argv (Array<String>)

    optional array with arguments to pass to the script

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

Returns:

  • depends on the script

See Also:


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

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

#evalsha(*args) ⇒ Object

Evaluate Lua script by its SHA.

Examples:

EVALSHA without KEYS nor ARGV

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

EVALSHA with KEYS and ARGV as array arguments

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

EVALSHA with KEYS and ARGV in a hash argument

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

Parameters:

  • keys (Array<String>)

    optional array with keys to pass to the script

  • argv (Array<String>)

    optional array with arguments to pass to the script

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

Returns:

  • depends on the script

See Also:


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

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

#execnil, Array<...>

Execute all commands issued after MULTI.

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

Returns:

  • (nil, Array<...>)
    • when commands were not executed, nil
    • when commands were executed, an array with their replies

See Also:


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

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

#exists(*keys) ⇒ Integer

Determine how many of the keys exists.

Parameters:

  • keys (String, Array<String>)

Returns:

  • (Integer)

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

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)

603
604
605
606
607
608
609
# File 'lib/redis.rb', line 603

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


424
425
426
427
428
# File 'lib/redis.rb', line 424

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


435
436
437
438
439
# File 'lib/redis.rb', line 435

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


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

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


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

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


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

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.


2926
2927
2928
2929
2930
# File 'lib/redis.rb', line 2926

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


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

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


2914
2915
2916
2917
2918
# File 'lib/redis.rb', line 2914

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


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

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


2900
2901
2902
2903
2904
2905
2906
# File 'lib/redis.rb', line 2900

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)

952
953
954
955
956
# File 'lib/redis.rb', line 952

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


1036
1037
1038
1039
1040
# File 'lib/redis.rb', line 1036

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


1013
1014
1015
1016
1017
# File 'lib/redis.rb', line 1013

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


1102
1103
1104
1105
1106
# File 'lib/redis.rb', line 1102

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


2239
2240
2241
2242
2243
# File 'lib/redis.rb', line 2239

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


2250
2251
2252
2253
2254
# File 'lib/redis.rb', line 2250

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)

2190
2191
2192
2193
2194
# File 'lib/redis.rb', line 2190

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

2304
2305
2306
2307
2308
# File 'lib/redis.rb', line 2304

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


2262
2263
2264
2265
2266
# File 'lib/redis.rb', line 2262

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


2274
2275
2276
2277
2278
# File 'lib/redis.rb', line 2274

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

2284
2285
2286
2287
2288
# File 'lib/redis.rb', line 2284

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


2118
2119
2120
2121
2122
# File 'lib/redis.rb', line 2118

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:


2207
2208
2209
2210
2211
# File 'lib/redis.rb', line 2207

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:


2164
2165
2166
2167
2168
# File 'lib/redis.rb', line 2164

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


2709
2710
2711
2712
2713
# File 'lib/redis.rb', line 2709

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


2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
# File 'lib/redis.rb', line 2726

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


2133
2134
2135
2136
2137
2138
2139
# File 'lib/redis.rb', line 2133

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


2147
2148
2149
2150
2151
# File 'lib/redis.rb', line 2147

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

2294
2295
2296
2297
2298
# File 'lib/redis.rb', line 2294

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

#idObject


3324
3325
3326
# File 'lib/redis.rb', line 3324

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


789
790
791
792
793
# File 'lib/redis.rb', line 789

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


804
805
806
807
808
# File 'lib/redis.rb', line 804

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


819
820
821
822
823
# File 'lib/redis.rb', line 819

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

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

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


3328
3329
3330
# File 'lib/redis.rb', line 3328

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

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

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)

326
327
328
329
330
# File 'lib/redis.rb', line 326

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)

1293
1294
1295
1296
1297
# File 'lib/redis.rb', line 1293

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


1307
1308
1309
1310
1311
# File 'lib/redis.rb', line 1307

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)

1123
1124
1125
1126
1127
# File 'lib/redis.rb', line 1123

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

#lpop(key) ⇒ String

Remove and get the first element in a list.

Parameters:

  • key (String)

Returns:

  • (String)

1177
1178
1179
1180
1181
# File 'lib/redis.rb', line 1177

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

#lpush(key, value) ⇒ Integer

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

Parameters:

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

    string value, or array of string values to push

Returns:

  • (Integer)

    the length of the list after the push operation


1134
1135
1136
1137
1138
# File 'lib/redis.rb', line 1134

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


1145
1146
1147
1148
1149
# File 'lib/redis.rb', line 1145

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

1319
1320
1321
1322
1323
# File 'lib/redis.rb', line 1319

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


1334
1335
1336
1337
1338
# File 'lib/redis.rb', line 1334

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


1346
1347
1348
1349
1350
# File 'lib/redis.rb', line 1346

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


1358
1359
1360
1361
1362
# File 'lib/redis.rb', line 1358

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:


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

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:


2181
2182
2183
# File 'lib/redis.rb', line 2181

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:


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

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:


914
915
916
# File 'lib/redis.rb', line 914

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:


944
945
946
# File 'lib/redis.rb', line 944

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:


968
969
970
971
972
# File 'lib/redis.rb', line 968

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"


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

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


338
339
340
341
342
# File 'lib/redis.rb', line 338

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


646
647
648
649
650
# File 'lib/redis.rb', line 646

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:


898
899
900
901
902
# File 'lib/redis.rb', line 898

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:


928
929
930
931
932
# File 'lib/redis.rb', line 928

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:

Returns:

  • (String, Array<...>)
    • when a block is not given, OK
    • when a block is given, an array with replies

See Also:


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

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

#object(*args) ⇒ Object


652
653
654
655
656
# File 'lib/redis.rb', line 652

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


413
414
415
416
417
# File 'lib/redis.rb', line 413

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


464
465
466
467
468
# File 'lib/redis.rb', line 464

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


475
476
477
478
479
# File 'lib/redis.rb', line 475

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.


2819
2820
2821
2822
2823
# File 'lib/redis.rb', line 2819

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)

2832
2833
2834
2835
2836
# File 'lib/redis.rb', line 2832

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)

2844
2845
2846
2847
2848
# File 'lib/redis.rb', line 2844

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


170
171
172
173
174
# File 'lib/redis.rb', line 170

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

#pipelinedObject


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

def pipelined
  synchronize do |_client|
    begin
      pipeline = Pipeline.new(@client)
      original, @client = @client, pipeline
      yield(self)
      original.call_pipeline(@client)
    ensure
      @client = original
    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"


871
872
873
874
875
# File 'lib/redis.rb', line 871

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.


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

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.


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

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


492
493
494
495
496
# File 'lib/redis.rb', line 492

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

#publish(channel, message) ⇒ Object

Post a message to a channel.


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

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.


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

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.


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

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 http://redis.io/topics/pipelining for more details.


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

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

#quitString

Close the connection.

Returns:

  • (String)

    OK


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

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)

661
662
663
664
665
# File 'lib/redis.rb', line 661

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


672
673
674
675
676
# File 'lib/redis.rb', line 672

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


683
684
685
686
687
# File 'lib/redis.rb', line 683

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:


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

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

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

#rpop(key) ⇒ String

Remove and get the last element in a list.

Parameters:

  • key (String)

Returns:

  • (String)

1187
1188
1189
1190
1191
# File 'lib/redis.rb', line 1187

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

#rpoplpush(source, destination) ⇒ nil, String

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

Parameters:

  • source (String)

    source key

  • destination (String)

    destination key

Returns:

  • (nil, String)

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


1198
1199
1200
1201
1202
# File 'lib/redis.rb', line 1198

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


1156
1157
1158
1159
1160
# File 'lib/redis.rb', line 1156

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


1167
1168
1169
1170
1171
# File 'lib/redis.rb', line 1167

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


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

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)

347
348
349
350
351
# File 'lib/redis.rb', line 347

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

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 keys


2668
2669
2670
# File 'lib/redis.rb', line 2668

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

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


2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
# File 'lib/redis.rb', line 2687

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)

1368
1369
1370
1371
1372
# File 'lib/redis.rb', line 1368

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

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

Control remote script registry.

Examples:

Load a script

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

Check if a script exists

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

Check if multiple scripts exist

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

Flush the script registry

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

Kill a running script

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

Parameters:

  • subcommand (String)

    e.g. exists, flush, load, kill

  • args (Array<String>)

    depends on subcommand

Returns:

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

    depends on subcommand

See Also:


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

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

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

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

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

#sdiff(*keys) ⇒ Array<String>

Subtract multiple sets.

Parameters:

  • keys (String, Array<String>)

    keys pointing to sets to subtract

Returns:

  • (Array<String>)

    members in the difference


1485
1486
1487
1488
1489
# File 'lib/redis.rb', line 1485

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


1496
1497
1498
1499
1500
# File 'lib/redis.rb', line 1496

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


159
160
161
162
163
164
# File 'lib/redis.rb', line 159

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


3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
# File 'lib/redis.rb', line 3262

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


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

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


1025
1026
1027
1028
1029
# File 'lib/redis.rb', line 1025

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"


859
860
861
862
863
# File 'lib/redis.rb', line 859

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


882
883
884
885
886
# File 'lib/redis.rb', line 882

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


1000
1001
1002
1003
1004
# File 'lib/redis.rb', line 1000

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.


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

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


1506
1507
1508
1509
1510
# File 'lib/redis.rb', line 1506

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


1517
1518
1519
1520
1521
# File 'lib/redis.rb', line 1517

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)

1465
1466
1467
1468
1469
# File 'lib/redis.rb', line 1465

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.


368
369
370
371
372
# File 'lib/redis.rb', line 368

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


379
380
381
382
383
384
385
# File 'lib/redis.rb', line 379

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

1475
1476
1477
1478
1479
# File 'lib/redis.rb', line 1475

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)

1454
1455
1456
1457
1458
# File 'lib/redis.rb', line 1454

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

714
715
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
# File 'lib/redis.rb', line 714

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)

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

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)

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

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


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

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


2788
2789
2790
# File 'lib/redis.rb', line 2788

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


2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
# File 'lib/redis.rb', line 2803

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


1113
1114
1115
1116
1117
# File 'lib/redis.rb', line 1113

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

#subscribe(*channels, &block) ⇒ Object

Listen for messages published to the given channels.


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

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.


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

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

#subscribed?Boolean

Returns:

  • (Boolean)

2317
2318
2319
2320
2321
# File 'lib/redis.rb', line 2317

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


1527
1528
1529
1530
1531
# File 'lib/redis.rb', line 1527

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


1538
1539
1540
1541
1542
# File 'lib/redis.rb', line 1538

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

#syncObject

Internal command used for replication.


388
389
390
391
392
# File 'lib/redis.rb', line 388

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

#synchronizeObject


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

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


401
402
403
404
405
406
407
# File 'lib/redis.rb', line 401

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.


453
454
455
456
457
# File 'lib/redis.rb', line 453

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


746
747
748
749
750
# File 'lib/redis.rb', line 746

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


565
566
567
568
569
# File 'lib/redis.rb', line 565

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

#unsubscribe(*channels) ⇒ Object

Stop listening for messages posted to the given channels.


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

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:


2434
2435
2436
2437
2438
# File 'lib/redis.rb', line 2434

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:


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

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


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

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


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

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


3177
3178
3179
3180
# File 'lib/redis.rb', line 3177

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


2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
# File 'lib/redis.rb', line 2977

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


3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
# File 'lib/redis.rb', line 3214

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


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

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


3125
3126
3127
3128
# File 'lib/redis.rb', line 3125

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


2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
# File 'lib/redis.rb', line 2948

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


3076
3077
3078
# File 'lib/redis.rb', line 3076

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


3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
# File 'lib/redis.rb', line 3243

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


3039
3040
3041
3042
3043
# File 'lib/redis.rb', line 3039

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


3097
3098
3099
3100
3101
3102
# File 'lib/redis.rb', line 3097

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


3155
3156
3157
3158
3159
3160
3161
# File 'lib/redis.rb', line 3155

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


3062
3063
3064
3065
3066
# File 'lib/redis.rb', line 3062

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


3001
3002
3003
3004
# File 'lib/redis.rb', line 3001

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.

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

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)

1552
1553
1554
1555
1556
# File 'lib/redis.rb', line 1552

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


2051
2052
2053
2054
2055
# File 'lib/redis.rb', line 2051

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


1619
1620
1621
1622
1623
# File 'lib/redis.rb', line 1619

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


2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
# File 'lib/redis.rb', line 2071

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


1870
1871
1872
1873
1874
# File 'lib/redis.rb', line 1870

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


1670
1671
1672
1673
1674
1675
# File 'lib/redis.rb', line 1670

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


1691
1692
1693
1694
1695
1696
# File 'lib/redis.rb', line 1691

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

1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
# File 'lib/redis.rb', line 1773

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

1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
# File 'lib/redis.rb', line 1897

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

1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
# File 'lib/redis.rb', line 1961

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)

1815
1816
1817
1818
1819
# File 'lib/redis.rb', line 1815

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

1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
# File 'lib/redis.rb', line 1642

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


1846
1847
1848
1849
1850
# File 'lib/redis.rb', line 1846

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


2028
2029
2030
2031
2032
# File 'lib/redis.rb', line 2028

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:


1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
# File 'lib/redis.rb', line 1797

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:


1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
# File 'lib/redis.rb', line 1921

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:


1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
# File 'lib/redis.rb', line 1993

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)

1827
1828
1829
1830
1831
# File 'lib/redis.rb', line 1827

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


2749
2750
2751
2752
2753
# File 'lib/redis.rb', line 2749

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


2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
# File 'lib/redis.rb', line 2766

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


1749
1750
1751
1752
1753
# File 'lib/redis.rb', line 1749

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


2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
# File 'lib/redis.rb', line 2099

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