Module: Valkey::Commands::HashCommands

Included in:
Valkey::Commands
Defined in:
lib/valkey/commands/hash_commands.rb

Overview

This module contains commands on the Hash data type.

Instance Method Summary collapse

Instance Method Details

#hdel(key, *fields) ⇒ Integer

Delete one or more hash fields.

Examples:

valkey.hdel("hash", "field1", "field2")
  # => 2

Parameters:

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

    one field, or array of fields

Returns:

  • (Integer)

    the number of fields that were removed



19
20
21
22
# File 'lib/valkey/commands/hash_commands.rb', line 19

def hdel(key, *fields)
  fields.flatten!(1)
  send_command(RequestType::HDEL, [key].concat(fields))
end

#hexists(key, field) ⇒ Boolean

Determine if a hash field exists.

Examples:

valkey.hexists("hash", "field")
  # => true

Parameters:

  • key (String)
  • field (String)

Returns:

  • (Boolean)

    whether the field exists



33
34
35
# File 'lib/valkey/commands/hash_commands.rb', line 33

def hexists(key, field)
  send_command(RequestType::HEXISTS, [key, field], &Utils::Boolify)
end

#hexpire(key, seconds, *fields, nx: nil, xx: nil, gt: nil, lt: nil) ⇒ Array<Integer>

Set a timeout on one or more hash fields.

Examples:

valkey.hexpire("hash", 60, "field1", "field2")
  # => [1, 1]

Parameters:

  • key (String)
  • seconds (Integer)

    time to live in seconds

  • fields (String, Array<String>)

    one field, or array of fields

  • options (Hash)
    • ‘:nx => true`: Set expiry only when the field has no expiry.

    • ‘:xx => true`: Set expiry only when the field has an existing expiry.

    • ‘:gt => true`: Set expiry only when the new expiry is greater than current one.

    • ‘:lt => true`: Set expiry only when the new expiry is less than current one.

Returns:

  • (Array<Integer>)

    Array of results for each field.

    • ‘1` if the expiration time was successfully set for the field.

    • ‘0` if the specified condition was not met.

    • ‘-2` if the field does not exist in the HASH, or key does not exist.



394
395
396
397
398
399
400
401
402
403
404
# File 'lib/valkey/commands/hash_commands.rb', line 394

def hexpire(key, seconds, *fields, nx: nil, xx: nil, gt: nil, lt: nil)
  fields.flatten!(1)
  args = [key, Integer(seconds)]
  args << "NX" if nx
  args << "XX" if xx
  args << "GT" if gt
  args << "LT" if lt
  args.push("FIELDS", fields.length, *fields)

  send_command(RequestType::HEXPIRE, args)
end

#hexpireat(key, unix_time, *fields, nx: nil, xx: nil, gt: nil, lt: nil) ⇒ Array<Integer>

Set the expiration for one or more hash fields as a UNIX timestamp.

Examples:

valkey.hexpireat("hash", Time.now.to_i + 60, "field1", "field2")
  # => [1, 1]

Parameters:

  • key (String)
  • unix_time (Integer)

    expiry time specified as a UNIX timestamp in seconds

  • fields (String, Array<String>)

    one field, or array of fields

  • options (Hash)
    • ‘:nx => true`: Set expiry only when the field has no expiry.

    • ‘:xx => true`: Set expiry only when the field has an existing expiry.

    • ‘:gt => true`: Set expiry only when the new expiry is greater than current one.

    • ‘:lt => true`: Set expiry only when the new expiry is less than current one.

Returns:

  • (Array<Integer>)

    Array of results for each field.

    • ‘1` if the expiration time was successfully set for the field.

    • ‘0` if the specified condition was not met.

    • ‘-2` if the field does not exist in the HASH, or key does not exist.



424
425
426
427
428
429
430
431
432
433
434
# File 'lib/valkey/commands/hash_commands.rb', line 424

def hexpireat(key, unix_time, *fields, nx: nil, xx: nil, gt: nil, lt: nil)
  fields.flatten!(1)
  args = [key, Integer(unix_time)]
  args << "NX" if nx
  args << "XX" if xx
  args << "GT" if gt
  args << "LT" if lt
  args.push("FIELDS", fields.length, *fields)

  send_command(RequestType::HEXPIREAT, args)
end

#hexpiretime(key, *fields) ⇒ Array<Integer>

Get the expiration Unix timestamp in seconds for one or more hash fields.

Examples:

valkey.hexpiretime("hash", "field1", "field2")
  # => [1234567890, -1]

Parameters:

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

    one field, or array of fields

