Redis Struct

Utilizando structs com Redis

Muitas vezes vamos precisar armazenar uma struct no Redis ao invés de armazenar somente campos separados, podemos armazenar uma struct dessa forma:

Recho de código completo:

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)
}

Nós podemos utlizar struct field tags para alterar o nome do campo dentro do hash.

type Media struct {
	Title        string `redis:"title"`
	IsPopular    bool   `redis:"is_popular"`
	AgeRating    int    `redis:"age_rating"`
	IgnoredField int    `redis:"-"`
}

Podemos também ignorar o campo com a struct field tag -, dessa forma o campo irá existir na struct, mas não será armazenado no Redis.

O go-redis não provê uma forma de salvar uma struct diretamente, por isso, vamos utilizar uma pipeline para carregar alguns valores no nosso banco de dados.

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)
}

Após os valores terem sido enviados para o banco de dados, podemos fazer um scan para popular os valores na nossa struct.

var media Media
if err := client.HGetAll(ctx, key).Scan(&media); err != nil {
    panic(err)
}

E com os valores populados na nossa struct podemos imprimir os valores:

Title: Inception - IsPopular: true - AgeRating: 13