From 486b6c2548379a5c396f8744ebb385ebe5080d2a Mon Sep 17 00:00:00 2001 From: ofekshenawa Date: Thu, 13 Mar 2025 12:03:05 +0200 Subject: [PATCH 1/3] Add vector types INT8 and UINT8 test --- search_test.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/search_test.go b/search_test.go index d309b1a8be..9b6563e80f 100644 --- a/search_test.go +++ b/search_test.go @@ -1902,4 +1902,62 @@ var _ = Describe("RediSearch commands Resp 3", Label("search"), func() { Expect(res2).ToNot(BeEmpty()) }).ShouldNot(Panic()) }) + + It("should FTCreate VECTOR with int8 and uint8 types", Label("search", "ftcreate"), func() { + ctx := context.TODO() + + // Define INT8 vector field + hnswOptionsInt8 := &redis.FTHNSWOptions{ + Type: "INT8", + Dim: 2, + DistanceMetric: "L2", + } + + // Define UINT8 vector field + hnswOptionsUint8 := &redis.FTHNSWOptions{ + Type: "UINT8", + Dim: 2, + DistanceMetric: "L2", + } + + // Create index with INT8 and UINT8 vector fields + val, err := client.FTCreate(ctx, "idx1", + &redis.FTCreateOptions{}, + &redis.FieldSchema{FieldName: "int8_vector", FieldType: redis.SearchFieldTypeVector, VectorArgs: &redis.FTVectorArgs{HNSWOptions: hnswOptionsInt8}}, + &redis.FieldSchema{FieldName: "uint8_vector", FieldType: redis.SearchFieldTypeVector, VectorArgs: &redis.FTVectorArgs{HNSWOptions: hnswOptionsUint8}}, + ).Result() + + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(BeEquivalentTo("OK")) + WaitForIndexing(client, "idx1") + + // Insert vectors in int8 and uint8 format + client.HSet(ctx, "doc1", "int8_vector", "\x01\x02", "uint8_vector", "\x01\x02") + client.HSet(ctx, "doc2", "int8_vector", "\x03\x04", "uint8_vector", "\x03\x04") + + // Perform KNN search on INT8 vector + searchOptionsInt8 := &redis.FTSearchOptions{ + Return: []redis.FTSearchReturn{{FieldName: "int8_vector"}}, + SortBy: []redis.FTSearchSortBy{{FieldName: "int8_vector", Asc: true}}, + DialectVersion: 2, + Params: map[string]interface{}{"vec": "\x01\x02"}, + } + + resInt8, err := client.FTSearchWithArgs(ctx, "idx1", "*=>[KNN 1 @int8_vector $vec]", searchOptionsInt8).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(resInt8).To(BeEquivalentTo("doc1")) + + // Perform KNN search on UINT8 vector + searchOptionsUint8 := &redis.FTSearchOptions{ + Return: []redis.FTSearchReturn{{FieldName: "uint8_vector"}}, + SortBy: []redis.FTSearchSortBy{{FieldName: "uint8_vector", Asc: true}}, + DialectVersion: 2, + Params: map[string]interface{}{"vec": "\x01\x02"}, + } + + resUint8, err := client.FTSearchWithArgs(ctx, "idx1", "*=>[KNN 1 @uint8_vector $vec]", searchOptionsUint8).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(resUint8).To(BeEquivalentTo("doc1")) + }) + }) From babb5d4542562a164e1b0224bff7c30481421c1a Mon Sep 17 00:00:00 2001 From: ofekshenawa Date: Tue, 18 Mar 2025 16:12:53 +0200 Subject: [PATCH 2/3] Add vector types INT8 and UINT8 test --- search_commands.go | 1 - search_test.go | 114 ++++++++++++++++++++++----------------------- 2 files changed, 56 insertions(+), 59 deletions(-) diff --git a/search_commands.go b/search_commands.go index c50ac07fb4..b58de36c79 100644 --- a/search_commands.go +++ b/search_commands.go @@ -1592,7 +1592,6 @@ func parseFTSearch(data []interface{}, noContent, withScores, withPayloads, with if !ok { return FTSearchResult{}, fmt.Errorf("invalid total results format") } - var results []Document for i := 1; i < len(data); { docID, ok := data[i].(string) diff --git a/search_test.go b/search_test.go index 9b6563e80f..e80ee662fc 100644 --- a/search_test.go +++ b/search_test.go @@ -1577,6 +1577,62 @@ var _ = Describe("RediSearch commands Resp 2", Label("search"), func() { Expect(res.Docs[0].ID).To(BeEquivalentTo("property:1")) Expect(res.Docs[1].ID).To(BeEquivalentTo("property:2")) }) + + It("should FTCreate VECTOR with int8 and uint8 types", Label("search", "ftcreate"), func() { + // Define INT8 vector field + hnswOptionsInt8 := &redis.FTHNSWOptions{ + Type: "INT8", + Dim: 2, + DistanceMetric: "L2", + } + + // Define UINT8 vector field + hnswOptionsUint8 := &redis.FTHNSWOptions{ + Type: "UINT8", + Dim: 2, + DistanceMetric: "L2", + } + + // Create index with INT8 and UINT8 vector fields + val, err := client.FTCreate(ctx, "idx1", + &redis.FTCreateOptions{}, + &redis.FieldSchema{FieldName: "int8_vector", FieldType: redis.SearchFieldTypeVector, VectorArgs: &redis.FTVectorArgs{HNSWOptions: hnswOptionsInt8}}, + &redis.FieldSchema{FieldName: "uint8_vector", FieldType: redis.SearchFieldTypeVector, VectorArgs: &redis.FTVectorArgs{HNSWOptions: hnswOptionsUint8}}, + ).Result() + + Expect(err).NotTo(HaveOccurred()) + Expect(val).To(BeEquivalentTo("OK")) + WaitForIndexing(client, "idx1") + + // Insert vectors in int8 and uint8 format + client.HSet(ctx, "doc1", "int8_vector", "\x01\x02", "uint8_vector", "\x01\x02") + client.HSet(ctx, "doc2", "int8_vector", "\x03\x04", "uint8_vector", "\x03\x04") + + // Perform KNN search on INT8 vector + searchOptionsInt8 := &redis.FTSearchOptions{ + Return: []redis.FTSearchReturn{{FieldName: "int8_vector"}}, + SortBy: []redis.FTSearchSortBy{{FieldName: "int8_vector", Asc: true}}, + DialectVersion: 2, + Params: map[string]interface{}{"vec": "\x01\x02"}, + } + + resInt8, err := client.FTSearchWithArgs(ctx, "idx1", "*=>[KNN 1 @int8_vector $vec]", searchOptionsInt8).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(resInt8.Docs[0].ID).To(BeEquivalentTo("doc1")) + + // Perform KNN search on UINT8 vector + searchOptionsUint8 := &redis.FTSearchOptions{ + Return: []redis.FTSearchReturn{{FieldName: "uint8_vector"}}, + SortBy: []redis.FTSearchSortBy{{FieldName: "uint8_vector", Asc: true}}, + DialectVersion: 2, + Params: map[string]interface{}{"vec": "\x01\x02"}, + } + + resUint8, err := client.FTSearchWithArgs(ctx, "idx1", "*=>[KNN 1 @uint8_vector $vec]", searchOptionsUint8).Result() + Expect(err).NotTo(HaveOccurred()) + Expect(resUint8.Docs[0].ID).To(BeEquivalentTo("doc1")) + }) + }) func _assert_geosearch_result(result *redis.FTSearchResult, expectedDocIDs []string) { @@ -1902,62 +1958,4 @@ var _ = Describe("RediSearch commands Resp 3", Label("search"), func() { Expect(res2).ToNot(BeEmpty()) }).ShouldNot(Panic()) }) - - It("should FTCreate VECTOR with int8 and uint8 types", Label("search", "ftcreate"), func() { - ctx := context.TODO() - - // Define INT8 vector field - hnswOptionsInt8 := &redis.FTHNSWOptions{ - Type: "INT8", - Dim: 2, - DistanceMetric: "L2", - } - - // Define UINT8 vector field - hnswOptionsUint8 := &redis.FTHNSWOptions{ - Type: "UINT8", - Dim: 2, - DistanceMetric: "L2", - } - - // Create index with INT8 and UINT8 vector fields - val, err := client.FTCreate(ctx, "idx1", - &redis.FTCreateOptions{}, - &redis.FieldSchema{FieldName: "int8_vector", FieldType: redis.SearchFieldTypeVector, VectorArgs: &redis.FTVectorArgs{HNSWOptions: hnswOptionsInt8}}, - &redis.FieldSchema{FieldName: "uint8_vector", FieldType: redis.SearchFieldTypeVector, VectorArgs: &redis.FTVectorArgs{HNSWOptions: hnswOptionsUint8}}, - ).Result() - - Expect(err).NotTo(HaveOccurred()) - Expect(val).To(BeEquivalentTo("OK")) - WaitForIndexing(client, "idx1") - - // Insert vectors in int8 and uint8 format - client.HSet(ctx, "doc1", "int8_vector", "\x01\x02", "uint8_vector", "\x01\x02") - client.HSet(ctx, "doc2", "int8_vector", "\x03\x04", "uint8_vector", "\x03\x04") - - // Perform KNN search on INT8 vector - searchOptionsInt8 := &redis.FTSearchOptions{ - Return: []redis.FTSearchReturn{{FieldName: "int8_vector"}}, - SortBy: []redis.FTSearchSortBy{{FieldName: "int8_vector", Asc: true}}, - DialectVersion: 2, - Params: map[string]interface{}{"vec": "\x01\x02"}, - } - - resInt8, err := client.FTSearchWithArgs(ctx, "idx1", "*=>[KNN 1 @int8_vector $vec]", searchOptionsInt8).Result() - Expect(err).NotTo(HaveOccurred()) - Expect(resInt8).To(BeEquivalentTo("doc1")) - - // Perform KNN search on UINT8 vector - searchOptionsUint8 := &redis.FTSearchOptions{ - Return: []redis.FTSearchReturn{{FieldName: "uint8_vector"}}, - SortBy: []redis.FTSearchSortBy{{FieldName: "uint8_vector", Asc: true}}, - DialectVersion: 2, - Params: map[string]interface{}{"vec": "\x01\x02"}, - } - - resUint8, err := client.FTSearchWithArgs(ctx, "idx1", "*=>[KNN 1 @uint8_vector $vec]", searchOptionsUint8).Result() - Expect(err).NotTo(HaveOccurred()) - Expect(resUint8).To(BeEquivalentTo("doc1")) - }) - }) From b21e871edf8e71c6bf96172d8a844e73f82e1d5d Mon Sep 17 00:00:00 2001 From: ofekshenawa Date: Tue, 18 Mar 2025 17:18:58 +0200 Subject: [PATCH 3/3] Skip the test before redis 8 --- search_commands.go | 1 + search_test.go | 1 + 2 files changed, 2 insertions(+) diff --git a/search_commands.go b/search_commands.go index b58de36c79..c50ac07fb4 100644 --- a/search_commands.go +++ b/search_commands.go @@ -1592,6 +1592,7 @@ func parseFTSearch(data []interface{}, noContent, withScores, withPayloads, with if !ok { return FTSearchResult{}, fmt.Errorf("invalid total results format") } + var results []Document for i := 1; i < len(data); { docID, ok := data[i].(string) diff --git a/search_test.go b/search_test.go index e80ee662fc..79a01bc6a9 100644 --- a/search_test.go +++ b/search_test.go @@ -1579,6 +1579,7 @@ var _ = Describe("RediSearch commands Resp 2", Label("search"), func() { }) It("should FTCreate VECTOR with int8 and uint8 types", Label("search", "ftcreate"), func() { + SkipBeforeRedisVersion(7.9, "doesn't work with older redis") // Define INT8 vector field hnswOptionsInt8 := &redis.FTHNSWOptions{ Type: "INT8",