module Redis::Commands::SortedSets

def _zsets_operation(cmd, *keys, weights: nil, aggregate: nil, with_scores: false)

def _zsets_operation(cmd, *keys, weights: nil, aggregate: nil, with_scores: false)
  keys.flatten!(1)
  command = [cmd, keys.size].concat(keys)
  if weights
    command << "WEIGHTS"
    command.concat(weights)
  end
  command << "AGGREGATE" << aggregate if aggregate
  if with_scores
    command << "WITHSCORES"
    block = FloatifyPairs
  end
  send_command(command, &block)
end

def _zsets_operation_store(cmd, destination, keys, weights: nil, aggregate: nil)

def _zsets_operation_store(cmd, destination, keys, weights: nil, aggregate: nil)
  keys.flatten!(1)
  command = [cmd, destination, keys.size].concat(keys)
  if weights
    command << "WEIGHTS"
    command.concat(weights)
  end
  command << "AGGREGATE" << aggregate if aggregate
  send_command(command)
end

def bzpopmax(*args)

Returns:
  • (nil) - when no element could be popped and the timeout expired
  • (Array) - a touple of key, member and score

Other tags:
    Example: Popping a member from multiple sorted sets -
    Example: Popping a member from a sorted set -
def bzpopmax(*args)
  _bpop(:bzpopmax, args) do |reply|
    reply.is_a?(Array) ? [reply[0], reply[1], Floatify.call(reply[2])] : reply
  end
end

def bzpopmin(*args)

Returns:
  • (nil) - when no element could be popped and the timeout expired
  • (Array) - a touple of key, member and score

Other tags:
    Example: Popping a member from multiple sorted sets -
    Example: Popping a member from a sorted set -
def bzpopmin(*args)
  _bpop(:bzpopmin, args) do |reply|
    reply.is_a?(Array) ? [reply[0], reply[1], Floatify.call(reply[2])] : reply
  end
end

def zadd(key, *args, nx: nil, xx: nil, lt: nil, gt: nil, ch: nil, incr: nil)

Returns:
  • (Boolean, Integer, Float) -

Parameters:
  • options (Hash) --
  • args ([Float, String], Array<[Float, String]>) --
  • key (String) --

Other tags:
    Example: Add an array of `[score, member]` pairs to a sorted set -
    Example: Add a single `[score, member]` pair to a sorted set -
def zadd(key, *args, nx: nil, xx: nil, lt: nil, gt: nil, ch: nil, incr: nil)
  command = [:zadd, key]
  command << "NX" if nx
  command << "XX" if xx
  command << "LT" if lt
  command << "GT" if gt
  command << "CH" if ch
  command << "INCR" if incr
  if args.size == 1 && args[0].is_a?(Array)
    members_to_add = args[0]
    return 0 if members_to_add.empty?
    # Variadic: return float if INCR, integer if !INCR
    send_command(command + members_to_add, &(incr ? Floatify : nil))
  elsif args.size == 2
    # Single pair: return float if INCR, boolean if !INCR
    send_command(command + args, &(incr ? Floatify : Boolify))
  else
    raise ArgumentError, "wrong number of arguments"
  end
end

def zcard(key)

Returns:
  • (Integer) -

Parameters:
  • key (String) --
def zcard(key)
  send_command([:zcard, key])
end

def zcount(key, min, max)

Returns:
  • (Integer) - number of members in within the specified range

Parameters:
  • max (String) --
  • min (String) --
  • key (String) --

Other tags:
    Example: Count members with scores `> 5` -
    Example: Count members with score `>= 5` and `< 100` -
def zcount(key, min, max)
  send_command([:zcount, key, min, max])
end

def zdiff(*keys, with_scores: false)

Returns:
  • (Array, Array<[String, Float]>) -

Parameters:
  • options (Hash) --
  • keys (String, Array) -- one or more keys to compute the difference

Other tags:
    Example: With scores -
def zdiff(*keys, with_scores: false)
  _zsets_operation(:zdiff, *keys, with_scores: with_scores)
