@@ -1017,6 +1017,110 @@ var _ = Describe("RediSearch commands", Label("search"), func() {
10171017 Expect (res .Attributes [0 ].WithSuffixtrie ).To (BeTrue ())
10181018 })
10191019
1020+ It ("should test dialect 4" , Label ("search" , "ftcreate" , "ftsearch" , "NonRedisEnterprise" ), func () {
1021+ val , err := client .FTCreate (ctx , "idx1" , & redis.FTCreateOptions {
1022+ Prefix : []interface {}{"resource:" },
1023+ }, & redis.FieldSchema {
1024+ FieldName : "uuid" ,
1025+ FieldType : redis .SearchFieldTypeTag ,
1026+ }, & redis.FieldSchema {
1027+ FieldName : "tags" ,
1028+ FieldType : redis .SearchFieldTypeTag ,
1029+ }, & redis.FieldSchema {
1030+ FieldName : "description" ,
1031+ FieldType : redis .SearchFieldTypeText ,
1032+ }, & redis.FieldSchema {
1033+ FieldName : "rating" ,
1034+ FieldType : redis .SearchFieldTypeNumeric ,
1035+ }).Result ()
1036+ Expect (err ).NotTo (HaveOccurred ())
1037+ Expect (val ).To (BeEquivalentTo ("OK" ))
1038+
1039+ client .HSet (ctx , "resource:1" , map [string ]interface {}{
1040+ "uuid" : "123e4567-e89b-12d3-a456-426614174000" ,
1041+ "tags" : "finance|crypto|$btc|blockchain" ,
1042+ "description" : "Analysis of blockchain technologies & Bitcoin's potential." ,
1043+ "rating" : 5 ,
1044+ })
1045+ client .HSet (ctx , "resource:2" , map [string ]interface {}{
1046+ "uuid" : "987e6543-e21c-12d3-a456-426614174999" ,
1047+ "tags" : "health|well-being|fitness|new-year's-resolutions" ,
1048+ "description" : "Health trends for the new year, including fitness regimes." ,
1049+ "rating" : 4 ,
1050+ })
1051+
1052+ res , err := client .FTSearchWithArgs (ctx , "idx1" , "@uuid:{$uuid}" ,
1053+ & redis.FTSearchOptions {
1054+ DialectVersion : 2 ,
1055+ Params : map [string ]interface {}{"uuid" : "123e4567-e89b-12d3-a456-426614174000" },
1056+ }).Result ()
1057+ Expect (err ).NotTo (HaveOccurred ())
1058+ Expect (res .Total ).To (BeEquivalentTo (int64 (1 )))
1059+ Expect (res .Docs [0 ].ID ).To (BeEquivalentTo ("resource:1" ))
1060+
1061+ res , err = client .FTSearchWithArgs (ctx , "idx1" , "@uuid:{$uuid}" ,
1062+ & redis.FTSearchOptions {
1063+ DialectVersion : 4 ,
1064+ Params : map [string ]interface {}{"uuid" : "123e4567-e89b-12d3-a456-426614174000" },
1065+ }).Result ()
1066+ Expect (err ).NotTo (HaveOccurred ())
1067+ Expect (res .Total ).To (BeEquivalentTo (int64 (1 )))
1068+ Expect (res .Docs [0 ].ID ).To (BeEquivalentTo ("resource:1" ))
1069+
1070+ client .HSet (ctx , "test:1" , map [string ]interface {}{
1071+ "uuid" : "3d3586fe-0416-4572-8ce" ,
1072+ 1073+ "num" : 5 ,
1074+ })
1075+
1076+ // Create the index
1077+ ftCreateOptions := & redis.FTCreateOptions {
1078+ Prefix : []interface {}{"test:" },
1079+ }
1080+ schema := []* redis.FieldSchema {
1081+ {
1082+ FieldName : "uuid" ,
1083+ FieldType : redis .SearchFieldTypeTag ,
1084+ },
1085+ {
1086+ FieldName : "email" ,
1087+ FieldType : redis .SearchFieldTypeTag ,
1088+ },
1089+ {
1090+ FieldName : "num" ,
1091+ FieldType : redis .SearchFieldTypeNumeric ,
1092+ },
1093+ }
1094+
1095+ val , err = client .FTCreate (ctx , "idx_hash" , ftCreateOptions , schema ... ).Result ()
1096+ Expect (err ).NotTo (HaveOccurred ())
1097+ Expect (val ).To (Equal ("OK" ))
1098+
1099+ ftSearchOptions := & redis.FTSearchOptions {
1100+ DialectVersion : 4 ,
1101+ Params : map [string ]interface {}{
1102+ "uuid" : "3d3586fe-0416-4572-8ce" ,
1103+ 1104+ },
1105+ }
1106+
1107+ res , err = client .FTSearchWithArgs (ctx , "idx_hash" , "@uuid:{$uuid}" , ftSearchOptions ).Result ()
1108+ Expect (err ).NotTo (HaveOccurred ())
1109+ Expect (res .Docs [0 ].ID ).To (BeEquivalentTo ("test:1" ))
1110+ Expect (res .Docs [0 ].Fields ["uuid" ]).To (BeEquivalentTo ("3d3586fe-0416-4572-8ce" ))
1111+
1112+ res , err = client .FTSearchWithArgs (ctx , "idx_hash" , "@email:{$email}" , ftSearchOptions ).Result ()
1113+ Expect (err ).NotTo (HaveOccurred ())
1114+ Expect (res .Docs [0 ].ID ).To (BeEquivalentTo ("test:1" ))
1115+ Expect (
res .
Docs [
0 ].
Fields [
"email" ]).
To (
BeEquivalentTo (
"[email protected] " ))
1116+
1117+ ftSearchOptions .Params = map [string ]interface {}{"num" : 5 }
1118+ res , err = client .FTSearchWithArgs (ctx , "idx_hash" , "@num:[5]" , ftSearchOptions ).Result ()
1119+ Expect (err ).NotTo (HaveOccurred ())
1120+ Expect (res .Docs [0 ].ID ).To (BeEquivalentTo ("test:1" ))
1121+ Expect (res .Docs [0 ].Fields ["num" ]).To (BeEquivalentTo ("5" ))
1122+ })
1123+
10201124 It ("should FTCreate GeoShape" , Label ("search" , "ftcreate" , "ftsearch" ), func () {
10211125 val , err := client .FTCreate (ctx , "idx1" , & redis.FTCreateOptions {}, & redis.FieldSchema {FieldName : "geom" , FieldType : redis .SearchFieldTypeGeoShape , GeoShapeFieldType : "FLAT" }).Result ()
10221126 Expect (err ).NotTo (HaveOccurred ())
@@ -1043,8 +1147,185 @@ var _ = Describe("RediSearch commands", Label("search"), func() {
10431147 Expect (err ).NotTo (HaveOccurred ())
10441148 Expect (res2 .Total ).To (BeEquivalentTo (int64 (2 )))
10451149 })
1150+
1151+ It ("should create search index with FLOAT16 and BFLOAT16 vectors" , Label ("search" , "ftcreate" , "NonRedisEnterprise" ), func () {
1152+ val , err := client .FTCreate (ctx , "index" , & redis.FTCreateOptions {},
1153+ & redis.FieldSchema {FieldName : "float16" , FieldType : redis .SearchFieldTypeVector , VectorArgs : & redis.FTVectorArgs {FlatOptions : & redis.FTFlatOptions {Type : "FLOAT16" , Dim : 768 , DistanceMetric : "COSINE" }}},
1154+ & redis.FieldSchema {FieldName : "bfloat16" , FieldType : redis .SearchFieldTypeVector , VectorArgs : & redis.FTVectorArgs {FlatOptions : & redis.FTFlatOptions {Type : "BFLOAT16" , Dim : 768 , DistanceMetric : "COSINE" }}},
1155+ ).Result ()
1156+ Expect (err ).NotTo (HaveOccurred ())
1157+ Expect (val ).To (BeEquivalentTo ("OK" ))
1158+ WaitForIndexing (client , "index" )
1159+ })
1160+
1161+ It ("should test geoshapes query intersects and disjoint" , Label ("NonRedisEnterprise" ), func () {
1162+ _ , err := client .FTCreate (ctx , "idx1" , & redis.FTCreateOptions {}, & redis.FieldSchema {
1163+ FieldName : "g" ,
1164+ FieldType : redis .SearchFieldTypeGeoShape ,
1165+ GeoShapeFieldType : "FLAT" ,
1166+ }).Result ()
1167+ Expect (err ).NotTo (HaveOccurred ())
1168+
1169+ client .HSet (ctx , "doc_point1" , "g" , "POINT (10 10)" )
1170+ client .HSet (ctx , "doc_point2" , "g" , "POINT (50 50)" )
1171+ client .HSet (ctx , "doc_polygon1" , "g" , "POLYGON ((20 20, 25 35, 35 25, 20 20))" )
1172+ client .HSet (ctx , "doc_polygon2" , "g" , "POLYGON ((60 60, 65 75, 70 70, 65 55, 60 60))" )
1173+
1174+ intersection , err := client .FTSearchWithArgs (ctx , "idx1" , "@g:[intersects $shape]" ,
1175+ & redis.FTSearchOptions {
1176+ DialectVersion : 3 ,
1177+ Params : map [string ]interface {}{"shape" : "POLYGON((15 15, 75 15, 50 70, 20 40, 15 15))" },
1178+ }).Result ()
1179+ Expect (err ).NotTo (HaveOccurred ())
1180+ _assert_geosearch_result (& intersection , []string {"doc_point2" , "doc_polygon1" })
1181+
1182+ disjunction , err := client .FTSearchWithArgs (ctx , "idx1" , "@g:[disjoint $shape]" ,
1183+ & redis.FTSearchOptions {
1184+ DialectVersion : 3 ,
1185+ Params : map [string ]interface {}{"shape" : "POLYGON((15 15, 75 15, 50 70, 20 40, 15 15))" },
1186+ }).Result ()
1187+ Expect (err ).NotTo (HaveOccurred ())
1188+ _assert_geosearch_result (& disjunction , []string {"doc_point1" , "doc_polygon2" })
1189+ })
1190+
1191+ It ("should test geoshapes query contains and within" , func () {
1192+ _ , err := client .FTCreate (ctx , "idx2" , & redis.FTCreateOptions {}, & redis.FieldSchema {
1193+ FieldName : "g" ,
1194+ FieldType : redis .SearchFieldTypeGeoShape ,
1195+ GeoShapeFieldType : "FLAT" ,
1196+ }).Result ()
1197+ Expect (err ).NotTo (HaveOccurred ())
1198+
1199+ client .HSet (ctx , "doc_point1" , "g" , "POINT (10 10)" )
1200+ client .HSet (ctx , "doc_point2" , "g" , "POINT (50 50)" )
1201+ client .HSet (ctx , "doc_polygon1" , "g" , "POLYGON ((20 20, 25 35, 35 25, 20 20))" )
1202+ client .HSet (ctx , "doc_polygon2" , "g" , "POLYGON ((60 60, 65 75, 70 70, 65 55, 60 60))" )
1203+
1204+ containsA , err := client .FTSearchWithArgs (ctx , "idx2" , "@g:[contains $shape]" ,
1205+ & redis.FTSearchOptions {
1206+ DialectVersion : 3 ,
1207+ Params : map [string ]interface {}{"shape" : "POINT(25 25)" },
1208+ }).Result ()
1209+ Expect (err ).NotTo (HaveOccurred ())
1210+ _assert_geosearch_result (& containsA , []string {"doc_polygon1" })
1211+
1212+ containsB , err := client .FTSearchWithArgs (ctx , "idx2" , "@g:[contains $shape]" ,
1213+ & redis.FTSearchOptions {
1214+ DialectVersion : 3 ,
1215+ Params : map [string ]interface {}{"shape" : "POLYGON((24 24, 24 26, 25 25, 24 24))" },
1216+ }).Result ()
1217+ Expect (err ).NotTo (HaveOccurred ())
1218+ _assert_geosearch_result (& containsB , []string {"doc_polygon1" })
1219+
1220+ within , err := client .FTSearchWithArgs (ctx , "idx2" , "@g:[within $shape]" ,
1221+ & redis.FTSearchOptions {
1222+ DialectVersion : 3 ,
1223+ Params : map [string ]interface {}{"shape" : "POLYGON((15 15, 75 15, 50 70, 20 40, 15 15))" },
1224+ }).Result ()
1225+ Expect (err ).NotTo (HaveOccurred ())
1226+ _assert_geosearch_result (& within , []string {"doc_point2" , "doc_polygon1" })
1227+ })
1228+
1229+ It ("should search missing fields" , Label ("search" , "ftcreate" , "ftsearch" , "NonRedisEnterprise" ), func () {
1230+ val , err := client .FTCreate (ctx , "idx1" , & redis.FTCreateOptions {Prefix : []interface {}{"property:" }},
1231+ & redis.FieldSchema {FieldName : "title" , FieldType : redis .SearchFieldTypeText , Sortable : true },
1232+ & redis.FieldSchema {FieldName : "features" , FieldType : redis .SearchFieldTypeTag , IndexMissing : true },
1233+ & redis.FieldSchema {FieldName : "description" , FieldType : redis .SearchFieldTypeText , IndexMissing : true }).Result ()
1234+ Expect (err ).NotTo (HaveOccurred ())
1235+ Expect (val ).To (BeEquivalentTo ("OK" ))
1236+ WaitForIndexing (client , "idx1" )
1237+
1238+ client .HSet (ctx , "property:1" , map [string ]interface {}{
1239+ "title" : "Luxury Villa in Malibu" ,
1240+ "features" : "pool,sea view,modern" ,
1241+ "description" : "A stunning modern villa overlooking the Pacific Ocean." ,
1242+ })
1243+
1244+ client .HSet (ctx , "property:2" , map [string ]interface {}{
1245+ "title" : "Downtown Flat" ,
1246+ "description" : "Modern flat in central Paris with easy access to metro." ,
1247+ })
1248+
1249+ client .HSet (ctx , "property:3" , map [string ]interface {}{
1250+ "title" : "Beachfront Bungalow" ,
1251+ "features" : "beachfront,sun deck" ,
1252+ })
1253+
1254+ res , err := client .FTSearchWithArgs (ctx , "idx1" , "ismissing(@features)" , & redis.FTSearchOptions {DialectVersion : 4 , Return : []redis.FTSearchReturn {{FieldName : "id" }}, NoContent : true }).Result ()
1255+ Expect (err ).NotTo (HaveOccurred ())
1256+ Expect (res .Docs [0 ].ID ).To (BeEquivalentTo ("property:2" ))
1257+
1258+ res , err = client .FTSearchWithArgs (ctx , "idx1" , "-ismissing(@features)" , & redis.FTSearchOptions {DialectVersion : 4 , Return : []redis.FTSearchReturn {{FieldName : "id" }}, NoContent : true }).Result ()
1259+ Expect (err ).NotTo (HaveOccurred ())
1260+ Expect (res .Docs [0 ].ID ).To (BeEquivalentTo ("property:1" ))
1261+ Expect (res .Docs [1 ].ID ).To (BeEquivalentTo ("property:3" ))
1262+
1263+ res , err = client .FTSearchWithArgs (ctx , "idx1" , "ismissing(@description)" , & redis.FTSearchOptions {DialectVersion : 4 , Return : []redis.FTSearchReturn {{FieldName : "id" }}, NoContent : true }).Result ()
1264+ Expect (err ).NotTo (HaveOccurred ())
1265+ Expect (res .Docs [0 ].ID ).To (BeEquivalentTo ("property:3" ))
1266+
1267+ res , err = client .FTSearchWithArgs (ctx , "idx1" , "-ismissing(@description)" , & redis.FTSearchOptions {DialectVersion : 4 , Return : []redis.FTSearchReturn {{FieldName : "id" }}, NoContent : true }).Result ()
1268+ Expect (err ).NotTo (HaveOccurred ())
1269+ Expect (res .Docs [0 ].ID ).To (BeEquivalentTo ("property:1" ))
1270+ Expect (res .Docs [1 ].ID ).To (BeEquivalentTo ("property:2" ))
1271+ })
1272+
1273+ It ("should search empty fields" , Label ("search" , "ftcreate" , "ftsearch" , "NonRedisEnterprise" ), func () {
1274+ val , err := client .FTCreate (ctx , "idx1" , & redis.FTCreateOptions {Prefix : []interface {}{"property:" }},
1275+ & redis.FieldSchema {FieldName : "title" , FieldType : redis .SearchFieldTypeText , Sortable : true },
1276+ & redis.FieldSchema {FieldName : "features" , FieldType : redis .SearchFieldTypeTag , IndexEmpty : true },
1277+ & redis.FieldSchema {FieldName : "description" , FieldType : redis .SearchFieldTypeText , IndexEmpty : true }).Result ()
1278+ Expect (err ).NotTo (HaveOccurred ())
1279+ Expect (val ).To (BeEquivalentTo ("OK" ))
1280+ WaitForIndexing (client , "idx1" )
1281+
1282+ client .HSet (ctx , "property:1" , map [string ]interface {}{
1283+ "title" : "Luxury Villa in Malibu" ,
1284+ "features" : "pool,sea view,modern" ,
1285+ "description" : "A stunning modern villa overlooking the Pacific Ocean." ,
1286+ })
1287+
1288+ client .HSet (ctx , "property:2" , map [string ]interface {}{
1289+ "title" : "Downtown Flat" ,
1290+ "features" : "" ,
1291+ "description" : "Modern flat in central Paris with easy access to metro." ,
1292+ })
1293+
1294+ client .HSet (ctx , "property:3" , map [string ]interface {}{
1295+ "title" : "Beachfront Bungalow" ,
1296+ "features" : "beachfront,sun deck" ,
1297+ "description" : "" ,
1298+ })
1299+
1300+ res , err := client .FTSearchWithArgs (ctx , "idx1" , "@features:{\" \" }" , & redis.FTSearchOptions {DialectVersion : 4 , Return : []redis.FTSearchReturn {{FieldName : "id" }}, NoContent : true }).Result ()
1301+ Expect (err ).NotTo (HaveOccurred ())
1302+ Expect (res .Docs [0 ].ID ).To (BeEquivalentTo ("property:2" ))
1303+
1304+ res , err = client .FTSearchWithArgs (ctx , "idx1" , "-@features:{\" \" }" , & redis.FTSearchOptions {DialectVersion : 4 , Return : []redis.FTSearchReturn {{FieldName : "id" }}, NoContent : true }).Result ()
1305+ Expect (err ).NotTo (HaveOccurred ())
1306+ Expect (res .Docs [0 ].ID ).To (BeEquivalentTo ("property:1" ))
1307+ Expect (res .Docs [1 ].ID ).To (BeEquivalentTo ("property:3" ))
1308+
1309+ res , err = client .FTSearchWithArgs (ctx , "idx1" , "@description:''" , & redis.FTSearchOptions {DialectVersion : 4 , Return : []redis.FTSearchReturn {{FieldName : "id" }}, NoContent : true }).Result ()
1310+ Expect (err ).NotTo (HaveOccurred ())
1311+ Expect (res .Docs [0 ].ID ).To (BeEquivalentTo ("property:3" ))
1312+
1313+ res , err = client .FTSearchWithArgs (ctx , "idx1" , "-@description:''" , & redis.FTSearchOptions {DialectVersion : 4 , Return : []redis.FTSearchReturn {{FieldName : "id" }}, NoContent : true }).Result ()
1314+ Expect (err ).NotTo (HaveOccurred ())
1315+ Expect (res .Docs [0 ].ID ).To (BeEquivalentTo ("property:1" ))
1316+ Expect (res .Docs [1 ].ID ).To (BeEquivalentTo ("property:2" ))
1317+ })
10461318})
10471319
1320+ func _assert_geosearch_result (result * redis.FTSearchResult , expectedDocIDs []string ) {
1321+ ids := make ([]string , len (result .Docs ))
1322+ for i , doc := range result .Docs {
1323+ ids [i ] = doc .ID
1324+ }
1325+ Expect (ids ).To (ConsistOf (expectedDocIDs ))
1326+ Expect (result .Total ).To (BeEquivalentTo (len (expectedDocIDs )))
1327+ }
1328+
10481329// It("should FTProfile Search and Aggregate", Label("search", "ftprofile"), func() {
10491330// val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, &redis.FieldSchema{FieldName: "t", FieldType: redis.SearchFieldTypeText}).Result()
10501331// Expect(err).NotTo(HaveOccurred())
0 commit comments