StackExchange.Redis: Usando estruturas de dados string
Tags: redis, dotnet, programming, braziliandevs
Published: 2023-02-19 06:24:14

## Introdução

Uma das principais vantagens do Redis é sua capacidade de armazenar e manipular várias estruturas de dados complexas, incluindo listas, conjuntos, hashes e muito mais. A biblioteca `StackExchange.Redis` torna fácil trabalhar com essas estruturas de dados, permitindo que os desenvolvedores tirem o máximo proveito do Redis para seus aplicativos.

## Redis Strings

Redis Strings são as estruturas de dados Redis mais simples. Eles mapeiam uma única chave Redis para um único valor Redis. Apesar de sua simplicidade, eles têm uma variedade de recursos que os tornam úteis em vários casos de uso.

### Redis strings na prática

As coisas mais simples que você pode fazer com uma string são configurá-la e obtê-la, para fazer isso tudo que você precisa fazer é usar os métodos `StringSet` e `StringGet`:

```csharp
var programingLanguageNameKey = new RedisKey("programing-languages:1:name");
// Set a string
await database.StringSetAsync(programingLanguageNameKey, "C#");
// Get a string
var programingLanguage1Name = await database.StringGetAsync(programingLanguageNameKey);
Console.WriteLine($"Programing language 1 name is: {programingLanguage1Name}");
```

```csharp
// output
Programing language 1 name is: C#
```

Se você deseja anexar uma string a um valor de string existente, pode usar o método `StringAppend`:

```csharp
// append a string onto an existing string value
await database.StringAppendAsync(programingLanguageNameKey, " or CSharp");
programingLanguage1Name = await database.StringGetAsync(programingLanguageNameKey);
Console.WriteLine($"Programing language 1 full name is: {programingLanguage1Name}");
```

```csharp
// output
Programing language 1 full name is: C# or CSharp
```

### String numérica

Existem codificações alternativas de strings além de uma string de caracteres brutos. Se uma string for definida como um valor numérico, você poderá usar os métodos `StringIncrement` nela.

Existem duas sobrecargas do método `StringIncrement`, se você passar em um long, ele irá incrementar a chave em um valor long:

```csharp
var csharpLangStartsKey = "csharpLang:starts";
database.StringSet(csharpLangStartsKey, 9689);
var csharpLangStarts = database.StringIncrement(csharpLangStartsKey, 5);
Console.WriteLine($"C# has {csharpLangStarts} starts");
csharpLangStarts = database.StringIncrement(csharpLangStartsKey);
Console.WriteLine($"C# has {csharpLangStarts} starts");
```

Se você precisar incrementar por um ponto flutuante, você pode passar um double como o incremento

```csharp
var csharpLangStartsAsDouble = database.StringIncrement(csharpLangStartsKey, .5);
Console.WriteLine($"C# has {csharpLangStartsAsDouble} starts");
```

⚠️ Se você incrementar por um ponto flutuante, não poderá mais incrementar por um número inteiro, pois alterou a codificação da string.

## Opções de string

Existem algumas opções importantes a serem observadas ao definir strings.

### Expiração

Você pode definir uma expiração em uma string ao defini-la usando a opção de expiração. A expiração é um `TimeSpan`, há várias maneiras de criá-los. Neste exemplo, criaremos apenas uma chave de duração super curta usando o método `FromSeconds` para inicializar uma chave que durará 1 segundo.

```csharp
await database.StringSetAsync("tempKey", "temp message", TimeSpan.FromSeconds(1));
```

### Condições de atribuições

Pode ser definida uma condição de atribuição usando a opção when. A opção when usa a enumeração When e tem três valores possíveis.

- `Always`: Este é o padrão, sempre defina a chave.
- `Exists`: Definir apenas se a chave existir
- `NotExists`: Definir apenas se a chave não existir

```csharp
var conditionalKey = "conditionalKey";
await database.StringSetAsync(conditionalKey, "conditionalText not exists", when: When.NotExists);
Console.WriteLine(await database.StringGetAsync(conditionalKey));
await database.StringSetAsync(conditionalKey, "conditionalText always");
Console.WriteLine(await database.StringGetAsync(conditionalKey));
await database.StringSetAsync(conditionalKey, "conditionalText if exists", when: When.Exists);
Console.WriteLine(await database.StringGetAsync(conditionalKey));
```

```csharp
conditionalText not exists
conditionalText always
conditionalText if exists
```

## Conclusão

Essas são algumas maneira de se utilizar strings e algumas das principais operações que você pode utilizar.

## Código completo

```csharp
using StackExchange.Redis;
using System.Diagnostics;

var options = new ConfigurationOptions
{
    EndPoints = new EndPointCollection { "localhost:6379" }
};

var conn = ConnectionMultiplexer.Connect(options);
var database = conn.GetDatabase();

var programingLanguageNameKey = new RedisKey("programing-languages:1:name");
// Set a string
await database.StringSetAsync(programingLanguageNameKey, "C#");
// Get a string
var programingLanguage1Name = await database.StringGetAsync(programingLanguageNameKey);
Console.WriteLine($"Programing language 1 name is: {programingLanguage1Name}");

// append a string onto an existing string value
await database.StringAppendAsync(programingLanguageNameKey, " or CSharp");
programingLanguage1Name = await database.StringGetAsync(programingLanguageNameKey);
Console.WriteLine($"Programing language 1 full name is: {programingLanguage1Name}");

var csharpLangStartsKey = "csharpLang:starts";
database.StringSet(csharpLangStartsKey, 9689);
var csharpLangStarts = database.StringIncrement(csharpLangStartsKey, 5);
Console.WriteLine($"C# has {csharpLangStarts} starts");
csharpLangStarts = database.StringIncrement(csharpLangStartsKey);
Console.WriteLine($"C# has {csharpLangStarts} starts");
var csharpLangStartsAsDouble = database.StringIncrement(csharpLangStartsKey, .5);
Console.WriteLine($"C# has {csharpLangStartsAsDouble} starts");

await database.StringSetAsync("tempKey", "temp message", TimeSpan.FromSeconds(1));

var conditionalKey = "conditionalKey";
await database.StringSetAsync(conditionalKey, "conditionalText not exists", when: When.NotExists);
Console.WriteLine(await database.StringGetAsync(conditionalKey));
await database.StringSetAsync(conditionalKey, "conditionalText always");
Console.WriteLine(await database.StringGetAsync(conditionalKey));
await database.StringSetAsync(conditionalKey, "conditionalText if exists", when: When.Exists);
Console.WriteLine(await database.StringGetAsync(conditionalKey));
```