end

def zdiffstore(*args)

Returns:
  • (Integer) - number of elements in the resulting sorted set

Parameters:
  • keys (Array) -- source keys
  • destination (String) -- destination key
def zdiffstore(*args)
  _zsets_operation_store(:zdiffstore, *args)
end

def zincrby(key, increment, member)

Returns:
  • (Float) - score of the member after incrementing it

Parameters:
  • member (String) --
  • increment (Float) --
  • key (String) --
def zincrby(key, increment, member)
  send_command([:zincrby, key, increment, member], &Floatify)
end

def zinter(*args)

Returns:
  • (Array, Array<[String, Float]>) -

Parameters:
  • options (Hash) --
  • keys (String, Array) -- one or more keys to intersect

Other tags:
    Example: Retrieve the intersection of `2*zsetA` and `1*zsetB`, and their scores -
    Example: Retrieve the intersection of `2*zsetA` and `1*zsetB` -
def zinter(*args)
  _zsets_operation(:zinter, *args)
end

def zinterstore(*args)

Returns:
  • (Integer) - number of elements in the resulting sorted set

Parameters:
  • options (Hash) --
  • keys (Array) -- source keys
  • destination (String) -- destination key

Other tags:
    Example: Compute the intersection of `2*zsetA` with `1*zsetB`, summing their scores -
def zinterstore(*args)
  _zsets_operation_store(:zinterstore, *args)
end

def zlexcount(key, min, max)

Returns:
  • (Integer) - number of members within the specified lexicographical range

Parameters:
  • max (String) --
  • min (String) --
  • key (String) --

Other tags:
    Example: Count members matching a-z -
    Example: Count members matching a -
def zlexcount(key, min, max)
  send_command([:zlexcount, key, min, max])
end

def zmscore(key, *members)

Returns:
  • (Array) - scores of the members

Parameters:
  • members (String, Array) --
  • key (String) --

Other tags:
    Example: Get the scores for members "a" and "b" -
def zmscore(key, *members)
  send_command([:zmscore, key, *members]) do |reply|
    reply.map(&Floatify)
  end
end

def zpopmax(key, count = nil)

Returns:
  • (Array>) - list of popped elements and scores
  • (Array) - element and score pair if count is not specified

Other tags:
    Example: With count option -
    Example: Popping a member -
def zpopmax(key, count = nil)
  command = [:zpopmax, key]
  command << Integer(count) if count
  send_command(command) do |members|
    members = FloatifyPairs.call(members)
    count.to_i > 1 ? members : members.first
  end
end

def zpopmin(key, count = nil)

Returns:
  • (Array>) - list of popped elements and scores
  • (Array) - element and score pair if count is not specified

Other tags:
    Example: With count option -
    Example: Popping a member -
def zpopmin(key, count = nil)
  command = [:zpopmin, key]
  command << Integer(count) if count
  send_command(command) do |members|
    members = FloatifyPairs.call(members)
    count.to_i > 1 ? members : members.first
  end
end

def zrandmember(key, count = nil, withscores: false, with_scores: withscores)

Returns:
  • (nil, String, Array, Array<[String, Float]>) -

Parameters:
  • options (Hash) --
  • count (Integer) --
  • key (String) --

Other tags:
    Example: Get multiple random members with scores -
    Example: Get multiple random members -
    Example: Get one random member -
def zrandmember(key, count = nil, withscores: false, with_scores: withscores)
  if with_scores && count.nil?
    raise ArgumentError, "count argument must be specified"
  end
  args = [:zrandmember, key]
  args << Integer(count) if count
  if with_scores
    args << "WITHSCORES"
    block = FloatifyPairs
  end
  send_command(args, &block)
end

