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

Class Method 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 (Fixnum) — 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 (Fixnum) — 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, Fixnum)

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

  • :reconnect_attempts (Fixnum)

    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



41
42
43
44
45
46
47
48
49
# File 'lib/redis.rb', line 41

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



3309
3310
3311
3312
3313
# File 'lib/redis.rb', line 3309

def method_missing(command, *args)
  synchronize do |client|
    client.call([command] + args)
  end
end

Class Method Details

.currentObject



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

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

.current=(redis) ⇒ Object



12
13
14
# File 'lib/redis.rb', line 12

def self.current=(redis)
  @current = redis
end

Instance Method Details

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



1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
# File 'lib/redis.rb', line 1166

def _bpop(cmd, args, &blk)
  options = {}

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

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

  keys = args.flatten
  timeout = options[:timeout] || 0

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

#_clientObject



121
122
123
# File 'lib/redis.rb', line 121

def _client
  @client
end

#_eval(cmd, args) ⇒ Object



2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
# File 'lib/redis.rb', line 2548

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

#_scan(command, cursor, args, options = {}, &block) ⇒ Object



2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
# File 'lib/redis.rb', line 2611

def _scan(command, cursor, args, options = {}, &block)
  # SSCAN/ZSCAN/HSCAN already prepend the key to +args+.

  args << cursor

  if match = options[:match]
    args.concat(["MATCH", match])
  end

  if count = options[:count]
    args.concat(["COUNT", count])
  end

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

#append(key, value) ⇒ Fixnum

Append a value to a key.

Parameters:

  • key (String)
  • value (String)

    value to append

Returns:

  • (Fixnum)

    length of the string after appending



1007
1008
1009
1010
1011
# File 'lib/redis.rb', line 1007

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:



3281
3282
3283
# File 'lib/redis.rb', line 3281

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



130
131
132
133
134
# File 'lib/redis.rb', line 130

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

#bgrewriteaofString

Asynchronously rewrite the append-only file.

Returns:

  • (String)

    OK



184
185
186
187
188
# File 'lib/redis.rb', line 184

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

#bgsaveString

Asynchronously save the dataset to disk.

Returns:

  • (String)

    OK



193
194
195
196
197
# File 'lib/redis.rb', line 193

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

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

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

Parameters:

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

    start index

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

    stop index

Returns:

  • (Fixnum)

    the number of bits set to 1



1019
1020
1021
1022
1023
# File 'lib/redis.rb', line 1019

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

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

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:

  • (Fixnum)

    the length of the string stored in destkey



1031
1032
1033
1034
1035
# File 'lib/redis.rb', line 1031

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

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

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

Parameters:

  • key (String)
  • bit (Fixnum)

    whether to look for the first 1 or 0 bit

  • start (Fixnum) (defaults to: nil)

    start index

  • stop (Fixnum) (defaults to: nil)

    stop index

Returns:

  • (Fixnum)

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



1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
# File 'lib/redis.rb', line 1045

def bitpos(key, bit, start=nil, stop=nil)
  if stop and not start
    raise(ArgumentError, 'stop parameter specified without start parameter')
  end

  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 => Fixnum: 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


1211
1212
1213
# File 'lib/redis.rb', line 1211

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 => Fixnum: 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:



1227
1228
1229
# File 'lib/redis.rb', line 1227

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

#brpoplpush(source, destination, options = {}) ⇒ 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) (defaults to: {})
    • :timeout => Fixnum: timeout in seconds, defaults to no timeout

Returns:

  • (nil, String)
    • nil when the operation timed out
    • the element was popped and pushed otherwise


1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
# File 'lib/redis.rb', line 1242

def brpoplpush(source, destination, options = {})
  case options
  when Integer
    # Issue deprecation notice in obnoxious mode...
    options = { :timeout => options }
  end

  timeout = options[:timeout] || 0

  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



1694
1695
1696
1697
1698
# File 'lib/redis.rb', line 1694

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



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

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.



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

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



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

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.



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

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:



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

def cluster(subcommand, *args)
  subcommand = subcommand.to_s.downcase
  block = case subcommand
          when 'slots'  then HashifyClusterSlots
          when 'nodes'  then HashifyClusterNodes
          when 'slaves' then HashifyClusterSlaves
          when 'info'   then 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.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/redis.rb', line 106

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



