Redis Struct
Using structs with Redis
Many times, we will need to store a struct in Redis instead of storing only separate fields. We can store a struct like this:
Complete code snippet:
package main
import (
"context"
"fmt"
"github.com/redis/go-redis/v9"
)
type Media struct {
Title string `redis:"title"`
IsPopular bool `redis:"is_popular"`
AgeRating int `redis:"age_rating"`
IgnoredField int `redis:"-"`
}
func main() {
client := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
Protocol: 2,
})
ctx := context.Background()
key := "media01"
if _, err := client.Pipelined(ctx, func(rdb redis.Pipeliner) error {
rdb.HSet(ctx, key, "title", "Inception")
rdb.HSet(ctx, key, "is_popular", 1)
rdb.HSet(ctx, key, "age_rating", 13)
return nil
}); err != nil {
panic(err)
}
var media Media
if err := client.HGetAll(ctx, key).Scan(&media); err != nil {
panic(err)
}
fmt.Printf("Title: %s - IsPopular: %t - AgeRating: %d\n", media.Title, media.IsPopular, media.AgeRating)
}
We can use struct field tags to change the field name within the hash.
type Media struct {
Title string `redis:"title"`
IsPopular bool `redis:"is_popular"`
AgeRating int `redis:"age_rating"`
IgnoredField int `redis:"-"`
}
We can also ignore the field using the struct field tag -. This way, the field will exist in the struct but will not be stored in Redis.
The go-redis library does not provide a way to directly save a struct, so we will use a pipeline to load some values into our database.
if _, err := client.Pipelined(ctx, func(rdb redis.Pipeliner) error {
rdb.HSet(ctx, key, "title", "Inception")
rdb.HSet(ctx, key, "is_popular", 1)
rdb.HSet(ctx, key, "age_rating", 13)
return nil
}); err != nil {
panic(err)
}
After the values have been sent to the database, we can perform a scan to populate the values into our struct.
var media Media
if err := client.HGetAll(ctx, key).Scan(&media); err != nil {
panic(err)
}
And with the values populated in our struct, we can print the values:
Title: Inception - IsPopular: true - AgeRating: 13