Returns:

  • (Array<Integer>)

    Array of expiration timestamps in seconds for each field.

    • Expiration Unix timestamp in seconds if the field exists and has a timeout.

    • ‘-1` if the field exists but has no associated expire.

    • ‘-2` if the field does not exist in the provided hash key, or the hash key is empty.



565
566
567
568
569
570
# File 'lib/valkey/commands/hash_commands.rb', line 565

def hexpiretime(key, *fields)
  fields.flatten!(1)
  args = [key, "FIELDS", fields.length, *fields]

  send_command(RequestType::HEXPIRETIME, args)
end

#hget(key, field) ⇒ String?

Get the value of a hash field.

Examples:

valkey.hget("hash", "field")
  # => "value"

Parameters:

  • key (String)
  • field (String)

Returns:

  • (String, nil)

    the value of the field, or nil if the field does not exist



46
47
48
# File 'lib/valkey/commands/hash_commands.rb', line 46

def hget(key, field)
  send_command(RequestType::HGET, [key, field])
end

#hgetall(key) ⇒ Hash

Get all the fields and values in a hash.

Examples:

valkey.hgetall("hash")
  # => {"field1" => "value1", "field2" => "value2"}

Parameters:

  • key (String)

Returns:

  • (Hash)

    a hash mapping fields to their values



58
59
60
# File 'lib/valkey/commands/hash_commands.rb', line 58

def hgetall(key)
  send_command(RequestType::HGET_ALL, [key], &Utils::Hashify)
end

#hgetex(key, *fields, ex: nil, px: nil, exat: nil, pxat: nil, persist: false) ⇒ String, Array<String, nil>

Get the value of one or more hash fields and optionally set their expiration time.

Examples:

valkey.hgetex("hash", "field1", "field2", ex: 60)
  # => ["value1", "value2"]

Parameters:

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

    one field, or array of fields

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

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

    • ‘:exat => Integer`: Set the specified Unix time at which the field will expire, in seconds.

    • ‘:pxat => Integer`: Set the specified Unix time at which the field will expire, in milliseconds.

    • ‘:persist => true`: Remove the time to live associated with the field.

Returns:

  • (String, Array<String, nil>)

    The value of the field for single field, or array of values for multiple fields. For every field that does not exist in the hash, a nil value is returned.



361
362
363
364
365
366
367
368
369
370
371
372
373
374
# File 'lib/valkey/commands/hash_commands.rb', line 361

def hgetex(key, *fields, ex: nil, px: nil, exat: nil, pxat: nil, persist: false)
  fields.flatten!(1)
  args = [key]
  args << "EX" << ex if ex
  args << "PX" << px if px
  args << "EXAT" << exat if exat
  args << "PXAT" << pxat if pxat
  args << "PERSIST" if persist
  args.push("FIELDS", fields.length, *fields)

  send_command(RequestType::HGETEX, args) do |reply|
    fields.length == 1 ? reply[0] : reply
  end
end

#hincrby(key, field, increment) ⇒ Integer

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

Examples:

valkey.hincrby("hash", "field", 5)
  # => 10

Parameters:

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

Returns:

  • (Integer)

    value after incrementing it



72
73
74
# File 'lib/valkey/commands/hash_commands.rb', line 72

def hincrby(key, field, increment)
  send_command(RequestType::HINCR_BY, [key, field, Integer(increment)])
end

#hincrbyfloat(key, field, increment) ⇒ Float

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

Examples:

valkey.hincrbyfloat("hash", "field", 1.23)
  # => 1.23

Parameters:

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

Returns:

  • (Float)

    value after incrementing it



86
87
88
# File 'lib/valkey/commands/hash_commands.rb', line 86

def hincrbyfloat(key, field, increment)
  send_command(RequestType::HINCR_BY_FLOAT, [key, field, Float(increment)], &Utils::Floatify)
end

#hkeys(key) ⇒ Array<String>

Get all the fields in a hash.

Examples:

valkey.hkeys("hash")
  # => ["field1", "field2"]

Parameters:

  • key (String)

Returns:

  • (Array<String>)

    an array of field names



98
99
100
# File 'lib/valkey/commands/hash_commands.rb', line 98

def hkeys(key)
  send_command(RequestType::HKEYS, [key])
end

#hlen(key) ⇒ Integer

Get the number of fields in a hash.

Examples:

valkey.hlen("hash")
  # => 2

Parameters:

  • key (String)

Returns:

  • (Integer)

    the number of fields in the hash



110
111
112
# File 'lib/valkey/commands/hash_commands.rb', line 110

def hlen(key)
  send_command(RequestType::HLEN, [key])
end

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

Get the values of all the given hash fields.

Examples:

valkey.hmget("hash", "field1", "field2")
  # => ["value1", "value2"]

Parameters:

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

    one field, or array of fields

Returns:

  • (Array<String, nil>)

    an array of values for the specified fields

See Also:



125
126
127
128
# File 'lib/valkey/commands/hash_commands.rb', line 125

def hmget(key, *fields, &blk)
  fields.flatten!(1)
  send_command(RequestType::HMGET, [key].concat(fields), &blk)
end

#hmset(key, *args) ⇒ String

Set multiple hash fields to multiple values.

Examples:

valkey.hmset("hash", "field1", "value1", "field2", "value2")
  # => "OK"

Parameters:

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

    array of field-value pairs

Returns:

  • (String)

    ‘“OK”`