204
205
206
207
208
209
210
211
212
213
214
# File 'lib/redis.rb', line 204

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

#connected?Boolean

Test whether or not the client is connected

Returns:

  • (Boolean)


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

def connected?
  @original_client.connected?
end

#connectionObject



3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
# File 'lib/redis.rb', line 3297

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

#dbsizeFixnum

Return the number of keys in the selected database.

Returns:

  • (Fixnum)


238
239
240
241
242
# File 'lib/redis.rb', line 238

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

#debug(*args) ⇒ Object



244
245
246
247
248
# File 'lib/redis.rb', line 244

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

#decr(key) ⇒ Fixnum

Decrement the integer value of a key by one.

Examples:

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

Parameters:

  • key (String)

Returns:

  • (Fixnum)

    value after decrementing it



714
715
716
717
718
# File 'lib/redis.rb', line 714

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

#decrby(key, decrement) ⇒ Fixnum

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

Examples:

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

Parameters:

  • key (String)
  • decrement (Fixnum)

Returns:

  • (Fixnum)

    value after decrementing it



729
730
731
732
733
# File 'lib/redis.rb', line 729

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

#del(*keys) ⇒ Fixnum

Delete one or more keys.

Parameters:

  • keys (String, Array<String>)

Returns:

  • (Fixnum)

    number of keys that were deleted



536
537
538
539
540
# File 'lib/redis.rb', line 536

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:



2494
2495
2496
2497
2498
# File 'lib/redis.rb', line 2494

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



483
484
485
486
487
# File 'lib/redis.rb', line 483

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

#dupObject



3293
3294
3295
# File 'lib/redis.rb', line 3293

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

#echo(value) ⇒ String

Echo the given string.

Parameters:

  • value (String)

Returns:

  • (String)


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

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:



2582
2583
2584
# File 'lib/redis.rb', line 2582

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:



2607
2608
2609
# File 'lib/redis.rb', line 2607

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:



2480
2481
2482
2483
2484
# File 'lib/redis.rb', line 2480

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

#exists(key) ⇒ Boolean

Determine if a key exists.

Parameters:

  • key (String)

Returns:

  • (Boolean)


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

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

#expire(key, seconds) ⇒ Boolean

Set a key's time to live in seconds.

Parameters:

  • key (String)
  • seconds (Fixnum)

    time to live

Returns:

  • (Boolean)

    whether the timeout was set or not



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

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

    expiry time specified as a UNIX timestamp

Returns:

  • (Boolean)

    whether the timeout was set or not



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

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



255
256
257
258
259
260
261
262
263
# File 'lib/redis.rb', line 255

def flushall(options = nil)
  synchronize do |client|
    if options && options[:async]
      client.call([: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



270
271
272
273
274
275
276
277
278
# File 'lib/redis.rb', line 270

def flushdb(options = nil)
  synchronize do |client|
    if options && options[:async]
      client.call([: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



2827
2828
2829
2830
2831
# File 'lib/redis.rb', line 2827

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.



2896
2897
2898
2899
2900
# File 'lib/redis.rb', line 2896

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



2838
2839
2840
2841
2842
# File 'lib/redis.rb', line 2838

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



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

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



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

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



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

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)


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

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

#getbit(key, offset) ⇒ Fixnum

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

Parameters:

  • key (String)
  • offset (Fixnum)

    bit offset

Returns:

  • (Fixnum)

    0 or 1



996
997
998
999
1000
# File 'lib/redis.rb', line 996

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

#getrange(key, start, stop) ⇒ Fixnum

Get a substring of the string stored at a key.

Parameters:

  • key (String)
  • start (Fixnum)

    zero-based start offset

  • stop (Fixnum)

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

Returns:

  • (Fixnum)

    0 or 1



973
974
975
976
977
# File 'lib/redis.rb', line 973

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



1064
1065
1066
1067
1068
# File 'lib/redis.rb', line 1064

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

#hdel(key, *fields) ⇒ Fixnum

Delete one or more hash fields.

Parameters:

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

Returns:

  • (Fixnum)

    the number of fields that were removed from the hash



2213
2214
2215
2216
2217
# File 'lib/redis.rb', line 2213

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



2224
2225
2226
2227
2228
# File 'lib/redis.rb', line 2224

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)


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

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


2278
2279
2280
2281
2282
# File 'lib/redis.rb', line 2278

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

#hincrby(key, field, increment) ⇒ Fixnum

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

Parameters:

  • key (String)
  • field (String)
  • increment (Fixnum)

Returns:

  • (Fixnum)

    value of the field after incrementing it



2236
2237
2238
2239
2240
# File 'lib/redis.rb', line 2236

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



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

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


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

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

#hlen(key) ⇒ Fixnum

Get the number of fields in a hash.

Parameters:

  • key (String)

Returns:

  • (Fixnum)

    number of fields in the hash



2097
2098
2099
2100
2101
# File 'lib/redis.rb', line 2097

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:



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

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:



2138
2139
2140
2141
2142
# File 'lib/redis.rb', line 2138

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) (defaults to: {})
    • :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



2684
2685
2686
2687
2688
# File 'lib/redis.rb', line 2684

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) (defaults to: {})
    • :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



