Skip to content

Commit a3ed59f

Browse files
committed
- add SVS integration tests
- fix LeanVec command typo
1 parent c637f63 commit a3ed59f

File tree

3 files changed

+83
-5
lines changed

3 files changed

+83
-5
lines changed

src/NRedisStack/Search/Schema.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -556,8 +556,8 @@ internal override void AddDirectAttributes(List<object> args)
556556
VectorCompressionAlgorithm.LVQ4 => "LVQ4",
557557
VectorCompressionAlgorithm.LVQ4x4 => "LVQ4x4",
558558
VectorCompressionAlgorithm.LVQ4x8 => "LVQ4x8",
559-
VectorCompressionAlgorithm.LeanVec4x8 => "LEAN_VEC4x8",
560-
VectorCompressionAlgorithm.LeanVec8x8 => "LEAN_VEC8x8",
559+
VectorCompressionAlgorithm.LeanVec4x8 => "LeanVec4x8",
560+
VectorCompressionAlgorithm.LeanVec8x8 => "LeanVec8x8",
561561
_ => CompressionAlgorithm.ToString(), // fallback
562562
});
563563
}

tests/NRedisStack.Tests/AbstractNRedisStackTest.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@
33
using System.Runtime.CompilerServices;
44
using StackExchange.Redis;
55
using Xunit;
6+
using Xunit.Abstractions;
7+
68
namespace NRedisStack.Tests;
79

810
public abstract class AbstractNRedisStackTest : IClassFixture<EndpointsFixture>, IAsyncLifetime
911
{
1012
protected internal EndpointsFixture EndpointsFixture;
13+
private readonly ITestOutputHelper? log;
14+
15+
protected void Log(string message) => log?.WriteLine(message); // TODO: DISH overload in net9? net10?
1116

1217
protected readonly ConfigurationOptions DefaultConnectionConfig = new()
1318
{
@@ -16,9 +21,10 @@ public abstract class AbstractNRedisStackTest : IClassFixture<EndpointsFixture>,
1621
AllowAdmin = true,
1722
};
1823

19-
protected internal AbstractNRedisStackTest(EndpointsFixture endpointsFixture)
24+
protected internal AbstractNRedisStackTest(EndpointsFixture endpointsFixture, ITestOutputHelper? log = null)
2025
{
2126
this.EndpointsFixture = endpointsFixture;
27+
this.log = log;
2228
}
2329

2430
protected ConnectionMultiplexer GetConnection(string endpointId = EndpointsFixture.Env.Standalone) => EndpointsFixture.GetConnectionById(this.DefaultConnectionConfig, endpointId);

tests/NRedisStack.Tests/Search/IndexCreationTests.cs

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1+
using System.Runtime.InteropServices;
12
using StackExchange.Redis;
23
using NRedisStack.Search;
34
using NRedisStack.RedisStackCommands;
45
using Xunit;
56
using NetTopologySuite.Geometries;
7+
using Xunit.Abstractions;
68

79
namespace NRedisStack.Tests.Search;
810

911
public class IndexCreationTests : AbstractNRedisStackTest, IDisposable
1012
{
1113
private readonly string index = "MISSING_EMPTY_INDEX";
1214

13-
public IndexCreationTests(EndpointsFixture endpointsFixture) : base(endpointsFixture)
15+
public IndexCreationTests(EndpointsFixture endpointsFixture, ITestOutputHelper log) : base(endpointsFixture, log)
1416
{
1517
}
1618

19+
private readonly ITestOutputHelper log;
1720
private static readonly string INDEXMISSING = "INDEXMISSING";
1821
private static readonly string INDEXEMPTY = "INDEXEMPTY";
1922
private static readonly string SORTABLE = "SORTABLE";
@@ -144,6 +147,7 @@ public void TestCreateFloat16VectorField(string endpointId)
144147
["DIM"] = "4",
145148
["DISTANCE_METRIC"] = "L2",
146149
});
150+
147151
Assert.True(ft.Create("idx", new FTCreateParams(), schema));
148152

149153
short[] vec1 = new short[] { 2, 1, 2, 2, 2 };
@@ -168,6 +172,74 @@ public void TestCreateFloat16VectorField(string endpointId)
168172
Assert.Equal(2, res.TotalResults);
169173
}
170174

