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