2701
2702
2703
2704
2705
2706
2707
2708
2709
# File 'lib/redis.rb', line 2701

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, field, value) ⇒ Boolean

Set the string value of a hash field.

Parameters:

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

Returns:

  • (Boolean)

    whether or not the field was added to the hash



2109
2110
2111
2112
2113
# File 'lib/redis.rb', line 2109

def hset(key, field, value)
  synchronize do |client|
    client.call([:hset, key, field, value], &Boolify)
  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



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

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


2268
2269
2270
2271
2272
# File 'lib/redis.rb', line 2268

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

#idObject



3285
3286
3287
# File 'lib/redis.rb', line 3285

def id
  @original_client.id
end

#incr(key) ⇒ Fixnum

Increment the integer value of a key by one.

Examples:

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

Parameters:

  • key (String)

Returns:

  • (Fixnum)

    value after incrementing it



743
744
745
746
747
# File 'lib/redis.rb', line 743

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

#incrby(key, increment) ⇒ Fixnum

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

Examples:

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

Parameters:

  • key (String)
  • increment (Fixnum)

Returns:

  • (Fixnum)

    value after incrementing it



758
759
760
761
762
# File 'lib/redis.rb', line 758

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



773
774
775
776
777
# File 'lib/redis.rb', line 773

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


284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/redis.rb', line 284

def info(cmd = nil)
  synchronize do |client|
    client.call([:info, cmd].compact) do |reply|
      if reply.kind_of?(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



3289
3290
3291
# File 'lib/redis.rb', line 3289

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


566
567
568
569
570
571
572
573
574
575
576
# File 'lib/redis.rb', line 566

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

#lastsaveFixnum

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

Returns:

  • (Fixnum)


307
308
309
310
311
# File 'lib/redis.rb', line 307

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

Returns:

  • (String)


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

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

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

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:

  • (Fixnum)

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



1277
1278
1279
1280
1281
# File 'lib/redis.rb', line 1277

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

#llen(key) ⇒ Fixnum

Get the length of a list.

Parameters:

  • key (String)

Returns:

  • (Fixnum)


1085
1086
1087
1088
1089
# File 'lib/redis.rb', line 1085

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)


1139
1140
1141
1142
1143
# File 'lib/redis.rb', line 1139

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

#lpush(key, value) ⇒ Fixnum

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:

  • (Fixnum)

    the length of the list after the push operation



1096
1097
1098
1099
1100
# File 'lib/redis.rb', line 1096

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

#lpushx(key, value) ⇒ Fixnum

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

Parameters:

  • key (String)
  • value (String)

Returns:

  • (Fixnum)

    the length of the list after the push operation



1107
1108
1109
1110
1111
# File 'lib/redis.rb', line 1107

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

    start index

  • stop (Fixnum)

    stop index

Returns:

  • (Array<String>)


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

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

#lrem(key, count, value) ⇒ Fixnum

Remove elements from a list.

Parameters:

  • key (String)
  • count (Fixnum)

    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:

  • (Fixnum)

    the number of removed elements



1304
1305
1306
1307
1308
# File 'lib/redis.rb', line 1304

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 (Fixnum)
  • value (String)

