Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion build/components/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
'java-sync': '@Test',
'java-async': '@Test',
'java-reactive': '@Test',
'c#': r'\[Fact]|\[SkipIfRedis\(.*\)]'
'c#': r'\[Fact]|\[SkipIfRedis\(.*\)]',
'c#-sync': r'\[Fact]|\[SkipIfRedis\(.*\)]',
'c#-async': r'\[Fact]|\[SkipIfRedis\(.*\)]'
}
PREFIXES = {
'python': '#',
Expand All @@ -25,6 +27,8 @@
'java-reactive': '//',
'go': '//',
'c#': '//',
'c#-sync': '//',
'c#-async': '//',
'redisvl': '#',
'php': '//',
'rust': '//',
Expand Down
7 changes: 6 additions & 1 deletion build/local_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
'python': 'Python',
'node.js': 'Node.js',
'go': 'Go',
'c#': 'C#',
'c#': 'C#-Sync',
'java': 'Java-Sync', # Default to sync, could be overridden
'php': 'PHP',
'redisvl': 'RedisVL',
Expand Down Expand Up @@ -72,6 +72,11 @@ def get_client_name_from_language_and_path(language: str, path: str) -> str:
return 'Rust-Async'
if 'rust-sync' in path:
return 'Rust-Sync'
if language == 'c#':
if 'async' in path:
return 'C#-Async'
if 'sync' in path:
return 'C#-Sync'
# Default behavior for all languages (and Java fallback)
return get_client_name_from_language(language)

Expand Down
5 changes: 3 additions & 2 deletions config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ tagManagerId = "GTM-TKZ6J9R"
gitHubRepo = "https://github.com/redis/docs"

# Display and sort order for client examples
clientsExamples = ["Python", "Node.js", "Java-Sync", "Java-Async", "Java-Reactive", "Go", "C#", "RedisVL", "PHP", "Rust-Sync", "Rust-Async"]
clientsExamples = ["Python", "Node.js", "Java-Sync", "Java-Async", "Java-Reactive", "Go", "C#-Sync", "C#-Async", "RedisVL", "PHP", "Rust-Sync", "Rust-Async"]
searchService = "/convai/api/search-service"
ratingsService = "/docusight/api/rate"

Expand All @@ -64,7 +64,8 @@ rdi_current_version = "1.14.1"
"Java-async"={quickstartSlug="lettuce"}
"Java-reactive"={quickstartSlug="lettuce"}
"Go"={quickstartSlug="go"}
"C#"={quickstartSlug="dotnet"}
"C#-Sync"={quickstartSlug="dotnet"}
"C#-Async"={quickstartSlug="dotnet"}
"RedisVL"={quickstartSlug="redis-vl"}
"PHP"={quickstartSlug="php"}
"Rust-sync"={quickstartSlug="rust"}
Expand Down
44 changes: 15 additions & 29 deletions content/develop/clients/dotnet/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,45 +36,31 @@ dotnet add package NRedisStack

## Connect and test

Connect to localhost on port 6379.

```csharp
using NRedisStack;
using NRedisStack.RedisStackCommands;
using StackExchange.Redis;
//...
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
IDatabase db = redis.GetDatabase();
```
Add the following imports to your source file:

{{< clients-example set="landing" step="import" lang_filter="C#-Sync,C#-Async" >}}
{{< /clients-example >}}

Connect to localhost on port 6379. The client supports both synchronous and asynchronous commands.

{{< clients-example set="landing" step="connect" lang_filter="C#-Sync,C#-Async" >}}
{{< /clients-example >}}

You can test the connection by storing and retrieving a simple string.

```csharp
db.StringSet("foo", "bar");
Console.WriteLine(db.StringGet("foo")); // prints bar
```
{{< clients-example set="landing" step="set_get_string" lang_filter="C#-Sync,C#-Async" >}}
{{< /clients-example >}}

Store and retrieve a HashMap.

```csharp
var hash = new HashEntry[] {
new HashEntry("name", "John"),
new HashEntry("surname", "Smith"),
new HashEntry("company", "Redis"),
new HashEntry("age", "29"),
};
db.HashSet("user-session:123", hash);

var hashFields = db.HashGetAll("user-session:123");
Console.WriteLine(String.Join("; ", hashFields));
// Prints:
// name: John; surname: Smith; company: Redis; age: 29
```
{{< clients-example set="landing" step="set_get_hash" lang_filter="C#-Sync,C#-Async" >}}
{{< /clients-example >}}

## Redis Open Source modules

To access Redis Open Source capabilities, use the appropriate interface like this:

```
```cs
IBloomCommands bf = db.BF();
ICuckooCommands cf = db.CF();
ICmsCommands cms = db.CMS();
Expand Down
12 changes: 6 additions & 6 deletions content/develop/clients/dotnet/prob.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,15 @@ add. The following example adds some names to a Bloom filter representing
a list of users and checks for the presence or absence of users in the list.
Note that you must use the `BF()` method to access the Bloom filter commands.

{{< clients-example home_prob_dts bloom "C#" >}}
{{< clients-example home_prob_dts bloom "C#-Sync" >}}
{{< /clients-example >}}

A Cuckoo filter has similar features to a Bloom filter, but also supports
a deletion operation to remove hashes from a set, as shown in the example
below. Note that you must use the `CF()` method to access the Cuckoo filter
commands.

{{< clients-example home_prob_dts cuckoo "C#" >}}
{{< clients-example home_prob_dts cuckoo "C#-Sync" >}}
{{< /clients-example >}}

Which of these two data types you choose depends on your use case.
Expand All @@ -128,7 +128,7 @@ You can also merge two or more HyperLogLogs to find the cardinality of the
[union](https://en.wikipedia.org/wiki/Union_(set_theory)) of the sets they
represent.

{{< clients-example home_prob_dts hyperloglog "C#" >}}
{{< clients-example home_prob_dts hyperloglog "C#-Sync" >}}
{{< /clients-example >}}

The main benefit that HyperLogLogs offer is their very low
Expand Down Expand Up @@ -169,7 +169,7 @@ a Count-min sketch object, add data to it, and then query it.
Note that you must use the `CMS()` method to access the Count-min
sketch commands.

{{< clients-example home_prob_dts cms "C#" >}}
{{< clients-example home_prob_dts cms "C#-Sync" >}}
{{< /clients-example >}}

The advantage of using a CMS over keeping an exact count with a
Expand Down Expand Up @@ -202,7 +202,7 @@ shows how to merge two or more t-digest objects to query the combined
data set. Note that you must use the `TDIGEST()` method to access the
t-digest commands.

{{< clients-example home_prob_dts tdigest "C#" >}}
{{< clients-example home_prob_dts tdigest "C#-Sync" >}}
{{< /clients-example >}}

A t-digest object also supports several other related commands, such
Expand All @@ -225,5 +225,5 @@ top *k* items and query whether or not a given item is in the
list. Note that you must use the `TOPK()` method to access the
Top-K commands.

{{< clients-example home_prob_dts topk "C#" >}}
{{< clients-example home_prob_dts topk "C#-Sync" >}}
{{< /clients-example >}}
6 changes: 3 additions & 3 deletions content/develop/clients/dotnet/transpipe.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ versions of the standard command methods
buffered in the pipeline and only execute when you call the `Execute()`
method on the pipeline object.

{{< clients-example pipe_trans_tutorial basic_pipe "C#" >}}
{{< clients-example pipe_trans_tutorial basic_pipe "C#-Sync" >}}
{{< /clients-example >}}

## Execute a transaction
Expand All @@ -47,7 +47,7 @@ instance of the `Transaction` class, call async command methods
on that object, and then call the transaction object's
`Execute()` method to execute it.

{{< clients-example pipe_trans_tutorial basic_trans "C#" >}}
{{< clients-example pipe_trans_tutorial basic_trans "C#-Sync" >}}
{{< /clients-example >}}

## Watch keys for changes
Expand Down Expand Up @@ -77,7 +77,7 @@ For example, the `KeyNotExists` condition aborts the transaction
if a specified key exists or is added by another client while the
transaction executes:

{{< clients-example pipe_trans_tutorial trans_watch "C#" >}}
{{< clients-example pipe_trans_tutorial trans_watch "C#-Sync" >}}
{{< /clients-example >}}

You can also use a `When` condition on certain individual commands to
Expand Down
20 changes: 10 additions & 10 deletions content/develop/clients/dotnet/vecsets.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,22 @@ dotnet add package Microsoft.ML
In a new C# file, import the required classes. Note that the `#pragma`
directive suppresses warnings about the experimental status of the vector set API:

{{< clients-example set="home_vecsets" step="import" lang_filter="C#" >}}
{{< clients-example set="home_vecsets" step="import" lang_filter="C#-Sync" >}}
{{< /clients-example >}}

## Access the model

Use the `GetPredictionEngine()` helper function declared in the example below to load the model that creates the embeddings:

{{< clients-example set="home_vecsets" step="model" lang_filter="C#" >}}
{{< clients-example set="home_vecsets" step="model" lang_filter="C#-Sync" >}}
{{< /clients-example >}}

The `GetPredictionEngine()` function uses two classes, `TextData` and `TransformedTextData`,
to specify the `PredictionEngine` model. These have a very simple definition
and are required because the model expects the input and output to be
passed in named object fields:

{{< clients-example set="home_vecsets" step="data_classes" lang_filter="C#" >}}
{{< clients-example set="home_vecsets" step="data_classes" lang_filter="C#-Sync" >}}
{{< /clients-example >}}

Note that you must declare these classes at the end of the source file
Expand All @@ -73,15 +73,15 @@ The `GetEmbedding()` function declared below can then use this model to
generate an embedding from a section of text and return it as a `float[]` array,
which is the format required by the vector set API:

{{< clients-example set="home_vecsets" step="get_embedding" lang_filter="C#" >}}
{{< clients-example set="home_vecsets" step="get_embedding" lang_filter="C#-Sync" >}}
{{< /clients-example >}}

## Create the data

The example data is contained a `Dictionary` object with some brief
descriptions of famous people:

{{< clients-example set="home_vecsets" step="data" lang_filter="C#" >}}
{{< clients-example set="home_vecsets" step="data" lang_filter="C#-Sync" >}}
{{< /clients-example >}}

## Add the data to a vector set
Expand All @@ -99,7 +99,7 @@ The call to `VectorSetAdd()` also adds the `born` and `died` values from the
original dictionary as attribute data. You can access this during a query
or by using the [`VectorSetGetAttributesJson()`]({{< relref "/commands/vgetattr" >}}) method.

{{< clients-example set="home_vecsets" step="add_data" lang_filter="C#" >}}
{{< clients-example set="home_vecsets" step="add_data" lang_filter="C#-Sync" >}}
{{< /clients-example >}}

## Query the vector set
Expand All @@ -112,7 +112,7 @@ return elements of the set, ranked in order of similarity to the query.

Start with a simple query for "actors":

{{< clients-example set="home_vecsets" step="basic_query" lang_filter="C#" >}}
{{< clients-example set="home_vecsets" step="basic_query" lang_filter="C#-Sync" >}}
{{< /clients-example >}}

This returns the following list of elements (formatted slightly for clarity):
Expand All @@ -131,7 +131,7 @@ on the information contained in the embedding model.
You can use the `Count` property of `VectorSetSimilaritySearchRequest` to limit the
list of elements to just the most relevant few items:

{{< clients-example set="home_vecsets" step="limited_query" lang_filter="C#" >}}
{{< clients-example set="home_vecsets" step="limited_query" lang_filter="C#-Sync" >}}
{{< /clients-example >}}

The reason for using text embeddings rather than simple text search
Expand All @@ -141,7 +141,7 @@ different. For example, the word "entertainer" doesn't appear in any of the
descriptions but if you use it as a query, the actors and musicians are ranked
highest in the results list:

{{< clients-example set="home_vecsets" step="entertainer_query" lang_filter="C#" >}}
{{< clients-example set="home_vecsets" step="entertainer_query" lang_filter="C#-Sync" >}}
{{< /clients-example >}}

Similarly, if you use "science" as a query, you get the following results:
Expand All @@ -162,7 +162,7 @@ with `VectorSetSimilaritySearch()` to restrict the search further. For example,
repeat the "science" query, but this time limit the results to people
who died before the year 2000:

{{< clients-example set="home_vecsets" step="filtered_query" lang_filter="C#" >}}
{{< clients-example set="home_vecsets" step="filtered_query" lang_filter="C#-Sync" >}}
{{< /clients-example >}}

Note that the boolean filter expression is applied to items in the list
Expand Down
3 changes: 2 additions & 1 deletion data/components/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"docs": [],
"modules": [],
"clients": [
"nredisstack",
"nredisstack_sync",
"nredisstack_async",
"go_redis",
"node_redis",
"php",
Expand Down
15 changes: 15 additions & 0 deletions data/components/nredisstack_async.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"id": "nredisstack_async",
"type": "client",
"name": "NRedisStack_Async",
"language": "C#",
"label": "C#-Async",
"repository": {
"git_uri": "https://github.com/redis/NRedisStack"
},
"examples": {
"git_uri": "https://github.com/redis/NRedisStack",
"path": "tests/Doc/Async",
"pattern": "*.cs"
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"id": "nredisstack",
"id": "nredisstack_sync",
"type": "client",
"name": "NRedisStack",
"name": "NRedisStack_Sync",
"language": "C#",
"label": "C#",
"label": "C#-Sync",
"repository": {
"git_uri": "https://github.com/redis/NRedisStack"
},
Expand Down
63 changes: 63 additions & 0 deletions local_examples/client-specific/dotnet-async/AsyncLandingExample.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// EXAMPLE: landing
// STEP_START import
using NRedisStack;
using NRedisStack.RedisStackCommands;
using StackExchange.Redis;
// STEP_END
// REMOVE_START
using NRedisStack.Tests;
using System.Threading.Tasks;

namespace Doc;

[Collection("DocsTests")]
// REMOVE_END

public class AsyncLandingExample
// REMOVE_START
: AbstractNRedisStackTest, IDisposable
// REMOVE_END
{
// REMOVE_START
public AsyncLandingExample(EndpointsFixture fixture) : base(fixture) { }

[SkippableFact]
// REMOVE_END
public async Task Run()
{
//REMOVE_START
// This is needed because we're constructing ConfigurationOptions in the test before calling GetConnection
SkipIfTargetConnectionDoesNotExist(EndpointsFixture.Env.Standalone);
var _ = GetCleanDatabase(EndpointsFixture.Env.Standalone);
//REMOVE_END
// STEP_START connect
var muxer = await ConnectionMultiplexer.ConnectAsync("localhost:6379");
var db = muxer.GetDatabase();
// STEP_END
//REMOVE_START
// Clear any keys here before using them in tests.
await db.KeyDeleteAsync(new RedisKey[] { "bike:1", "foo", "user-session:123" });
//REMOVE_END

// STEP_START set_get_string
await db.StringSetAsync("foo", "bar");
string? fooResult = await db.StringGetAsync("foo");
Console.WriteLine(fooResult); // >>> bar
// STEP_END

// STEP_START set_get_hash
var hash = new HashEntry[] {
new HashEntry("name", "John"),
new HashEntry("surname", "Smith"),
new HashEntry("company", "Redis"),
new HashEntry("age", "29"),
};
await db.HashSetAsync("user-session:123", hash);

var hashFields = await db.HashGetAllAsync("user-session:123");
Console.WriteLine(String.Join("; ", hashFields));
// >>> name: John; surname: Smith; company: Redis; age: 29
// STEP_END
}
}

Loading