Redis Hash in Go With HSET, HGET and HGETALL

A hash is one of the data types in Redis. Redis hash is a map that that contains keys and their corresponding values. It is useful to store objects. Keys and values in Redis hash are string, but there are client libraries in Go to convert it to our type. In this article, I will show you how to use the hash data type in Redis.

The commands that we are going to use are: HSET, HGET, and HGETALL. HSET is a command to write fields in a hash. If the hash exists, it will be overwritten. If not, a new hash will be created. HGET is a command to get a field’s value of a hash. And HGETALL is a command to get all field’s value.

The client library that I use is https://github.com/gomodule/redigo.

Set Hash in Redis

Just like I explained in the previous post, we execute a command using a connection from the pool. Then return the connection back to the pool. For example, we want to store User data to Redis. So the code to set hash to Redis will be like this:

    ...
    key := "user_1"
    expInSeconds := 1000

    newUser := User{
        Name: "my user name",
        Age:  22,
    }


    conn := pool.Get()
    defer conn.Close()

    _, err := conn.Do("HSET", redis.Args{}.Add(key).AddFlat(newUser)...)
    if err != nil {
        return err
    }

    _, err = conn.Do("EXPIRE", key, expInSeconds)
    if err != nil {
        return err
    }
    ...

HSET command allows multiple fields to be stored in one command. With the redigo library, we can use a struct object to be stored in a hash. Let’s see the example above. We use redis.Args{}.Add(key).AddFlat(newUser)... to use a struct object as a command parameter. What actually happens is the object is flattened by AddFlat function. The function convert the object to a format that is acceptable by Redis command. Redigo will use redis field tag of the struct as the key. So the struct User in the example is:

    type User struct {
        Name string `redis:"name"`
        Age  int    `redis:"age"`
    }

Note that we execute the command EXPIRE after HSET. We do this to set the expire time of the data. It is recommended to always set the expire time. Data without expire time will exhaust the memory sooner or later.

Get Hash in Redis

HGET to Get A Field Value

If we only need the value of a single field, you can use HGET command with parameters key and field. It will return only the value of that field.

    conn := pool.Get()
    defer conn.Close()

    reply, err := redis.String(conn.Do("HGET", key, field))
    if err != nil {
        w.Write([]byte(err.Error()))
        return
    }

To get the remaining expiry time, you can use TTL command.

HGETALL to Get All Field Value

To get all fields of the hash, we HGETALL command. Redigo provides a ScanStruct function to convert the command’s reply to our struct.

    values, err := redis.Values(conn.Do("HGETALL", key))
    if err != nil {
        w.Write([]byte(err.Error()))
        return
    }

    p := user{}
    redis.ScanStruct(values, &p)

ScanStruct uses the redis field tag of the struct to find the matching field. Then set the value to the destination, so you need to use the pointer of an object as parameter.

Conclusion

There are many ways to serialize an object to be stored in Redis. One of them is to use Redis Hash. Redis hash is useful to store map or struct object. You can make a caching to database easily with it. I usually use Redis Hash to cache struct object, but that is not the only function of Redis Hash. If you have another interesting experience with it, leave a comment.

redis  go 

See also