def zrange(key, start, stop, byscore: false, by_score: byscore, bylex: false, by_lex: bylex,

Returns:
  • (Array, Array<[String, Float]>) -

Parameters:
  • options (Hash) --
  • stop (Integer) -- stop index
  • start (Integer) -- start index
  • key (String) --

Other tags:
    Example: Retrieve all members and their scores from a sorted set -
    Example: Retrieve all members from a sorted set, by index -
def zrange(key, start, stop, byscore: false, by_score: byscore, bylex: false, by_lex: bylex,
           rev: false, limit: nil, withscores: false, with_scores: withscores)
  if by_score && by_lex
    raise ArgumentError, "only one of :by_score or :by_lex can be specified"
  end
  args = [:zrange, key, start, stop]
  if by_score
    args << "BYSCORE"
  elsif by_lex
    args << "BYLEX"
  end
  args << "REV" if rev
  if limit
    args << "LIMIT"
    args.concat(limit.map { |l| Integer(l) })
  end
  if with_scores
    args << "WITHSCORES"
    block = FloatifyPairs
  end
  send_command(args, &block)
end

def zrangebylex(key, min, max, limit: nil)

Returns:
  • (Array, Array<[String, Float]>) -

Parameters:
  • options (Hash) --
  • max (String) --
  • min (String) --
  • key (String) --

Other tags:
    Example: Retrieve the first 2 members matching a -
    Example: Retrieve members matching a -
def zrangebylex(key, min, max, limit: nil)
  args = [:zrangebylex, key, min, max]
  if limit
    args << "LIMIT"
    args.concat(limit.map { |l| Integer(l) })
  end
  send_command(args)
end

def zrangebyscore(key, min, max, withscores: false, with_scores: withscores, limit: nil)

Returns:
  • (Array, Array<[String, Float]>) -

Parameters:
  • options (Hash) --
  • max (String) --
  • min (String) --
  • key (String) --

Other tags:
    Example: Retrieve members and their scores with scores `> 5` -
    Example: Retrieve the first 2 members with score `>= 0` -
    Example: Retrieve members with score `>= 5` and `< 100` -
def zrangebyscore(key, min, max, withscores: false, with_scores: withscores, limit: nil)
  args = [:zrangebyscore, key, min, max]
  if with_scores
    args << "WITHSCORES"
    block = FloatifyPairs
  end
  if limit
    args << "LIMIT"
    args.concat(limit.map { |l| Integer(l) })
  end
  send_command(args, &block)
end

def zrangestore(dest_key, src_key, start, stop, byscore: false, by_score: byscore,

Other tags:
    See: #zrange -

Returns:
  • (Integer) - the number of elements in the resulting sorted set
def zrangestore(dest_key, src_key, start, stop, byscore: false, by_score: byscore,
                bylex: false, by_lex: bylex, rev: false, limit: nil)
  if by_score && by_lex
    raise ArgumentError, "only one of :by_score or :by_lex can be specified"
  end
  args = [:zrangestore, dest_key, src_key, start, stop]
  if by_score
    args << "BYSCORE"
  elsif by_lex
    args << "BYLEX"
  end
  args << "REV" if rev
  if limit
    args << "LIMIT"
    args.concat(limit.map { |l| Integer(l) })
  end
  send_command(args)
end

def zrank(key, member)

Returns:
  • (Integer) -

Parameters:
  • member (String) --
  • key (String) --
def zrank(key, member)
  send_command([:zrank, key, member])
end

def zrem(key, member)

Returns:
  • (Boolean, Integer) -

Parameters:
  • member (String, Array) --
  • key (String) --

Other tags:
    Example: Remove an array of members from a sorted set -
    Example: Remove a single member from a sorted set -
def zrem(key, member)
  if member.is_a?(Array)
    members_to_remove = member
    return 0 if members_to_remove.empty?
  end
  send_command([: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

def zremrangebyrank(key, start, stop)

Returns:
  • (Integer) - number of members that were removed

Parameters:
  • stop (Integer) -- stop index
  • start (Integer) -- start index
  • key (String) --

Other tags:
    Example: Remove last 5 members -
    Example: Remove first 5 members -
def zremrangebyrank(key, start, stop)
  send_command([:zremrangebyrank, key, start, stop])
end

def zremrangebyscore(key, min, max)

Returns:
  • (Integer) - number of members that were removed

Parameters:
  • max (String) --
  • min (String) --
  • key (String) --

Other tags:
    Example: Remove members with scores `> 5` -
    Example: Remove members with score `>= 5` and `< 100` -
def zremrangebyscore(key, min, max)
  send_command([:zremrangebyscore, key, min, max])
end

def zrevrange(key, start, stop, withscores: false, with_scores: withscores)

Other tags:
    See: #zrange -

Other tags:
    Example: Retrieve all members and their scores from a sorted set -
    Example: Retrieve all members from a sorted set -
def zrevrange(key, start, stop, withscores: false, with_scores: withscores)
  args = [:zrevrange, key, Integer(start), Integer(stop)]
  if with_scores
    args << "WITHSCORES"
    block = FloatifyPairs
  end
  send_command(args, &block)
end

def zrevrangebylex(key, max, min, limit: nil)

Other tags:
    See: #zrangebylex -

Other tags:
    Example: Retrieve the last 2 members matching a -
    Example: Retrieve members matching a -
def zrevrangebylex(key, max, min, limit: nil)
  args = [:zrevrangebylex, key, max, min]
  if limit
    args << "LIMIT"
    args.concat(limit.map { |l| Integer(l) })
  end
  send_command(args)
end

def zrevrangebyscore(key, max, min, withscores: false, with_scores: withscores, limit: nil)

Other tags:
    See: #zrangebyscore -

Other tags:
    Example: Retrieve members and their scores with scores `> 5` -
    Example: Retrieve the first 2 members with score `<= 0` -
    Example: Retrieve members with score `< 100` and `>= 5` -
def zrevrangebyscore(key, max, min, withscores: false, with_scores: withscores, limit: nil)
  args = [:zrevrangebyscore, key, max, min]
  if with_scores
    args << "WITHSCORES"
    block = FloatifyPairs
  end
  if limit
    args << "LIMIT"
    args.concat(limit.map { |l| Integer(l) })
  end
  send_command(args, &block)
end

def zrevrank(key, member)

Returns:
  • (Integer) -

Parameters:
  • member (String) --
  • key (String) --
def zrevrank(key, member)
  send_command([:zrevrank, key, member])
end

def zscan(key, cursor, **options)

Returns:
  • (String, Array<[String, Float]>) - the next cursor and all found

Parameters:
  • options (Hash) --
  • cursor (String, Integer) -- the cursor of the iteration

Other tags:
    Example: Retrieve the first batch of key/value pairs in a hash -
def zscan(key, cursor, **options)
  _scan(:zscan, cursor, [key], **options) do |reply|
    [reply[0], FloatifyPairs.call(reply[1])]
  end
end

def zscan_each(key, **options, &block)

Returns:
  • (Enumerator) - an enumerator for all found scores and members

Parameters:
  • options (Hash) --

Other tags:
    Example: Retrieve all of the members/scores in a sorted set -
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

def zscore(key, member)

Returns:
  • (Float) - score of the member

Parameters:
  • member (String) --
  • key (String) --

Other tags:
    Example: Get the score for member "a" -
def zscore(key, member)
  send_command([:zscore, key, member], &Floatify)
end

def zunion(*args)

Returns:
  • (Array, Array<[String, Float]>) -

Parameters:
  • options (Hash) --
  • keys (String, Array) -- one or more keys to union

Other tags:
    Example: Retrieve the union of `2*zsetA` and `1*zsetB`, and their scores -
    Example: Retrieve the union of `2*zsetA` and `1*zsetB` -
def zunion(*args)
  _zsets_operation(:zunion, *args)
end

def zunionstore(*args)

Returns:
  • (Integer) - number of elements in the resulting sorted set

Parameters:
  • options (Hash) --
  • keys (Array) -- source keys
  • destination (String) -- destination key

Other tags:
    Example: Compute the union of `2*zsetA` with `1*zsetB`, summing their scores -
def zunionstore(*args)
  _zsets_operation_store(:zunionstore, *args)
end