Returns:

  • (String)

    OK



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

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

    start index

  • stop (Fixnum)

    stop index

Returns:

  • (String)

    OK



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

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:



2198
2199
2200
2201
2202
2203
2204
2205
2206
# File 'lib/redis.rb', line 2198

def mapped_hmget(key, *fields)
  hmget(key, *fields) do |reply|
    if reply.kind_of?(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:



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

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:



944
945
946
947
948
949
950
951
952
# File 'lib/redis.rb', line 944

def mapped_mget(*keys)
  mget(*keys) do |reply|
    if reply.kind_of?(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:



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

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:



904
905
906
# File 'lib/redis.rb', line 904

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", "key1")
  # => ["v1", "v2"]

Parameters:

  • keys (Array<String>)

Returns:

  • (Array<String>)

    an array of values for the specified keys

See Also:



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

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"



518
519
520
521
522
523
524
525
526
527
528
529
530
# File 'lib/redis.rb', line 518

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



319
320
321
322
323
# File 'lib/redis.rb', line 319

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

Returns:

  • (Boolean)

    whether the key was moved or not



597
598
599
600
601
# File 'lib/redis.rb', line 597

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:



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

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:



888
889
890
891
892
# File 'lib/redis.rb', line 888

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:



2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
# File 'lib/redis.rb', line 2453

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



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

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



394
395
396
397
398
# File 'lib/redis.rb', line 394

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

    time to live

Returns:

  • (Boolean)

    whether the timeout was set or not



445
446
447
448
449
# File 'lib/redis.rb', line 445

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

    expiry time specified as number of milliseconds from UNIX Epoch.

Returns:

  • (Boolean)

    whether the timeout was set or not



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

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.



2791
2792
2793
2794
2795
# File 'lib/redis.rb', line 2791

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

#pfcount(*keys) ⇒ Fixnum

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:

  • (Fixnum)


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

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)


2816
2817
2818
2819
2820
# File 'lib/redis.rb', line 2816

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



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

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

#pipelinedObject



2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
# File 'lib/redis.rb', line 2410

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 (Fixnum)
  • value (String)

Returns:

  • (String)

    "OK"



831
832
833
834
835
# File 'lib/redis.rb', line 831

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.



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

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.



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

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

#pttl(key) ⇒ Fixnum

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:

  • (Fixnum)

    remaining time to live in milliseconds



473
474
475
476
477
# File 'lib/redis.rb', line 473

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

#publish(channel, message) ⇒ Object

Post a message to a channel.



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

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.



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

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.



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

def punsubscribe(*channels)
  synchronize do |client|
    raise RuntimeError, "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.



98
99
100
# File 'lib/redis.rb', line 98

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

#quitString

Close the connection.

Returns:

  • (String)

    OK



170
171
172
173
174
175
176
177
178
179
# File 'lib/redis.rb', line 170

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)


612
613
614
615
616
# File 'lib/redis.rb', line 612

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



623
624
625
626
627
# File 'lib/redis.rb', line 623

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



634
635
636
637
638
# File 'lib/redis.rb', line 634

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

#restore(key, ttl, serialized_value, options = {}) ⇒ String

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

Parameters:

  • key (String)
  • ttl (String)
  • serialized_value (String)
  • options (Hash) (defaults to: {})
    • :replace => Boolean: if false, raises an error if key already exists

Returns:

  • (String)

    "OK"

Raises:



498
499
500
501
502
503
504
505
# File 'lib/redis.rb', line 498

def restore(key, ttl, serialized_value, options = {})
  args = [:restore, key, ttl, serialized_value]
  args << 'REPLACE' if options[: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)


1149
1150
1151
1152
1153
# File 'lib/redis.rb', line 1149

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



1160
1161
1162
1163
1164
# File 'lib/redis.rb', line 1160

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

#rpush(key, value) ⇒ Fixnum

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:

  • (Fixnum)

    the length of the list after the push operation



1118
1119
1120
1121
1122
# File 'lib/redis.rb', line 1118

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

#rpushx(key, value) ⇒ Fixnum

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

Parameters:

  • key (String)
  • value (String)

Returns:

  • (Fixnum)

    the length of the list after the push operation



