@@ -1017,6 +1017,110 @@ var _ = Describe("RediSearch commands", Label("search"), func() {
1017
1017
Expect (res .Attributes [0 ].WithSuffixtrie ).To (BeTrue ())
1018
1018
})
1019
1019
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
+ "email" : "adriano@acme.com.ie" ,
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
+ "email" : "adriano@acme.com.ie" ,
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 ("adriano@acme.com.ie" ))
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
+
1020
1124
It ("should FTCreate GeoShape" , Label ("search" , "ftcreate" , "ftsearch" ), func () {
1021
1125
val , err := client .FTCreate (ctx , "idx1" , & redis.FTCreateOptions {}, & redis.FieldSchema {FieldName : "geom" , FieldType : redis .SearchFieldTypeGeoShape , GeoShapeFieldType : "FLAT" }).Result ()
1022
1126
Expect (err ).NotTo (HaveOccurred ())
@@ -1043,8 +1147,185 @@ var _ = Describe("RediSearch commands", Label("search"), func() {
1043
1147
Expect (err ).NotTo (HaveOccurred ())
1044
1148
Expect (res2 .Total ).To (BeEquivalentTo (int64 (2 )))
1045
1149
})
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
+ })
1046
1318
})
1047
1319
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
+
1048
1329
// It("should FTProfile Search and Aggregate", Label("search", "ftprofile"), func() {
1049
1330
// val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, &redis.FieldSchema{FieldName: "t", FieldType: redis.SearchFieldTypeText}).Result()
1050
1331
// Expect(err).NotTo(HaveOccurred())
0 commit comments