175+
[SkipIfRedis(Comparison.LessThan, "8.1.240")]
176+
[MemberData(nameof(EndpointsFixture.Env.StandaloneOnly), MemberType = typeof(EndpointsFixture.Env))]
177+
public void TestCreate_Float16_Int32_VectorField_Svs(string endpointId)
178+
{
179+
IDatabase db = GetCleanDatabase(endpointId);
180+
var ft = db.FT(2);
181+
var schema = new Schema().AddSvsVanamaVectorField("v", Schema.VectorField.VectorType.FLOAT16, 5,
182+
Schema.VectorField.VectorDistanceMetric.EuclideanDistance)
183+
.AddSvsVanamaVectorField("v2", Schema.VectorField.VectorType.FLOAT32, 4,
184+
Schema.VectorField.VectorDistanceMetric.EuclideanDistance);
185+
186+
var cmd = SearchCommandBuilder.Create("idx", FTCreateParams.CreateParams(), schema).ToString();
187+
Log(cmd);
188+
189+
Assert.True(ft.Create("idx", new FTCreateParams(), schema));
190+
191+
byte[] vec1ToBytes = MemoryMarshal.AsBytes(stackalloc short[] { 2, 1, 2, 2, 2 }).ToArray();
192+
byte[] vec2ToBytes = MemoryMarshal.AsBytes(stackalloc int[] { 1, 2, 2, 2 }).ToArray();
193+
194+
var entries = new HashEntry[] { new HashEntry("v", vec1ToBytes), new HashEntry("v2", vec2ToBytes) };
195+
db.HashSet("a", entries);
196+
db.HashSet("b", entries);
197+
db.HashSet("c", entries);
198+
199+
var q = new Query("*=>[KNN 2 @v $vec]").ReturnFields("__v_score");
200+
var res = ft.Search("idx", q.AddParam("vec", vec1ToBytes));
201+
Assert.Equal(2, res.TotalResults);
202+
203+
q = new Query("*=>[KNN 2 @v2 $vec]").ReturnFields("__v_score");
204+
res = ft.Search("idx", q.AddParam("vec", vec2ToBytes));
205+
Assert.Equal(2, res.TotalResults);
206+
}
207+
208+
[SkipIfRedis(Comparison.LessThan, "8.1.240")]
209+
[MemberData(nameof(EndpointsFixture.Env.StandaloneOnly), MemberType = typeof(EndpointsFixture.Env))]
210+
public void TestCreate_Float16_Int32_VectorField_Svs_WithCompression(string endpointId)
211+
{
212+
IDatabase db = GetCleanDatabase(endpointId);
213+
var ft = db.FT(2);
214+
var schema = new Schema().AddSvsVanamaVectorField("v", Schema.VectorField.VectorType.FLOAT16, 5,
215+
Schema.VectorField.VectorDistanceMetric.EuclideanDistance,
216+
reducedDimensions: 2, compressionAlgorithm: Schema.VectorField.VectorCompressionAlgorithm.LeanVec4x8)
217+
.AddSvsVanamaVectorField("v2", Schema.VectorField.VectorType.FLOAT32, 4,
218+
Schema.VectorField.VectorDistanceMetric.EuclideanDistance,
219+
compressionAlgorithm: Schema.VectorField.VectorCompressionAlgorithm.LVQ4);
220+
221+
var cmd = SearchCommandBuilder.Create("idx", FTCreateParams.CreateParams(), schema).ToString();
222+
Log(cmd);
223+
224+
Assert.True(ft.Create("idx", new FTCreateParams(), schema));
225+
226+
byte[] vec1ToBytes = MemoryMarshal.AsBytes(stackalloc short[] { 2, 1, 2, 2, 2 }).ToArray();
227+
byte[] vec2ToBytes = MemoryMarshal.AsBytes(stackalloc int[] { 1, 2, 2, 2 }).ToArray();
228+
229+
var entries = new HashEntry[] { new HashEntry("v", vec1ToBytes), new HashEntry("v2", vec2ToBytes) };
230+
db.HashSet("a", entries);
231+
db.HashSet("b", entries);
232+
db.HashSet("c", entries);
233+
234+
var q = new Query("*=>[KNN 2 @v $vec]").ReturnFields("__v_score");
235+
var res = ft.Search("idx", q.AddParam("vec", vec1ToBytes));
236+
Assert.Equal(2, res.TotalResults);
237+
238+
q = new Query("*=>[KNN 2 @v2 $vec]").ReturnFields("__v_score");
239+
res = ft.Search("idx", q.AddParam("vec", vec2ToBytes));
240+
Assert.Equal(2, res.TotalResults);
241+
}
242+
171243
[SkipIfRedis(Comparison.LessThan, "7.9.0")]
172244
[MemberData(nameof(EndpointsFixture.Env.StandaloneOnly), MemberType = typeof(EndpointsFixture.Env))]
173245
public void TestCreateInt8VectorField(string endpointId)
@@ -203,7 +275,7 @@ public void TestCreateInt8VectorField(string endpointId)
203275
res = ft.Search("idx", q.AddParam("vec", vec2));
204276
Assert.Equal(2, res.TotalResults);
205277
}
206-
278+
207279
[Fact]
208280
public void TestMissingSortableFieldCommandArgs()
209281
{

0 commit comments

Comments
 (0)