1129
1130
1131
1132
1133
# File 'lib/redis.rb', line 1129

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

#sadd(key, member) ⇒ Boolean, Fixnum

Add one or more members to a set.

Parameters:

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

    one member, or array of members

Returns:

  • (Boolean, Fixnum)

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



1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
# File 'lib/redis.rb', line 1352

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)


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

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) (defaults to: {})
    • :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



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

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) (defaults to: {})
    • :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



2663
2664
2665
2666
2667
2668
2669
2670
2671
# File 'lib/redis.rb', line 2663

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

Get the number of members in a set.

Parameters:

  • key (String)

Returns:

  • (Fixnum)


1338
1339
1340
1341
1342
# File 'lib/redis.rb', line 1338

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:



2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
# File 'lib/redis.rb', line 2524

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



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

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

#sdiffstore(destination, *keys) ⇒ Fixnum

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:

  • (Fixnum)

    number of elements in the resulting set



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

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

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

Returns:

  • (String)

    OK



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

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



3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
# File 'lib/redis.rb', line 3228

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.kind_of?(Array)
          if reply[0].kind_of?(Array)
            reply.map(&Hashify)
          else
            Hashify.call(reply)
          end
        else
          reply
        end
      end
    end
  end
end

#set(key, value, options = {}) ⇒ String, Boolean

Set the string value of a key.

Parameters:

  • key (String)
  • value (String)
  • options (Hash) (defaults to: {})
    • :ex => Fixnum: Set the specified expire time, in seconds.
    • :px => Fixnum: 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.

Returns:

  • (String, Boolean)

    "OK" or true, false if :nx => true or :xx => true



789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
# File 'lib/redis.rb', line 789

def set(key, value, options = {})
  args = []

  ex = options[:ex]
  args.concat(["EX", ex]) if ex

  px = options[:px]
  args.concat(["PX", px]) if px

  nx = options[:nx]
  args.concat(["NX"]) if nx

  xx = options[:xx]
  args.concat(["XX"]) if xx

  synchronize do |client|
    if nx || xx
      client.call([:set, key, value.to_s] + args, &BoolifySet)
    else
      client.call([:set, key, value.to_s] + args)
    end
  end
end

#setbit(key, offset, value) ⇒ Fixnum

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

Parameters:

  • key (String)
  • offset (Fixnum)

    bit offset

  • value (Fixnum)

    bit value 0 or 1

Returns:

  • (Fixnum)

    the original bit value stored at offset



985
986
987
988
989
# File 'lib/redis.rb', line 985

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 (Fixnum)
  • value (String)

Returns:

  • (String)

    "OK"



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

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



842
843
844
845
846
# File 'lib/redis.rb', line 842

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

#setrange(key, offset, value) ⇒ Fixnum

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

Parameters:

  • key (String)
  • offset (Fixnum)

    byte offset

  • value (String)

Returns:

  • (Fixnum)

    length of the string after it was modified



960
961
962
963
964
# File 'lib/redis.rb', line 960

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.



335
336
337
338
339
340
341
342
343
344
345
346
# File 'lib/redis.rb', line 335

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



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

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

#sinterstore(destination, *keys) ⇒ Fixnum

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:

  • (Fixnum)

    number of elements in the resulting set



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

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)


1435
1436
1437
1438
1439
# File 'lib/redis.rb', line 1435

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.



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

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 (Fixnum) (defaults to: nil)

    maximum number of entries to return

Returns:

  • (Array<String>, Fixnum, String)

    depends on subcommand



360
361
362
363
364
365
366
# File 'lib/redis.rb', line 360

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


1445
1446
1447
1448
1449
# File 'lib/redis.rb', line 1445

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)


1424
1425
1426
1427
1428
# File 'lib/redis.rb', line 1424

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

#sort(key, options = {}) ⇒ 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) (defaults to: {})
    • :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>>, Fixnum)
    • 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


665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
# File 'lib/redis.rb', line 665

