Skip to content

Commit c3f2d33

Browse files
authored
Vector Search and Semantic Caching (#417)
1 parent 695a337 commit c3f2d33

File tree

103 files changed

+4996
-464
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+4996
-464
lines changed

.gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.onnx filter=lfs diff=lfs merge=lfs -text
2+
src/Redis.OM.Vectorizers.AllMiniLML6V2/Resources/vocab.txt filter=lfs diff=lfs merge=lfs -text

.github/workflows/dotnet-core.yml

+2
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@ jobs:
1111
runs-on: ubuntu-latest
1212
steps:
1313
- uses: actions/checkout@v2
14+
with:
15+
lfs: true
1416
- name: execute
1517
run: docker-compose -f ./docker/docker-compose.yaml run dotnet

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -388,3 +388,5 @@ FodyWeavers.xsd
388388
# JetBrains Rider
389389
.idea/
390390
*.sln.iml
391+
392+
test/Redis.OM.Unit.Tests/appsettings.json.local

README.md

+104
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,110 @@ customers.Where(x => x.LastName == "Bond" && x.FirstName == "James");
288288
customers.Where(x=>x.NickNames.Contains("Jim"));
289289
```
290290

291+
### Vectors
292+
293+
Redis OM .NET also supports storing and querying Vectors stored in Redis.
294+
295+
A `Vector<T>` is a representation of an object that can be transformed into a vector by a Vectorizer.
296+
297+
A `VectorizerAttribute` is the abstract class you use to decorate your Vector fields, it is responsible for defining the logic to convert the object's that `Vector<T>` is a container for into actual vector embeddings needed. In the package `Redis.OM.Vectorizers` we provide vectorizers for HuggingFace, OpenAI, and AzureOpenAI to allow you to easily integrate them into your workflows.
298+
299+
#### Define a Vector in your Model.
300+
301+
To define a vector in your model, simply decorate a `Vector<T>` field with an `Indexed` attribute which defines the algorithm and algorithmic parameters and a `Vectorizer` attribute which defines the shape of the vectors, (in this case we'll use OpenAI):
302+
303+
```cs
304+
[Document(StorageType = StorageType.Json)]
305+
public class OpenAICompletionResponse
306+
{
307+
[RedisIdField]
308+
public string Id { get; set; }
309+
310+
[Indexed(DistanceMetric = DistanceMetric.COSINE, Algorithm = VectorAlgorithm.HNSW, M = 16)]
311+
[OpenAIVectorizer]
312+
public Vector<string> Prompt { get; set; }
313+
314+
public string Response { get; set; }
315+
316+
[Indexed]
317+
public string Language { get; set; }
318+
319+
[Indexed]
320+
public DateTime TimeStamp { get; set; }
321+
}
322+
```
323+
324+
#### Insert Vectors into Redis
325+
326+
With the vector defined in our model, all we need to do is create Vectors of the generic type, and insert them with our model. Using our `RedisCollection`, you can do this by simply using `Insert`:
327+
328+
```cs
329+
var collection = _provider.RedisCollection<OpenAICompletionResponse>();
330+
var completionResult = new OpenAICompletionResponse
331+
{
332+
Language = "en_us",
333+
Prompt = Vector.Of("What is the Capital of France?"),
334+
Response = "Paris",
335+
TimeStamp = DateTime.Now - TimeSpan.FromHours(3)
336+
};
337+
collection.Insert(completionResult);
338+
```
339+
340+
The Vectorizer will manage the embedding generation for you without you having to intervene.
341+
342+
#### Query Vectors in Redis
343+
344+
To query vector fields in Redis, all you need to do is use the `VectorRange` method on a vector within our normal LINQ queries, and/or use the `NearestNeighbors` with whatever other filters you want to use, here's some examples:
345+
346+
```cs
347+
var prompt = "What really is the Capital of France?";
348+
349+
// simple vector range, find first within .15
350+
var result = collection.First(x => x.Prompt.VectorRange(prompt, .15));
351+
352+
// simple nearest neighbors query, finds first nearest neighbor
353+
result = collection.NearestNeighbors(x => x.Prompt, 1, prompt).First();
354+
355+
// hybrid query, pre-filters result set for english responses, then runs a nearest neighbors search.
356+
result = collection.Where(x=>x.Language == "en_us").NearestNeighbors(x => x.Prompt, 1, prompt).First();
357+
358+
// hybrid query, pre-filters responses newer than 4 hours, and finds first result within .15
359+
var ts = DateTimeOffset.Now - TimeSpan.FromHours(4);
360+
result = collection.First(x=>x.TimeStamp > ts && x.Prompt.VectorRange(prompt, .15));
361+
```
362+
363+
#### What Happens to the Embeddings?
364+
365+
With Redis OM, the embeddings can be completely transparent to you, they are generated and bound to the `Vector<T>` when you query/insert your vectors. If however you needed your embedding after the insertion/Query, they are available at `Vector<T>.Embedding`, and be queried either as the raw bytes, as an array of doubles or as an array of floats (depending on your vectorizer).
366+
367+
#### Configuration
368+
369+
The Vectorizers provided by the `Redis.OM.Vectorizers` package have some configuration parameters that it will pull in either from your `appsettings.json` file, or your environment variables (with your appsettings taking precedence).
370+
371+
| Configuration Parameter | Description |
372+
|-------------------------------- |-----------------------------------------------|
373+
| REDIS_OM_HF_TOKEN | HuggingFace Authorization token. |
374+
| REDIS_OM_OAI_TOKEN | OpenAI Authorization token |
375+
| REDIS_OM_OAI_API_URL | OpenAI URL |
376+
| REDIS_OM_AZURE_OAI_TOKEN | Azure OpenAI api key |
377+
| REDIS_OM_AZURE_OAI_RESOURCE_NAME | Azure resource name |
378+
| REDIS_OM_AZURE_OAI_DEPLOYMENT_NAME | Azure deployment |
379+
380+
### Semantic Caching
381+
382+
Redis OM also provides the ability to use Semantic Caching, as well as providers for OpenAI, HuggingFace, and Azure OpenAI to perform semantic caching. To use a Semantic Cache, simply pull one out of the RedisConnectionProvider and use `Store` to insert items, and `GetSimilar` to retrieve items. For example:
383+
384+
```cs
385+
var cache = _provider.OpenAISemanticCache(token, threshold: .15);
386+
cache.Store("What is the capital of France?", "Paris");
387+
var res = cache.GetSimilar("What really is the capital of France?").First();
388+
```
389+
390+
### ML.NET Based Vectorizers
391+
392+
We also provide the packages `Redis.OM.Vectorizers.ResNet18` and `Redis.OM.Vectorizers.AllMiniLML6V2` which have embedded models / ML Pipelines in them to
393+
allow you to easily Vectorize Images and Sentences respectively without the need to depend on an external API.
394+
291395
### 🖩 Aggregations
292396

293397
We can also run aggregations on the customer object, again using expressions in LINQ:

Redis.OM.sln

+58-54
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Redis.OM.POC", "src\Redis.O
1010
EndProject
1111
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Redis.OM.Unit.Tests", "test\Redis.OM.Unit.Tests\Redis.OM.Unit.Tests.csproj", "{570BF479-BCF4-4D1B-A702-2234CA0A3E7D}"
1212
EndProject
13-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Redis.OM.Test.ConsoleApp", "test\Redis.OM.Test.ConsoleApp\Redis.OM.Test.ConsoleApp.csproj", "{FC7E5ED3-51AC-45E6-A178-6287C9227975}"
13+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Redis.OM.Vectorizers", "src\Redis.OM.Vectorizers\Redis.OM.Vectorizers.csproj", "{4B9F4623-3126-48B7-B690-F28F702A4717}"
1414
EndProject
15-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Redis.OM.Analyzer", "src\Redis.OM.Analyzer\Redis.OM.Analyzer.csproj", "{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1}"
15+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Vectorizers", "Vectorizers", "{452DC80B-8195-44E8-A376-C246619492A8}"
1616
EndProject
17-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Redis.OM.AspNetCore", "src\Redis.OM.AspNetCore\Redis.OM.AspNetCore.csproj", "{230ED77D-D625-43BC-94D6-6BDBACEA3EAF}"
17+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Redis.OM.Vectorizers.AllMiniLML6V2", "src\Redis.OM.Vectorizers.AllMiniLML6V2\Redis.OM.Vectorizers.AllMiniLML6V2.csproj", "{081DEE32-9B26-44C6-B377-456E862D3813}"
1818
EndProject
19-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Redis.OM.Test.AspDotnetCore", "test\Redis.OM.Test.AspDotnetCore\Redis.OM.Test.AspDotnetCore.csproj", "{3F609AB2-1492-4EBE-9FF2-B47829307E9E}"
19+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Redis.OM.Vectorizer.Tests", "test\Redis.OM.Vectorizer.Tests\Redis.OM.Vectorizer.Tests.csproj", "{7C3E1D79-408C-45E9-931C-12195DFA268D}"
20+
EndProject
21+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Redis.OM.Vectorizers.Resnet18", "src\Redis.OM.Vectorizers.Resnet18\Redis.OM.Vectorizers.Resnet18.csproj", "{FE22706B-9A28-4045-9581-2058F32C4193}"
2022
EndProject
2123
Global
2224
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -64,63 +66,65 @@ Global
6466
{570BF479-BCF4-4D1B-A702-2234CA0A3E7D}.Release|x64.Build.0 = Release|Any CPU
6567
{570BF479-BCF4-4D1B-A702-2234CA0A3E7D}.Release|x86.ActiveCfg = Release|Any CPU
6668
{570BF479-BCF4-4D1B-A702-2234CA0A3E7D}.Release|x86.Build.0 = Release|Any CPU
67-
{FC7E5ED3-51AC-45E6-A178-6287C9227975}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
68-
{FC7E5ED3-51AC-45E6-A178-6287C9227975}.Debug|Any CPU.Build.0 = Debug|Any CPU
69-
{FC7E5ED3-51AC-45E6-A178-6287C9227975}.Debug|x64.ActiveCfg = Debug|Any CPU
70-
{FC7E5ED3-51AC-45E6-A178-6287C9227975}.Debug|x64.Build.0 = Debug|Any CPU
71-
{FC7E5ED3-51AC-45E6-A178-6287C9227975}.Debug|x86.ActiveCfg = Debug|Any CPU
72-
{FC7E5ED3-51AC-45E6-A178-6287C9227975}.Debug|x86.Build.0 = Debug|Any CPU
73-
{FC7E5ED3-51AC-45E6-A178-6287C9227975}.Release|Any CPU.ActiveCfg = Release|Any CPU
74-
{FC7E5ED3-51AC-45E6-A178-6287C9227975}.Release|Any CPU.Build.0 = Release|Any CPU
75-
{FC7E5ED3-51AC-45E6-A178-6287C9227975}.Release|x64.ActiveCfg = Release|Any CPU
76-
{FC7E5ED3-51AC-45E6-A178-6287C9227975}.Release|x64.Build.0 = Release|Any CPU
77-
{FC7E5ED3-51AC-45E6-A178-6287C9227975}.Release|x86.ActiveCfg = Release|Any CPU
78-
{FC7E5ED3-51AC-45E6-A178-6287C9227975}.Release|x86.Build.0 = Release|Any CPU
79-
{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
80-
{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
81-
{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1}.Debug|x64.ActiveCfg = Debug|Any CPU
82-
{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1}.Debug|x64.Build.0 = Debug|Any CPU
83-
{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1}.Debug|x86.ActiveCfg = Debug|Any CPU
84-
{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1}.Debug|x86.Build.0 = Debug|Any CPU
85-
{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
86-
{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1}.Release|Any CPU.Build.0 = Release|Any CPU
87-
{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1}.Release|x64.ActiveCfg = Release|Any CPU
88-
{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1}.Release|x64.Build.0 = Release|Any CPU
89-
{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1}.Release|x86.ActiveCfg = Release|Any CPU
90-
{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1}.Release|x86.Build.0 = Release|Any CPU
91-
{230ED77D-D625-43BC-94D6-6BDBACEA3EAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
92-
{230ED77D-D625-43BC-94D6-6BDBACEA3EAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
93-
{230ED77D-D625-43BC-94D6-6BDBACEA3EAF}.Debug|x64.ActiveCfg = Debug|Any CPU
94-
{230ED77D-D625-43BC-94D6-6BDBACEA3EAF}.Debug|x64.Build.0 = Debug|Any CPU
95-
{230ED77D-D625-43BC-94D6-6BDBACEA3EAF}.Debug|x86.ActiveCfg = Debug|Any CPU
96-
{230ED77D-D625-43BC-94D6-6BDBACEA3EAF}.Debug|x86.Build.0 = Debug|Any CPU
97-
{230ED77D-D625-43BC-94D6-6BDBACEA3EAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
98-
{230ED77D-D625-43BC-94D6-6BDBACEA3EAF}.Release|Any CPU.Build.0 = Release|Any CPU
99-
{230ED77D-D625-43BC-94D6-6BDBACEA3EAF}.Release|x64.ActiveCfg = Release|Any CPU
100-
{230ED77D-D625-43BC-94D6-6BDBACEA3EAF}.Release|x64.Build.0 = Release|Any CPU
101-
{230ED77D-D625-43BC-94D6-6BDBACEA3EAF}.Release|x86.ActiveCfg = Release|Any CPU
102-
{230ED77D-D625-43BC-94D6-6BDBACEA3EAF}.Release|x86.Build.0 = Release|Any CPU
103-
{3F609AB2-1492-4EBE-9FF2-B47829307E9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
104-
{3F609AB2-1492-4EBE-9FF2-B47829307E9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
105-
{3F609AB2-1492-4EBE-9FF2-B47829307E9E}.Debug|x64.ActiveCfg = Debug|Any CPU
106-
{3F609AB2-1492-4EBE-9FF2-B47829307E9E}.Debug|x64.Build.0 = Debug|Any CPU
107-
{3F609AB2-1492-4EBE-9FF2-B47829307E9E}.Debug|x86.ActiveCfg = Debug|Any CPU
108-
{3F609AB2-1492-4EBE-9FF2-B47829307E9E}.Debug|x86.Build.0 = Debug|Any CPU
109-
{3F609AB2-1492-4EBE-9FF2-B47829307E9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
110-
{3F609AB2-1492-4EBE-9FF2-B47829307E9E}.Release|Any CPU.Build.0 = Release|Any CPU
111-
{3F609AB2-1492-4EBE-9FF2-B47829307E9E}.Release|x64.ActiveCfg = Release|Any CPU
112-
{3F609AB2-1492-4EBE-9FF2-B47829307E9E}.Release|x64.Build.0 = Release|Any CPU
113-
{3F609AB2-1492-4EBE-9FF2-B47829307E9E}.Release|x86.ActiveCfg = Release|Any CPU
114-
{3F609AB2-1492-4EBE-9FF2-B47829307E9E}.Release|x86.Build.0 = Release|Any CPU
69+
{4B9F4623-3126-48B7-B690-F28F702A4717}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
70+
{4B9F4623-3126-48B7-B690-F28F702A4717}.Debug|Any CPU.Build.0 = Debug|Any CPU
71+
{4B9F4623-3126-48B7-B690-F28F702A4717}.Debug|x64.ActiveCfg = Debug|Any CPU
72+
{4B9F4623-3126-48B7-B690-F28F702A4717}.Debug|x64.Build.0 = Debug|Any CPU
73+
{4B9F4623-3126-48B7-B690-F28F702A4717}.Debug|x86.ActiveCfg = Debug|Any CPU
74+
{4B9F4623-3126-48B7-B690-F28F702A4717}.Debug|x86.Build.0 = Debug|Any CPU
75+
{4B9F4623-3126-48B7-B690-F28F702A4717}.Release|Any CPU.ActiveCfg = Release|Any CPU
76+
{4B9F4623-3126-48B7-B690-F28F702A4717}.Release|Any CPU.Build.0 = Release|Any CPU
77+
{4B9F4623-3126-48B7-B690-F28F702A4717}.Release|x64.ActiveCfg = Release|Any CPU
78+
{4B9F4623-3126-48B7-B690-F28F702A4717}.Release|x64.Build.0 = Release|Any CPU
79+
{4B9F4623-3126-48B7-B690-F28F702A4717}.Release|x86.ActiveCfg = Release|Any CPU
80+
{4B9F4623-3126-48B7-B690-F28F702A4717}.Release|x86.Build.0 = Release|Any CPU
81+
{081DEE32-9B26-44C6-B377-456E862D3813}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
82+
{081DEE32-9B26-44C6-B377-456E862D3813}.Debug|Any CPU.Build.0 = Debug|Any CPU
83+
{081DEE32-9B26-44C6-B377-456E862D3813}.Debug|x64.ActiveCfg = Debug|Any CPU
84+
{081DEE32-9B26-44C6-B377-456E862D3813}.Debug|x64.Build.0 = Debug|Any CPU
85+
{081DEE32-9B26-44C6-B377-456E862D3813}.Debug|x86.ActiveCfg = Debug|Any CPU
86+
{081DEE32-9B26-44C6-B377-456E862D3813}.Debug|x86.Build.0 = Debug|Any CPU
87+
{081DEE32-9B26-44C6-B377-456E862D3813}.Release|Any CPU.ActiveCfg = Release|Any CPU
88+
{081DEE32-9B26-44C6-B377-456E862D3813}.Release|Any CPU.Build.0 = Release|Any CPU
89+
{081DEE32-9B26-44C6-B377-456E862D3813}.Release|x64.ActiveCfg = Release|Any CPU
90+
{081DEE32-9B26-44C6-B377-456E862D3813}.Release|x64.Build.0 = Release|Any CPU
91+
{081DEE32-9B26-44C6-B377-456E862D3813}.Release|x86.ActiveCfg = Release|Any CPU
92+
{081DEE32-9B26-44C6-B377-456E862D3813}.Release|x86.Build.0 = Release|Any CPU
93+
{7C3E1D79-408C-45E9-931C-12195DFA268D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
94+
{7C3E1D79-408C-45E9-931C-12195DFA268D}.Debug|Any CPU.Build.0 = Debug|Any CPU
95+
{7C3E1D79-408C-45E9-931C-12195DFA268D}.Debug|x64.ActiveCfg = Debug|Any CPU
96+
{7C3E1D79-408C-45E9-931C-12195DFA268D}.Debug|x64.Build.0 = Debug|Any CPU
97+
{7C3E1D79-408C-45E9-931C-12195DFA268D}.Debug|x86.ActiveCfg = Debug|Any CPU
98+
{7C3E1D79-408C-45E9-931C-12195DFA268D}.Debug|x86.Build.0 = Debug|Any CPU
99+
{7C3E1D79-408C-45E9-931C-12195DFA268D}.Release|Any CPU.ActiveCfg = Release|Any CPU
100+
{7C3E1D79-408C-45E9-931C-12195DFA268D}.Release|Any CPU.Build.0 = Release|Any CPU
101+
{7C3E1D79-408C-45E9-931C-12195DFA268D}.Release|x64.ActiveCfg = Release|Any CPU
102+
{7C3E1D79-408C-45E9-931C-12195DFA268D}.Release|x64.Build.0 = Release|Any CPU
103+
{7C3E1D79-408C-45E9-931C-12195DFA268D}.Release|x86.ActiveCfg = Release|Any CPU
104+
{7C3E1D79-408C-45E9-931C-12195DFA268D}.Release|x86.Build.0 = Release|Any CPU
105+
{FE22706B-9A28-4045-9581-2058F32C4193}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
106+
{FE22706B-9A28-4045-9581-2058F32C4193}.Debug|Any CPU.Build.0 = Debug|Any CPU
107+
{FE22706B-9A28-4045-9581-2058F32C4193}.Debug|x64.ActiveCfg = Debug|Any CPU
108+
{FE22706B-9A28-4045-9581-2058F32C4193}.Debug|x64.Build.0 = Debug|Any CPU
109+
{FE22706B-9A28-4045-9581-2058F32C4193}.Debug|x86.ActiveCfg = Debug|Any CPU
110+
{FE22706B-9A28-4045-9581-2058F32C4193}.Debug|x86.Build.0 = Debug|Any CPU
111+
{FE22706B-9A28-4045-9581-2058F32C4193}.Release|Any CPU.ActiveCfg = Release|Any CPU
112+
{FE22706B-9A28-4045-9581-2058F32C4193}.Release|Any CPU.Build.0 = Release|Any CPU
113+
{FE22706B-9A28-4045-9581-2058F32C4193}.Release|x64.ActiveCfg = Release|Any CPU
114+
{FE22706B-9A28-4045-9581-2058F32C4193}.Release|x64.Build.0 = Release|Any CPU
115+
{FE22706B-9A28-4045-9581-2058F32C4193}.Release|x86.ActiveCfg = Release|Any CPU
116+
{FE22706B-9A28-4045-9581-2058F32C4193}.Release|x86.Build.0 = Release|Any CPU
115117
EndGlobalSection
116118
GlobalSection(SolutionProperties) = preSolution
117119
HideSolutionNode = FALSE
118120
EndGlobalSection
119121
GlobalSection(NestedProjects) = preSolution
120122
{7994382C-28EF-4F55-9B6D-810D35247816} = {8D9ECCFF-E022-4B68-BB43-228CEA248DEC}
121123
{E3A31119-E4F1-4793-B5C2-ED2D51502B01} = {8D9ECCFF-E022-4B68-BB43-228CEA248DEC}
122-
{44FAD9BB-C6DF-402C-BCE7-64E7C674F8D1} = {8D9ECCFF-E022-4B68-BB43-228CEA248DEC}
123-
{230ED77D-D625-43BC-94D6-6BDBACEA3EAF} = {8D9ECCFF-E022-4B68-BB43-228CEA248DEC}
124+
{452DC80B-8195-44E8-A376-C246619492A8} = {8D9ECCFF-E022-4B68-BB43-228CEA248DEC}
125+
{4B9F4623-3126-48B7-B690-F28F702A4717} = {452DC80B-8195-44E8-A376-C246619492A8}
126+
{081DEE32-9B26-44C6-B377-456E862D3813} = {452DC80B-8195-44E8-A376-C246619492A8}
127+
{FE22706B-9A28-4045-9581-2058F32C4193} = {452DC80B-8195-44E8-A376-C246619492A8}
124128
EndGlobalSection
125129
GlobalSection(ExtensibilityGlobals) = postSolution
126130
SolutionGuid = {E5752441-184B-4F17-BAD0-93823AC68607}

dockerfile

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
FROM mcr.microsoft.com/dotnet/sdk:6.0
2-
1+
FROM mcr.microsoft.com/dotnet/sdk:7.0
32

43
WORKDIR /app
54
ADD . /app
65

76
RUN ls /app
87
RUN dotnet restore /app/Redis.OM.sln
98

10-
ENTRYPOINT ["dotnet","test"]
9+
ENTRYPOINT ["dotnet", "test", "--framework", "net7.0" ]

src/Redis.OM.POC/RedisCommands.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ public static long XAck(this IRedisConnection connection, string streamId, strin
565565
public static async Task<string?> XAddAsync(this IRedisConnection connection, string streamId, object message, string messageId = "*", int maxLen = -1, string minId = "", bool trimApprox = true, bool makeStream = true)
566566
{
567567
var kvps = message.BuildHashSet();
568-
var args = new List<string> { streamId };
568+
var args = new List<object> { streamId };
569569
if (!makeStream)
570570
{
571571
args.Add("NOMKSTREAM");
@@ -611,7 +611,7 @@ public static long XAck(this IRedisConnection connection, string streamId, strin
611611
public static string? XAdd(this IRedisConnection connection, string streamId, object message, string messageId = "*", int maxLen = -1, string minId = "", bool trimApprox = true, bool makeStream = true)
612612
{
613613
var kvps = message.BuildHashSet();
614-
var args = new List<string> { streamId };
614+
var args = new List<object> { streamId };
615615
if (!makeStream)
616616
{
617617
args.Add("NOMKSTREAM");

0 commit comments

Comments
 (0)