See Also:



163
164
165
# File 'lib/valkey/commands/hash_commands.rb', line 163

def hmset(key, *args)
  send_command(RequestType::HMSET, [key].concat(args))
end

#hpersist(key, *fields) ⇒ Array<Integer>

Remove the expiration from one or more hash fields.

Examples:

valkey.hpersist("hash", "field1", "field2")
  # => [1, 1]

Parameters:

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

    one field, or array of fields

Returns:

  • (Array<Integer>)

    Array of results for each field.

    • ‘1` if the expiration time was successfully removed from the field.

    • ‘-1` if the field exists but has no expiration time.

    • ‘-2` if the field does not exist in the provided hash key, or the hash key does not exist.



508
509
510
511
512
513
# File 'lib/valkey/commands/hash_commands.rb', line 508

def hpersist(key, *fields)
  fields.flatten!(1)
  args = [key, "FIELDS", fields.length, *fields]

  send_command(RequestType::HPERSIST, args)
end

#hpexpire(key, milliseconds, *fields, nx: nil, xx: nil, gt: nil, lt: nil) ⇒ Array<Integer>

Set a timeout on one or more hash fields in milliseconds.

Examples:

valkey.hpexpire("hash", 60000, "field1", "field2")
  # => [1, 1]

Parameters:

  • key (String)
  • milliseconds (Integer)

    time to live in milliseconds

  • fields (String, Array<String>)

    one field, or array of fields

  • options (Hash)
    • ‘:nx => true`: Set expiry only when the field has no expiry.

    • ‘:xx => true`: Set expiry only when the field has an existing expiry.

    • ‘:gt => true`: Set expiry only when the new expiry is greater than current one.

    • ‘:lt => true`: Set expiry only when the new expiry is less than current one.

Returns:

  • (Array<Integer>)

    Array of results for each field.

    • ‘1` if the expiration time was successfully set for the field.

    • ‘0` if the specified condition was not met.

    • ‘-2` if the field does not exist in the HASH, or key does not exist.



454
455
456
457
458
459
460
461
462
463
464
# File 'lib/valkey/commands/hash_commands.rb', line 454

def hpexpire(key, milliseconds, *fields, nx: nil, xx: nil, gt: nil, lt: nil)
  fields.flatten!(1)
  args = [key, Integer(milliseconds)]
  args << "NX" if nx
  args << "XX" if xx
  args << "GT" if gt
  args << "LT" if lt
  args.push("FIELDS", fields.length, *fields)

  send_command(RequestType::HPEXPIRE, args)
end

#hpexpireat(key, unix_time_ms, *fields, nx: nil, xx: nil, gt: nil, lt: nil) ⇒ Array<Integer>

Set the expiration for one or more hash fields as a UNIX timestamp in milliseconds.

Examples:

valkey.hpexpireat("hash", (Time.now.to_i * 1000) + 60000, "field1", "field2")
  # => [1, 1]

Parameters:

  • key (String)
  • unix_time_ms (Integer)

    expiry time specified as a UNIX timestamp in milliseconds

  • fields (String, Array<String>)

    one field, or array of fields

  • options (Hash)
    • ‘:nx => true`: Set expiry only when the field has no expiry.

    • ‘:xx => true`: Set expiry only when the field has an existing expiry.

    • ‘:gt => true`: Set expiry only when the new expiry is greater than current one.

    • ‘:lt => true`: Set expiry only when the new expiry is less than current one.