def sort(key, options = {})
  args = []

  by = options[:by]
  args.concat(["BY", by]) if by

  limit = options[:limit]
  args.concat(["LIMIT"] + limit) if limit

  get = Array(options[:get])
  args.concat(["GET"].product(get).flatten) unless get.empty?

  order = options[:order]
  args.concat(order.split(" ")) if order

  store = options[:store]
  args.concat(["STORE", store]) if store

  synchronize do |client|
    client.call([:sort, key] + args) do |reply|
      if get.size > 1 && !store
        if reply
          reply.each_slice(get.size).to_a
        end
      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 (Fixnum) (defaults to: nil)

Returns:

  • (String)


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

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 (Fixnum) (defaults to: nil)

Returns:

  • (String)


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

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, Fixnum

Remove one or more members from a set.

Parameters:

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

    one member, or array of members

Returns:

  • (Boolean, Fixnum)

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



1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
# File 'lib/redis.rb', line 1374

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) (defaults to: {})
    • :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



2761
2762
2763
# File 'lib/redis.rb', line 2761

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) (defaults to: {})
    • :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



2776
2777
2778
2779
2780
2781
2782
2783
2784
# File 'lib/redis.rb', line 2776

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

Get the length of the value stored in a key.

Parameters:

  • key (String)

Returns:

  • (Fixnum)

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



1075
1076
1077
1078
1079
# File 'lib/redis.rb', line 1075

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

#subscribe(*channels, &block) ⇒ Object

Listen for messages published to the given channels.



2298
2299
2300
2301
2302
# File 'lib/redis.rb', line 2298

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.



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

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

#subscribed?Boolean

Returns:

  • (Boolean)


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

def subscribed?
  synchronize do |client|
    client.kind_of? 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



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

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

#sunionstore(destination, *keys) ⇒ Fixnum

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:

  • (Fixnum)

    number of elements in the resulting set



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

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

#syncObject

Internal command used for replication.



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

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

#synchronizeObject



51
52
53
# File 'lib/redis.rb', line 51

def synchronize
  mon_synchronize { yield(@client) }
end

#timeArray<Fixnum>

Return the server time.

Examples:

r.time # => [ 1333093196, 606806 ]

Returns:

  • (Array<Fixnum>)

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



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

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

#ttl(key) ⇒ Fixnum

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:

  • (Fixnum)

    remaining time to live in seconds.



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

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



700
701
702
703
704
# File 'lib/redis.rb', line 700

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

Unlink one or more keys.

Parameters:

  • keys (String, Array<String>)

Returns:

  • (Fixnum)

    number of keys that were unlinked



546
547
548
549
550
# File 'lib/redis.rb', line 546

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

#unsubscribe(*channels) ⇒ Object

Stop listening for messages posted to the given channels.



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

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

#unwatchString

Forget about all watched keys.

Returns:

  • (String)

    OK

See Also:



2404
2405
2406
2407
2408
# File 'lib/redis.rb', line 2404

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:



2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
# File 'lib/redis.rb', line 2379

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



56
57
58
59
60
# File 'lib/redis.rb', line 56

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



63
64
65
# File 'lib/redis.rb', line 63

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



3143
3144
3145
3146
# File 'lib/redis.rb', line 3143

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

#xadd(key, entry, opts = {}) ⇒ 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) (defaults to: {})

    several options for XADD command

Options Hash (opts):

  • :id (String)

    the entry id, default value is *, it means auto generation

  • :maxlen (Integer)

    max length of entries

  • :approximate (Boolean)

    whether to add ~ modifier of maxlen or not

Returns:

  • (String)

    the entry id



2947
2948
2949
2950
2951
2952
2953
# File 'lib/redis.rb', line 2947

def xadd(key, entry, opts = {})
  args = [:xadd, key]
  args.concat(['MAXLEN', (opts[:approximate] ? '~' : nil), opts[:maxlen]].compact) if opts[:maxlen]
  args << (opts[: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



3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
# File 'lib/redis.rb', line 3180

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



2983
2984
2985
2986
# File 'lib/redis.rb', line 2983

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)

    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



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

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



2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
# File 'lib/redis.rb', line 2918

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



3042
3043
3044
# File 'lib/redis.rb', line 3042

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



3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
# File 'lib/redis.rb', line 3209

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 = '-', _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)

    the number of entries as limit

Returns:

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

    the ids and entries pairs



3005
3006
3007
3008
3009
# File 'lib/redis.rb', line 3005

