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 Go 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 to reduce load of SQL database, but that is not the only function of Redis Hash. If you have another interesting experience with it, leave a comment.