Returns:

  • (Array<Integer>)

    Array of results for each field.

    • ‘1` if the expiration time was successfully set for the field.

    • ‘0` if the specified condition was not met.

    • ‘-2` if the field does not exist in the HASH, or key does not exist.



484
485
486
487
488
489
490
491
492
493
494
# File 'lib/valkey/commands/hash_commands.rb', line 484

def hpexpireat(key, unix_time_ms, *fields, nx: nil, xx: nil, gt: nil, lt: nil)
  fields.flatten!(1)
  args = [key, Integer(unix_time_ms)]
  args << "NX" if nx
  args << "XX" if xx
  args << "GT" if gt
  args << "LT" if lt
  args.push("FIELDS", fields.length, *fields)

  send_command(RequestType::HPEXPIREAT, args)
end

#hpexpiretime(key, *fields) ⇒ Array<Integer>

Get the expiration Unix timestamp in milliseconds for one or more hash fields.

Examples:

valkey.hpexpiretime("hash", "field1", "field2")
  # => [1234567890000, -1]

Parameters:

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

    one field, or array of fields

Returns:

  • (Array<Integer>)

    Array of expiration timestamps in milliseconds for each field.

    • Expiration Unix timestamp in milliseconds if the field exists and has a timeout.

    • ‘-1` if the field exists but has no associated expire.

    • ‘-2` if the field does not exist in the provided hash key, or the hash key is empty.



584
585
586
587
588
589
# File 'lib/valkey/commands/hash_commands.rb', line 584

def hpexpiretime(key, *fields)
  fields.flatten!(1)
  args = [key, "FIELDS", fields.length, *fields]

  send_command(RequestType::HPEXPIRETIME, args)
end

#hpttl(key, *fields) ⇒ Array<Integer>

Get the time to live in milliseconds of one or more hash fields.

Examples:

valkey.hpttl("hash", "field1", "field2")
  # => [60000, -1]

Parameters:

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

    one field, or array of fields

Returns:

  • (Array<Integer>)

    Array of TTLs in milliseconds for each field.

    • TTL in milliseconds if the field exists and has a timeout.

    • ‘-1` if the field exists but has no associated expire.

    • ‘-2` if the field does not exist in the provided hash key, or the hash key is empty.



546
547
548
549
550
551
# File 'lib/valkey/commands/hash_commands.rb', line 546

def hpttl(key, *fields)
  fields.flatten!(1)
  args = [key, "FIELDS", fields.length, *fields]

  send_command(RequestType::HPTTL, args)
end

#hrandfield(key, count = nil, withvalues: false, with_values: withvalues) ⇒ nil, ...

Get one or multiple random fields from a hash.

Examples:

Get one random field

valkey.hrandfield("hash")
  # => "field1"

Get multiple random fields

valkey.hrandfield("hash", 2)
  # => ["field1", "field2"]

Get multiple random fields with values

valkey.hrandfield("hash", 2, with_values: true)
  # => [["field1", "value1"], ["field2", "value2"]]

Parameters:

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

    number of fields to return (optional)

  • options (Hash)
    • ‘:with_values => true`: include values in output

Returns:

  • (nil, String, Array<String>, Array<[String, String]>)
    • when ‘key` does not exist, `nil`

    • when ‘count` is not specified, a field name

    • when ‘count` is specified and `:with_values` is not specified, an array of field names

    • when ‘:with_values` is specified, an array with `[field, value]` pairs

Raises:

  • (ArgumentError)


204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/valkey/commands/hash_commands.rb', line 204

def hrandfield(key, count = nil, withvalues: false, with_values: withvalues)
  raise ArgumentError, "count argument must be specified" if with_values && count.nil?

  args = [key]
  args << Integer(count) if count
  args << "WITHVALUES" if with_values

  if with_values
    send_command(RequestType::HRAND_FIELD, args) do |reply|
      # Handle both ARRAY (flat) and MAP (already pairs) response types
      if reply.is_a?(Array) && !reply.empty? && reply.first.is_a?(Array) && reply.first.size == 2
        # Already in pairs format (from MAP response): [[field, value], ...]
        reply
      elsif reply.is_a?(Array) && reply.respond_to?(:each_slice)
        # ARRAY response: flat array of field-value pairs, convert to pairs
        reply.each_slice(2).to_a
      else
        # Fallback: try Pairify
        Utils::Pairify.call(reply)
      end
    end
  else
    send_command(RequestType::HRAND_FIELD, args)
  end
end

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

Scan a hash

See the [Valkey Server HSCAN documentation](valkey.io/commands/hscan/) for further details

Examples:

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

valkey.hscan("hash", 0)

Parameters:

  • key (String)
  • cursor (String, Integer)

    the cursor of the iteration

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

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

Returns:

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

    the next cursor and all found key/value pairs



244
245
246
247
248
# File 'lib/valkey/commands/hash_commands.rb', line 244