def xrange(key, start = '-', _end = '+', count: nil)
  args = [:xrange, key, start, _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)

    the number of entries as limit per stream

  • block (Integer)

    the number of milliseconds as blocking timeout

Returns:

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

    the entries



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

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, opts = {}) ⇒ 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) (defaults to: {})

    several options for XREADGROUP command

Options Hash (opts):

  • :count (Integer)

    the number of entries as limit

  • :block (Integer)

    the number of milliseconds as blocking timeout

  • :noack (Boolean)

    whether message loss is acceptable or not

Returns:

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

    the entries



3121
3122
3123
3124
3125
3126
3127
# File 'lib/redis.rb', line 3121

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

#xrevrange(key, _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



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

def xrevrange(key, _end = '+', start = '-', count: nil)
  args = [:xrevrange, key, _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)

    whether to add ~ modifier of maxlen or not

Returns:

  • (Integer)

    the number of entries actually deleted



2967
2968
2969
2970
# File 'lib/redis.rb', line 2967

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

#zadd(key, *args) ⇒ 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, Fixnum, Float)
    • Boolean when a single pair is specified, holding whether or not it was added to the sorted set.
    • Fixnum 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.


1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
# File 'lib/redis.rb', line 1559

def zadd(key, *args) #, options
  zadd_options = []
  if args.last.is_a?(Hash)
    options = args.pop

    nx = options[:nx]
    zadd_options << "NX" if nx

    xx = options[:xx]
    zadd_options << "XX" if xx

    ch = options[:ch]
    zadd_options << "CH" if ch

    incr = options[:incr]
    zadd_options << "INCR" if incr
  end

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

#zcard(key) ⇒ Fixnum

Get the number of members in a sorted set.

Examples:

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

Parameters:

  • key (String)

Returns:

  • (Fixnum)


1522
1523
1524
1525
1526
# File 'lib/redis.rb', line 1522

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

#zcount(key, min, max) ⇒ Fixnum

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:

  • (Fixnum)

    number of members in within the specified range



2032
2033
2034
2035
2036
# File 'lib/redis.rb', line 2032

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



1600
1601
1602
1603
1604
# File 'lib/redis.rb', line 1600

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

#zinterstore(destination, keys, options = {}) ⇒ Fixnum

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) (defaults to: {})
    • :weights => [Float, Float, ...]: weights to associate with source sorted sets
    • :aggregate => String: aggregate function to use (sum, min, max, ...)

Returns:

  • (Fixnum)

    number of elements in the resulting sorted set



2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
# File 'lib/redis.rb', line 2052

def zinterstore(destination, keys, options = {})
  args = []

  weights = options[:weights]
  args.concat(["WEIGHTS"] + weights) if weights

  aggregate = options[:aggregate]
  args.concat(["AGGREGATE", aggregate]) if aggregate

  synchronize do |client|
    client.call([:zinterstore, destination, keys.size] + keys + args)
  end
end

#zlexcount(key, min, max) ⇒ Fixnum

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:

  • (Fixnum)

    number of members within the specified lexicographical range



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

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



1651
1652
1653
1654
1655
1656
# File 'lib/redis.rb', line 1651

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



1672
1673
1674
1675
1676
1677
# File 'lib/redis.rb', line 1672

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, options = {}) ⇒ 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 (Fixnum)

    start index

  • stop (Fixnum)

    stop index

  • options (Hash) (defaults to: {})
    • :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


1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
# File 'lib/redis.rb', line 1754

def zrange(key, start, stop, options = {})
  args = []

  with_scores = options[:with_scores] || options[:withscores]

  if with_scores
    args << "WITHSCORES"
    block = FloatifyPairs
  end

  synchronize do |client|
    client.call([:zrange, key, start, stop] + args, &block)
  end
end

#zrangebylex(key, min, max, options = {}) ⇒ 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) (defaults to: {})
    • :limit => [offset, count]: skip offset members, return a maximum of count members

Returns:

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


1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
# File 'lib/redis.rb', line 1882

def zrangebylex(key, min, max, options = {})
  args = []

  limit = options[:limit]
  args.concat(["LIMIT"] + limit) if limit

  synchronize do |client|
    client.call([:zrangebylex, key, min, max] + args)
  end
end

#zrangebyscore(key, min, max, options = {}) ⇒ 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) (defaults to: {})
    • :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


1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
# File 'lib/redis.rb', line 1942

def zrangebyscore(key, min, max, options = {})
  args = []

  with_scores = options[:with_scores] || options[:withscores]

  if with_scores
    args << "WITHSCORES"
    block = FloatifyPairs
  end

  limit = options[:limit]
  args.concat(["LIMIT"] + limit) if limit

  synchronize do |client|
    client.call([:zrangebyscore, key, min, max] + args, &block)
  end
end

#zrank(key, member) ⇒ Fixnum

Determine the index of a member in a sorted set.

Parameters:

  • key (String)
  • member (String)

Returns:

  • (Fixnum)


1800
1801
1802
1803
1804
# File 'lib/redis.rb', line 1800

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

#zrem(key, member) ⇒ Boolean, Fixnum

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, Fixnum)
    • Boolean when a single member is specified, holding whether or not it was removed from the sorted set
    • Fixnum when an array of pairs is specified, holding the number of members that were removed to the sorted set


1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
# File 'lib/redis.rb', line 1623

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

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

    start index

  • stop (Fixnum)

    stop index

Returns:

  • (Fixnum)

    number of members that were removed



1831
1832
1833
1834
1835
# File 'lib/redis.rb', line 1831

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

#zremrangebyscore(key, min, max) ⇒ Fixnum

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:

  • (Fixnum)

    number of members that were removed



2009
2010
2011
2012
2013
# File 'lib/redis.rb', line 2009

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

#zrevrange(key, start, stop, options = {}) ⇒ 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:



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

def zrevrange(key, start, stop, options = {})
  args = []

  with_scores = options[:with_scores] || options[:withscores]

  if with_scores
    args << "WITHSCORES"
    block = FloatifyPairs
  end

  synchronize do |client|
    client.call([:zrevrange, key, start, stop] + args, &block)
  end
end

#zrevrangebylex(key, max, min, options = {}) ⇒ 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:



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

def zrevrangebylex(key, max, min, options = {})
  args = []

  limit = options[:limit]
  args.concat(["LIMIT"] + limit) if limit

  synchronize do |client|
    client.call([:zrevrangebylex, key, max, min] + args)
  end
end

#zrevrangebyscore(key, max, min, options = {}) ⇒ 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:



1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
# File 'lib/redis.rb', line 1974

def zrevrangebyscore(key, max, min, options = {})
  args = []

  with_scores = options[:with_scores] || options[:withscores]

  if with_scores
    args << ["WITHSCORES"]
    block = FloatifyPairs
  end

  limit = options[:limit]
  args.concat(["LIMIT"] + limit) if limit

  synchronize do |client|
    client.call([:zrevrangebyscore, key, max, min] + args, &block)
  end
end

#zrevrank(key, member) ⇒ Fixnum

Determine the index of a member in a sorted set, with scores ordered from high to low.

Parameters:

  • key (String)
  • member (String)

Returns:

  • (Fixnum)


1812
1813
1814
1815
1816
# File 'lib/redis.rb', line 1812

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) (defaults to: {})
    • :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



2723
2724
2725
2726
2727
# File 'lib/redis.rb', line 2723

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) (defaults to: {})
    • :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



2740
2741
2742
2743
2744
2745
2746
2747
2748
# File 'lib/redis.rb', line 2740

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



1730
1731
1732
1733
1734
# File 'lib/redis.rb', line 1730

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

#zunionstore(destination, keys, options = {}) ⇒ Fixnum

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) (defaults to: {})
    • :weights => [Float, Float, ...]: weights to associate with source sorted sets
    • :aggregate => String: aggregate function to use (sum, min, max, ...)

Returns:

  • (Fixnum)

    number of elements in the resulting sorted set



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

def zunionstore(destination, keys, options = {})
  args = []

  weights = options[:weights]
  args.concat(["WEIGHTS"] + weights) if weights

  aggregate = options[:aggregate]
  args.concat(["AGGREGATE", aggregate]) if aggregate

  synchronize do |client|
    client.call([:zunionstore, destination, keys.size] + keys + args)
  end
end