def hscan(key, cursor, **options)
  _scan(RequestType::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

See the [Valkey Server HSCAN documentation](valkey.io/commands/hscan/) for further details

Examples:

Retrieve all of the key/value pairs in a hash

valkey.hscan_each("hash").to_a
# => [["field1", "value1"], ["field2", "value2"]]

Parameters:

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

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

Returns:

  • (Enumerator)

    an enumerator for all key/value pairs in the hash



264
265
266
267
268
269
270
271
272
273
# File 'lib/valkey/commands/hash_commands.rb', line 264

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

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

#hset(key, *attrs) ⇒ Integer

Set one or more hash values.

Examples:

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

Parameters:

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

    array or hash of fields and values

Returns:

  • (Integer)

    The number of fields that were added to the hash



284
285
286
287
288
# File 'lib/valkey/commands/hash_commands.rb', line 284

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

  send_command(RequestType::HSET, [key, *attrs])
end

#hsetex(key, field, value, seconds) ⇒ Integer

Set the string value of a hash field and set its expiration time in seconds.

Examples:

valkey.hsetex("hash", "field", "value", 60)
  # => 1

Parameters:

  • key (String)
  • field (String)
  • value (String)
  • seconds (Integer)

    expiration time in seconds

Returns:

  • (Integer)

    the number of fields that were added



341
342
343
# File 'lib/valkey/commands/hash_commands.rb', line 341

def hsetex(key, field, value, seconds)
  send_command(RequestType::HSETEX, [key, "EX", Integer(seconds), "FIELDS", 1, field, value])
end

#hsetnx(key, field, value) ⇒ Boolean

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

Examples:

valkey.hsetnx("hash", "field", "value")
  # => true

Parameters:

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

Returns:

  • (Boolean)

    whether the field was set or not



300
301
302
# File 'lib/valkey/commands/hash_commands.rb', line 300

def hsetnx(key, field, value)
  send_command(RequestType::HSET_NX, [key, field, value], &Utils::Boolify)
end

#hstrlen(key, field) ⇒ Integer

Get the string length of the value associated with field in the hash stored at key.

Examples:

valkey.hstrlen("hash", "field")
  # => 5

Parameters:

  • key (String)
  • field (String)

Returns:

  • (Integer)

    the string length of the value associated with field, or 0 when field is not present in the hash or key does not exist



314
315
316
# File 'lib/valkey/commands/hash_commands.rb', line 314

def hstrlen(key, field)
  send_command(RequestType::HSTRLEN, [key, field])
end

#httl(key, *fields) ⇒ Array<Integer>

Get the time to live in seconds of one or more hash fields.

Examples:

valkey.httl("hash", "field1", "field2")
  # => [60, -1]

Parameters:

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

    one field, or array of fields

Returns:

  • (Array<Integer>)

    Array of TTLs in seconds for each field.

    • TTL in seconds if the field exists and has a timeout.

    • ‘-1` if the field exists but has no associated expire.

    • ‘-2` if the field does not exist in the provided hash key, or the hash key is empty.



527
528
529
530
531
532
# File 'lib/valkey/commands/hash_commands.rb', line 527

def httl(key, *fields)
  fields.flatten!(1)
  args = [key, "FIELDS", fields.length, *fields]

  send_command(RequestType::HTTL, args)
end

#hvals(key) ⇒ Array<String>

Get all the values in a hash.

Examples:

valkey.hvals("hash")
  # => ["value1", "value2"]

Parameters:

  • key (String)

Returns:

  • (Array<String>)

    an array of values



326
327
328
# File 'lib/valkey/commands/hash_commands.rb', line 326

def hvals(key)
  send_command(RequestType::HVALS, [key])
end

#mapped_hmget(key, *fields) ⇒ Hash

Get the values of all the given hash fields.

Examples:

valkey.mapped_hmget("hash", "field1", "field2")
  # => {"field1" => "value1", "field2" => "value2"}

Parameters:

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

    one field, or array of fields

Returns:

  • (Hash)

    a hash mapping the specified fields to their values

See Also:



141
142
143
144
145
146
147
148
149
150
# File 'lib/valkey/commands/hash_commands.rb', line 141

def mapped_hmget(key, *fields)
  fields.flatten!(1)
  hmget(key, fields) do |reply|
    if reply.is_a?(Array)
      fields.zip(reply).to_h
    else
      reply
    end
  end
end

#mapped_hmset(key, hash) ⇒ String

Set multiple hash fields to multiple values.

Examples:

valkey.mapped_hmset("hash", { "field1" => "value1", "field2" => "value2" })
  # => "OK"

Parameters:

  • key (String)
  • hash (Hash)

    fields mapping to values

Returns:

  • (String)

    ‘“OK”`

See Also:



178
179
180
# File 'lib/valkey/commands/hash_commands.rb', line 178

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