-
Notifications
You must be signed in to change notification settings - Fork 2.4k
/
search_test.go
1205 lines (1011 loc) · 67.5 KB
/
search_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
package redis_test
import (
"context"
"time"
. "github.com/bsm/ginkgo/v2"
. "github.com/bsm/gomega"
"github.com/redis/go-redis/v9"
)
func WaitForIndexing(c *redis.Client, index string) {
for {
res, err := c.FTInfo(context.Background(), index).Result()
Expect(err).NotTo(HaveOccurred())
if res["indexing"].(float64) == 0 {
return
}
time.Sleep(100 * time.Millisecond)
}
}
var _ = Describe("RediSearch commands", Label("search"), func() {
ctx := context.TODO()
var client *redis.Client
BeforeEach(func() {
client = redis.NewClient(&redis.Options{Addr: ":6379"})
Expect(client.FlushDB(ctx).Err()).NotTo(HaveOccurred())
})
AfterEach(func() {
Expect(client.Close()).NotTo(HaveOccurred())
})
It("should FTCreate and FTSearch WithScores ", Label("search", "ftcreate", "ftsearch"), func() {
val, err := client.FTCreate(ctx, "txt", &redis.FTCreateOptions{}, &redis.FieldSchema{FieldName: "txt", FieldType: redis.SearchFieldTypeText}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "txt")
client.HSet(ctx, "doc1", "txt", "foo baz")
client.HSet(ctx, "doc2", "txt", "foo bar")
res, err := client.FTSearchWithArgs(ctx, "txt", "foo ~bar", &redis.FTSearchOptions{WithScores: true}).Result()
Expect(err).NotTo(HaveOccurred())
searchResult := res.(map[interface{}]interface{})
Expect(searchResult["total_results"]).To(BeEquivalentTo(int64(2)))
Expect(searchResult["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc2"))
Expect(searchResult["results"].([]interface{})[0].(map[interface{}]interface{})["score"]).To(BeEquivalentTo(float64(3.0)))
Expect(searchResult["results"].([]interface{})[1].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc1"))
})
It("should FTCreate and FTSearch stopwords ", Label("search", "ftcreate", "ftsearch"), func() {
val, err := client.FTCreate(ctx, "txt", &redis.FTCreateOptions{StopWords: []interface{}{"foo", "bar", "baz"}}, &redis.FieldSchema{FieldName: "txt", FieldType: redis.SearchFieldTypeText}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "txt")
client.HSet(ctx, "doc1", "txt", "foo baz")
client.HSet(ctx, "doc2", "txt", "hello world")
res1, err := client.FTSearchWithArgs(ctx, "txt", "foo bar", &redis.FTSearchOptions{NoContent: true}).Result()
Expect(err).NotTo(HaveOccurred())
searchResult1 := res1.(map[interface{}]interface{})
Expect(searchResult1["total_results"]).To(BeEquivalentTo(int64(0)))
res2, err := client.FTSearchWithArgs(ctx, "txt", "foo bar hello world", &redis.FTSearchOptions{NoContent: true}).Result()
Expect(err).NotTo(HaveOccurred())
searchResult2 := res2.(map[interface{}]interface{})
Expect(searchResult2["total_results"]).To(BeEquivalentTo(int64(1)))
})
It("should FTCreate and FTSearch filters ", Label("search", "ftcreate", "ftsearch"), func() {
val, err := client.FTCreate(ctx, "txt", &redis.FTCreateOptions{}, &redis.FieldSchema{FieldName: "txt", FieldType: redis.SearchFieldTypeText}, &redis.FieldSchema{FieldName: "num", FieldType: redis.SearchFieldTypeNumeric}, &redis.FieldSchema{FieldName: "loc", FieldType: redis.SearchFieldTypeGeo}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "txt")
client.HSet(ctx, "doc1", "txt", "foo bar", "num", 3.141, "loc", "-0.441,51.458")
client.HSet(ctx, "doc2", "txt", "foo baz", "num", 2, "loc", "-0.1,51.2")
res1, err := client.FTSearchWithArgs(ctx, "txt", "foo", &redis.FTSearchOptions{Filters: []redis.FTSearchFilter{{FieldName: "num", Min: 0, Max: 2}}, NoContent: true}).Result()
Expect(err).NotTo(HaveOccurred())
searchResult1 := res1.(map[interface{}]interface{})
Expect(searchResult1["total_results"]).To(BeEquivalentTo(int64(1)))
Expect(searchResult1["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc2"))
res2, err := client.FTSearchWithArgs(ctx, "txt", "foo", &redis.FTSearchOptions{Filters: []redis.FTSearchFilter{{FieldName: "num", Min: 0, Max: "+inf"}}, NoContent: true}).Result()
Expect(err).NotTo(HaveOccurred())
searchResult2 := res2.(map[interface{}]interface{})
Expect(searchResult2["total_results"]).To(BeEquivalentTo(int64(2)))
Expect(searchResult2["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc1"))
// Test Geo filter
geoFilter1 := redis.FTSearchGeoFilter{FieldName: "loc", Longitude: -0.44, Latitude: 51.45, Radius: 10, Unit: "km"}
geoFilter2 := redis.FTSearchGeoFilter{FieldName: "loc", Longitude: -0.44, Latitude: 51.45, Radius: 100, Unit: "km"}
res3, err := client.FTSearchWithArgs(ctx, "txt", "foo", &redis.FTSearchOptions{GeoFilter: []redis.FTSearchGeoFilter{geoFilter1}, NoContent: true}).Result()
Expect(err).NotTo(HaveOccurred())
searchResult3 := res3.(map[interface{}]interface{})
Expect(searchResult3["total_results"]).To(BeEquivalentTo(int64(1)))
Expect(searchResult3["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc1"))
res4, err := client.FTSearchWithArgs(ctx, "txt", "foo", &redis.FTSearchOptions{GeoFilter: []redis.FTSearchGeoFilter{geoFilter2}, NoContent: true}).Result()
Expect(err).NotTo(HaveOccurred())
searchResult4 := res4.(map[interface{}]interface{})
Expect(searchResult4["total_results"]).To(BeEquivalentTo(int64(2)))
docs := []interface{}{searchResult4["results"].([]interface{})[0].(map[interface{}]interface{})["id"], searchResult4["results"].([]interface{})[1].(map[interface{}]interface{})["id"]}
Expect(docs).To(ContainElement("doc1"))
Expect(docs).To(ContainElement("doc2"))
})
It("should FTCreate and FTSearch sortby ", Label("search", "ftcreate", "ftsearch"), func() {
val, err := client.FTCreate(ctx, "num", &redis.FTCreateOptions{}, &redis.FieldSchema{FieldName: "txt", FieldType: redis.SearchFieldTypeText}, &redis.FieldSchema{FieldName: "num", FieldType: redis.SearchFieldTypeNumeric, Sortable: true}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "num")
client.HSet(ctx, "doc1", "txt", "foo bar", "num", 1)
client.HSet(ctx, "doc2", "txt", "foo baz", "num", 2)
client.HSet(ctx, "doc3", "txt", "foo qux", "num", 3)
sortBy1 := redis.FTSearchSortBy{FieldName: "num", Asc: true}
sortBy2 := redis.FTSearchSortBy{FieldName: "num", Desc: true}
res1, err := client.FTSearchWithArgs(ctx, "num", "foo", &redis.FTSearchOptions{NoContent: true, SortBy: []redis.FTSearchSortBy{sortBy1}}).Result()
Expect(err).NotTo(HaveOccurred())
searchResult1 := res1.(map[interface{}]interface{})
Expect(searchResult1["total_results"]).To(BeEquivalentTo(int64(3)))
Expect(searchResult1["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc1"))
Expect(searchResult1["results"].([]interface{})[1].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc2"))
Expect(searchResult1["results"].([]interface{})[2].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc3"))
res2, err := client.FTSearchWithArgs(ctx, "num", "foo", &redis.FTSearchOptions{NoContent: true, SortBy: []redis.FTSearchSortBy{sortBy2}}).Result()
Expect(err).NotTo(HaveOccurred())
searchResult2 := res2.(map[interface{}]interface{})
Expect(searchResult2["total_results"]).To(BeEquivalentTo(int64(3)))
Expect(searchResult2["results"].([]interface{})[2].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc1"))
Expect(searchResult2["results"].([]interface{})[1].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc2"))
Expect(searchResult2["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc3"))
})
It("should FTCreate and FTSearch example ", Label("search", "ftcreate", "ftsearch"), func() {
val, err := client.FTCreate(ctx, "txt", &redis.FTCreateOptions{}, &redis.FieldSchema{FieldName: "title", FieldType: redis.SearchFieldTypeText, Weight: 5}, &redis.FieldSchema{FieldName: "body", FieldType: redis.SearchFieldTypeText}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "txt")
client.HSet(ctx, "doc1", "title", "RediSearch", "body", "Redisearch impements a search engine on top of redis")
res1, err := client.FTSearchWithArgs(ctx, "txt", "search engine", &redis.FTSearchOptions{NoContent: true, Verbatim: true, LimitOffset: 0, Limit: 5}).Result()
Expect(err).NotTo(HaveOccurred())
searchResult1 := res1.(map[interface{}]interface{})
Expect(searchResult1).ToNot(BeEmpty())
})
It("should FTCreate NoIndex ", Label("search", "ftcreate", "ftsearch"), func() {
text1 := &redis.FieldSchema{FieldName: "field", FieldType: redis.SearchFieldTypeText}
text2 := &redis.FieldSchema{FieldName: "text", FieldType: redis.SearchFieldTypeText, NoIndex: true, Sortable: true}
num := &redis.FieldSchema{FieldName: "numeric", FieldType: redis.SearchFieldTypeNumeric, NoIndex: true, Sortable: true}
geo := &redis.FieldSchema{FieldName: "geo", FieldType: redis.SearchFieldTypeGeo, NoIndex: true, Sortable: true}
tag := &redis.FieldSchema{FieldName: "tag", FieldType: redis.SearchFieldTypeTag, NoIndex: true, Sortable: true}
val, err := client.FTCreate(ctx, "idx", &redis.FTCreateOptions{}, text1, text2, num, geo, tag).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx")
client.HSet(ctx, "doc1", "field", "aaa", "text", "1", "numeric", 1, "geo", "1,1", "tag", "1")
client.HSet(ctx, "doc2", "field", "aab", "text", "2", "numeric", 2, "geo", "2,2", "tag", "2")
res1, err := client.FTSearch(ctx, "idx", "@text:aa*").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res1.(map[interface{}]interface{})["total_results"]).To(BeEquivalentTo(int64(0)))
res2, err := client.FTSearch(ctx, "idx", "@field:aa*").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res2.(map[interface{}]interface{})["total_results"]).To(BeEquivalentTo(int64(2)))
res3, err := client.FTSearchWithArgs(ctx, "idx", "*", &redis.FTSearchOptions{SortBy: []redis.FTSearchSortBy{{FieldName: "text", Desc: true}}}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res3.(map[interface{}]interface{})["total_results"]).To(BeEquivalentTo(int64(2)))
Expect(res3.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc2"))
res4, err := client.FTSearchWithArgs(ctx, "idx", "*", &redis.FTSearchOptions{SortBy: []redis.FTSearchSortBy{{FieldName: "text", Asc: true}}}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res4.(map[interface{}]interface{})["total_results"]).To(BeEquivalentTo(int64(2)))
Expect(res4.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc1"))
res5, err := client.FTSearchWithArgs(ctx, "idx", "*", &redis.FTSearchOptions{SortBy: []redis.FTSearchSortBy{{FieldName: "numeric", Asc: true}}}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res5.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc1"))
res6, err := client.FTSearchWithArgs(ctx, "idx", "*", &redis.FTSearchOptions{SortBy: []redis.FTSearchSortBy{{FieldName: "geo", Asc: true}}}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res6.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc1"))
res7, err := client.FTSearchWithArgs(ctx, "idx", "*", &redis.FTSearchOptions{SortBy: []redis.FTSearchSortBy{{FieldName: "tag", Asc: true}}}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(res7.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("doc1"))
})
It("should FTExplain ", Label("search", "ftexplain"), func() {
text1 := &redis.FieldSchema{FieldName: "f1", FieldType: redis.SearchFieldTypeText}
text2 := &redis.FieldSchema{FieldName: "f2", FieldType: redis.SearchFieldTypeText}
text3 := &redis.FieldSchema{FieldName: "f3", FieldType: redis.SearchFieldTypeText}
val, err := client.FTCreate(ctx, "txt", &redis.FTCreateOptions{}, text1, text2, text3).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "txt")
res1, err := client.FTExplain(ctx, "txt", "@f3:f3_val @f2:f2_val @f1:f1_val").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res1).ToNot(BeEmpty())
})
It("should FTAlias ", Label("search", "ftexplain"), func() {
text1 := &redis.FieldSchema{FieldName: "name", FieldType: redis.SearchFieldTypeText}
text2 := &redis.FieldSchema{FieldName: "name", FieldType: redis.SearchFieldTypeText}
val1, err := client.FTCreate(ctx, "testAlias", &redis.FTCreateOptions{Prefix: []interface{}{"index1:"}}, text1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val1).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "testAlias")
val2, err := client.FTCreate(ctx, "testAlias2", &redis.FTCreateOptions{Prefix: []interface{}{"index2:"}}, text2).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val2).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "testAlias2")
client.HSet(ctx, "index1:lonestar", "name", "lonestar")
client.HSet(ctx, "index2:yogurt", "name", "yogurt")
res1, err := client.FTSearch(ctx, "testAlias", "*").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res1.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("index1:lonestar"))
aliasAddRes, err := client.FTAliasAdd(ctx, "testAlias", "mj23").Result()
Expect(err).NotTo(HaveOccurred())
Expect(aliasAddRes).To(BeEquivalentTo("OK"))
res1, err = client.FTSearch(ctx, "mj23", "*").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res1.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("index1:lonestar"))
aliasUpdateRes, err := client.FTAliasUpdate(ctx, "testAlias2", "kb24").Result()
Expect(err).NotTo(HaveOccurred())
Expect(aliasUpdateRes).To(BeEquivalentTo("OK"))
res3, err := client.FTSearch(ctx, "kb24", "*").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res3.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["id"]).To(BeEquivalentTo("index2:yogurt"))
aliasDelRes, err := client.FTAliasDel(ctx, "mj23").Result()
Expect(err).NotTo(HaveOccurred())
Expect(aliasDelRes).To(BeEquivalentTo("OK"))
})
It("should FTCreate and FTSearch textfield, sortable and nostem ", Label("search", "ftcreate", "ftsearch"), func() {
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, &redis.FieldSchema{FieldName: "txt", FieldType: redis.SearchFieldTypeText, Sortable: true, NoStem: true}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
resInfo, err := client.FTInfo(ctx, "idx1").Result()
Expect(err).NotTo(HaveOccurred())
Expect(resInfo["attributes"].([]interface{})[0].(map[interface{}]interface{})["flags"]).To(ContainElements("SORTABLE", "NOSTEM"))
})
It("should FTAlter ", Label("search", "ftcreate", "ftsearch", "ftalter"), func() {
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, &redis.FieldSchema{FieldName: "txt", FieldType: redis.SearchFieldTypeText}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
resAlter, err := client.FTAlter(ctx, "idx1", false, []interface{}{"body", redis.SearchFieldTypeText.String()}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(resAlter).To(BeEquivalentTo("OK"))
client.HSet(ctx, "doc1", "title", "MyTitle", "body", "Some content only in the body")
res1, err := client.FTSearch(ctx, "idx1", "only in the body").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res1.(map[interface{}]interface{})["total_results"]).To(BeEquivalentTo(int64(1)))
})
It("should FTSpellCheck", Label("search", "ftcreate", "ftsearch", "ftspellcheck"), func() {
text1 := &redis.FieldSchema{FieldName: "f1", FieldType: redis.SearchFieldTypeText}
text2 := &redis.FieldSchema{FieldName: "f2", FieldType: redis.SearchFieldTypeText}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, text1, text2).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.HSet(ctx, "doc1", "f1", "some valid content", "f2", "this is sample text")
client.HSet(ctx, "doc2", "f1", "very important", "f2", "lorem ipsum")
resSpellCheck, err := client.FTSpellCheck(ctx, "idx1", "impornant").Result()
Expect(err).NotTo(HaveOccurred())
res := resSpellCheck["results"].(map[interface{}]interface{})["impornant"].([]interface{})[0].(map[interface{}]interface{})
Expect("important").To(BeKeyOf(res))
resSpellCheck2, err := client.FTSpellCheck(ctx, "idx1", "contnt").Result()
Expect(err).NotTo(HaveOccurred())
res2 := resSpellCheck2["results"].(map[interface{}]interface{})["contnt"].([]interface{})[0].(map[interface{}]interface{})
Expect("content").To(BeKeyOf(res2))
// test spellcheck with Levenshtein distance
resSpellCheck3, err := client.FTSpellCheck(ctx, "idx1", "vlis").Result()
Expect(err).NotTo(HaveOccurred())
Expect(resSpellCheck3["results"]).To(BeEquivalentTo(map[interface{}]interface{}{"vlis": []interface{}{}}))
resSpellCheck4, err := client.FTSpellCheckWithArgs(ctx, "idx1", "vlis", &redis.FTSpellCheckOptions{Distance: 2}).Result()
Expect(err).NotTo(HaveOccurred())
Expect("valid").To(BeKeyOf(resSpellCheck4["results"].(map[interface{}]interface{})["vlis"].([]interface{})[0].(map[interface{}]interface{})))
// test spellcheck include
dict := []interface{}{"lore", "lorem", "lorm"}
resDictAdd, err := client.FTDictAdd(ctx, "dict", dict).Result()
Expect(err).NotTo(HaveOccurred())
Expect(resDictAdd).To(BeEquivalentTo(3))
terms := redis.SpellCheckTerms{Include: true, Dictionary: "dict"}
resSpellCheck5, err := client.FTSpellCheckWithArgs(ctx, "idx1", "lorm", &redis.FTSpellCheckOptions{Terms: terms}).Result()
Expect(err).NotTo(HaveOccurred())
lorm := resSpellCheck5["results"].(map[interface{}]interface{})["lorm"].([]interface{})
Expect(len(lorm)).To(BeEquivalentTo(3))
Expect(lorm[0].(map[interface{}]interface{})["lorem"]).To(BeEquivalentTo(0.5))
Expect(lorm[1].(map[interface{}]interface{})["lore"]).To(BeEquivalentTo(0))
Expect(lorm[2].(map[interface{}]interface{})["lorm"]).To(BeEquivalentTo(0))
terms2 := redis.SpellCheckTerms{Exclude: true, Dictionary: "dict"}
resSpellCheck6, err := client.FTSpellCheckWithArgs(ctx, "idx1", "lorm", &redis.FTSpellCheckOptions{Terms: terms2}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(resSpellCheck6["results"]).To(BeEmpty())
})
It("should FTDict opreations ", Label("search", "ftdictdump", "ftdictdel", "ftdictadd"), func() {
text1 := &redis.FieldSchema{FieldName: "f1", FieldType: redis.SearchFieldTypeText}
text2 := &redis.FieldSchema{FieldName: "f2", FieldType: redis.SearchFieldTypeText}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, text1, text2).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
dict := []interface{}{"item1", "item2", "item3"}
resDictAdd, err := client.FTDictAdd(ctx, "custom_dict", dict).Result()
Expect(err).NotTo(HaveOccurred())
Expect(resDictAdd).To(BeEquivalentTo(3))
resDictDel, err := client.FTDictDel(ctx, "custom_dict", []interface{}{"item2"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(resDictDel).To(BeEquivalentTo(1))
resDictDump, err := client.FTDictDump(ctx, "custom_dict").Result()
Expect(err).NotTo(HaveOccurred())
Expect(resDictDump).To(BeEquivalentTo([]string{"item1", "item3"}))
resDictDel2, err := client.FTDictDel(ctx, "custom_dict", []interface{}{"item1", "item3"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(resDictDel2).To(BeEquivalentTo(2))
})
It("should FTSearch phonetic matcher ", Label("search", "ftsearch"), func() {
text1 := &redis.FieldSchema{FieldName: "name", FieldType: redis.SearchFieldTypeText}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, text1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.HSet(ctx, "doc1", "name", "Jon")
client.HSet(ctx, "doc2", "name", "John")
res1, err := client.FTSearch(ctx, "idx1", "Jon").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res1.(map[interface{}]interface{})["total_results"]).To(BeEquivalentTo(int64(1)))
name := res1.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})["name"]
Expect(name).To(BeEquivalentTo("Jon"))
client.FlushDB(ctx)
text2 := &redis.FieldSchema{FieldName: "name", FieldType: redis.SearchFieldTypeText, PhoneticMatcher: "dm:en"}
val2, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, text2).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val2).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.HSet(ctx, "doc1", "name", "Jon")
client.HSet(ctx, "doc2", "name", "John")
res2, err := client.FTSearch(ctx, "idx1", "Jon").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res2.(map[interface{}]interface{})["total_results"]).To(BeEquivalentTo(int64(2)))
results2 := res2.(map[interface{}]interface{})["results"].([]interface{})
n1 := results2[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})["name"]
n2 := results2[1].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})["name"]
names := []interface{}{n1, n2}
Expect(names).To(ContainElement("Jon"))
Expect(names).To(ContainElement("John"))
})
It("should FTSearch WithScores", Label("search", "ftsearch"), func() {
text1 := &redis.FieldSchema{FieldName: "description", FieldType: redis.SearchFieldTypeText}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, text1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.HSet(ctx, "doc1", "description", "The quick brown fox jumps over the lazy dog")
client.HSet(ctx, "doc2", "description", "Quick alice was beginning to get very tired of sitting by her quick sister on the bank, and of having nothing to do.")
res, err := client.FTSearchWithArgs(ctx, "idx1", "quick", &redis.FTSearchOptions{WithScores: true}).Result()
Expect(err).NotTo(HaveOccurred())
result := res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["score"]
Expect(result).To(BeEquivalentTo(1))
res, err = client.FTSearchWithArgs(ctx, "idx1", "quick", &redis.FTSearchOptions{WithScores: true, Scorer: "TFIDF"}).Result()
Expect(err).NotTo(HaveOccurred())
result = res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["score"]
Expect(result).To(BeEquivalentTo(1))
res, err = client.FTSearchWithArgs(ctx, "idx1", "quick", &redis.FTSearchOptions{WithScores: true, Scorer: "TFIDF.DOCNORM"}).Result()
Expect(err).NotTo(HaveOccurred())
result = res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["score"]
Expect(result).To(BeEquivalentTo(0.14285714285714285))
res, err = client.FTSearchWithArgs(ctx, "idx1", "quick", &redis.FTSearchOptions{WithScores: true, Scorer: "BM25"}).Result()
Expect(err).NotTo(HaveOccurred())
result = res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["score"]
Expect(result).To(BeEquivalentTo(0.22471909420069797))
res, err = client.FTSearchWithArgs(ctx, "idx1", "quick", &redis.FTSearchOptions{WithScores: true, Scorer: "DISMAX"}).Result()
Expect(err).NotTo(HaveOccurred())
result = res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["score"]
Expect(result).To(BeEquivalentTo(2))
res, err = client.FTSearchWithArgs(ctx, "idx1", "quick", &redis.FTSearchOptions{WithScores: true, Scorer: "DOCSCORE"}).Result()
Expect(err).NotTo(HaveOccurred())
result = res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["score"]
Expect(result).To(BeEquivalentTo(1))
res, err = client.FTSearchWithArgs(ctx, "idx1", "quick", &redis.FTSearchOptions{WithScores: true, Scorer: "HAMMING"}).Result()
Expect(err).NotTo(HaveOccurred())
result = res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})["score"]
Expect(result).To(BeEquivalentTo(0))
})
It("should FTConfigSet and FTConfigGet ", Label("search", "ftconfigget", "ftconfigset"), func() {
val, err := client.FTConfigSet(ctx, "TIMEOUT", "100").Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
res, err := client.FTConfigGet(ctx, "*").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res["TIMEOUT"]).To(BeEquivalentTo("100"))
res, err = client.FTConfigGet(ctx, "TIMEOUT").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(BeEquivalentTo(map[string]interface{}{"TIMEOUT": "100"}))
})
It("should FTAggregate GroupBy ", Label("search", "ftaggregate"), func() {
text1 := &redis.FieldSchema{FieldName: "title", FieldType: redis.SearchFieldTypeText}
text2 := &redis.FieldSchema{FieldName: "body", FieldType: redis.SearchFieldTypeText}
text3 := &redis.FieldSchema{FieldName: "parent", FieldType: redis.SearchFieldTypeText}
num := &redis.FieldSchema{FieldName: "random_num", FieldType: redis.SearchFieldTypeNumeric}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, text1, text2, text3, num).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.HSet(ctx, "search", "title", "RediSearch",
"body", "Redisearch impements a search engine on top of redis",
"parent", "redis",
"random_num", 10)
client.HSet(ctx, "ai", "title", "RedisAI",
"body", "RedisAI executes Deep Learning/Machine Learning models and managing their data.",
"parent", "redis",
"random_num", 3)
client.HSet(ctx, "json", "title", "RedisJson",
"body", "RedisJSON implements ECMA-404 The JSON Data Interchange Standard as a native data type.",
"parent", "redis",
"random_num", 8)
reducer := redis.FTAggregateReducer{Reducer: redis.SearchCount}
options := &redis.FTAggregateOptions{GroupBy: []redis.FTAggregateGroupBy{{Fields: []interface{}{"@parent"}, Reduce: []redis.FTAggregateReducer{reducer}}}}
res, err := client.FTAggregateWithArgs(ctx, "idx1", "redis", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr := res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr["parent"]).To(BeEquivalentTo("redis"))
Expect(extraAttr["__generated_aliascount"]).To(BeEquivalentTo("3"))
reducer = redis.FTAggregateReducer{Reducer: redis.SearchCountDistinct, Args: []interface{}{"@title"}}
options = &redis.FTAggregateOptions{GroupBy: []redis.FTAggregateGroupBy{{Fields: []interface{}{"@parent"}, Reduce: []redis.FTAggregateReducer{reducer}}}}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "redis", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr["parent"]).To(BeEquivalentTo("redis"))
Expect(extraAttr["__generated_aliascount_distincttitle"]).To(BeEquivalentTo("3"))
reducer = redis.FTAggregateReducer{Reducer: redis.SearchSum, Args: []interface{}{"@random_num"}}
options = &redis.FTAggregateOptions{GroupBy: []redis.FTAggregateGroupBy{{Fields: []interface{}{"@parent"}, Reduce: []redis.FTAggregateReducer{reducer}}}}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "redis", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr["parent"]).To(BeEquivalentTo("redis"))
Expect(extraAttr["__generated_aliassumrandom_num"]).To(BeEquivalentTo("21"))
reducer = redis.FTAggregateReducer{Reducer: redis.SearchMin, Args: []interface{}{"@random_num"}}
options = &redis.FTAggregateOptions{GroupBy: []redis.FTAggregateGroupBy{{Fields: []interface{}{"@parent"}, Reduce: []redis.FTAggregateReducer{reducer}}}}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "redis", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr["parent"]).To(BeEquivalentTo("redis"))
Expect(extraAttr["__generated_aliasminrandom_num"]).To(BeEquivalentTo("3"))
reducer = redis.FTAggregateReducer{Reducer: redis.SearchMax, Args: []interface{}{"@random_num"}}
options = &redis.FTAggregateOptions{GroupBy: []redis.FTAggregateGroupBy{{Fields: []interface{}{"@parent"}, Reduce: []redis.FTAggregateReducer{reducer}}}}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "redis", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr["parent"]).To(BeEquivalentTo("redis"))
Expect(extraAttr["__generated_aliasmaxrandom_num"]).To(BeEquivalentTo("10"))
reducer = redis.FTAggregateReducer{Reducer: redis.SearchAvg, Args: []interface{}{"@random_num"}}
options = &redis.FTAggregateOptions{GroupBy: []redis.FTAggregateGroupBy{{Fields: []interface{}{"@parent"}, Reduce: []redis.FTAggregateReducer{reducer}}}}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "redis", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr["parent"]).To(BeEquivalentTo("redis"))
Expect(extraAttr["__generated_aliasavgrandom_num"]).To(BeEquivalentTo("7"))
reducer = redis.FTAggregateReducer{Reducer: redis.SearchStdDev, Args: []interface{}{"@random_num"}}
options = &redis.FTAggregateOptions{GroupBy: []redis.FTAggregateGroupBy{{Fields: []interface{}{"@parent"}, Reduce: []redis.FTAggregateReducer{reducer}}}}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "redis", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr["parent"]).To(BeEquivalentTo("redis"))
Expect(extraAttr["__generated_aliasstddevrandom_num"]).To(BeEquivalentTo("3.60555127546"))
reducer = redis.FTAggregateReducer{Reducer: redis.SearchQuantile, Args: []interface{}{"@random_num", 0.5}}
options = &redis.FTAggregateOptions{GroupBy: []redis.FTAggregateGroupBy{{Fields: []interface{}{"@parent"}, Reduce: []redis.FTAggregateReducer{reducer}}}}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "redis", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr["parent"]).To(BeEquivalentTo("redis"))
Expect(extraAttr["__generated_aliasquantilerandom_num,0.5"]).To(BeEquivalentTo("8"))
reducer = redis.FTAggregateReducer{Reducer: redis.SearchToList, Args: []interface{}{"@title"}}
options = &redis.FTAggregateOptions{GroupBy: []redis.FTAggregateGroupBy{{Fields: []interface{}{"@parent"}, Reduce: []redis.FTAggregateReducer{reducer}}}}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "redis", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr["parent"]).To(BeEquivalentTo("redis"))
Expect(extraAttr["__generated_aliastolisttitle"].([]interface{})).To(ContainElements("RediSearch", "RedisAI", "RedisJson"))
reducer = redis.FTAggregateReducer{Reducer: redis.SearchFirstValue, Args: []interface{}{"@title"}, As: "first"}
options = &redis.FTAggregateOptions{GroupBy: []redis.FTAggregateGroupBy{{Fields: []interface{}{"@parent"}, Reduce: []redis.FTAggregateReducer{reducer}}}}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "redis", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr["parent"]).To(BeEquivalentTo("redis"))
Expect(extraAttr["first"]).To(BeEquivalentTo("RediSearch"))
reducer = redis.FTAggregateReducer{Reducer: redis.SearchRandomSample, Args: []interface{}{"@title", 2}, As: "random"}
options = &redis.FTAggregateOptions{GroupBy: []redis.FTAggregateGroupBy{{Fields: []interface{}{"@parent"}, Reduce: []redis.FTAggregateReducer{reducer}}}}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "redis", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr["parent"]).To(BeEquivalentTo("redis"))
Expect(len(extraAttr["random"].([]interface{}))).To(BeEquivalentTo(2))
Expect(extraAttr["random"].([]interface{})[0]).To(BeElementOf([]string{"RediSearch", "RedisAI", "RedisJson"}))
})
It("should FTAggregate sort and limit ", Label("search", "ftaggregate"), func() {
text1 := &redis.FieldSchema{FieldName: "t1", FieldType: redis.SearchFieldTypeText}
text2 := &redis.FieldSchema{FieldName: "t2", FieldType: redis.SearchFieldTypeText}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, text1, text2).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.HSet(ctx, "doc1", "t1", "a", "t2", "b")
client.HSet(ctx, "doc2", "t1", "b", "t2", "a")
options := &redis.FTAggregateOptions{SortBy: []redis.FTAggregateSortBy{{FieldName: "@t2", Asc: true}, {FieldName: "@t1", Desc: true}}}
res, err := client.FTAggregateWithArgs(ctx, "idx1", "*", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr0 := res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
extraAttr1 := res["results"].([]interface{})[1].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr0).To(BeEquivalentTo(map[interface{}]interface{}{"t1": "b", "t2": "a"}))
Expect(extraAttr1).To(BeEquivalentTo(map[interface{}]interface{}{"t1": "a", "t2": "b"}))
options = &redis.FTAggregateOptions{SortBy: []redis.FTAggregateSortBy{{FieldName: "@t1"}}}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "*", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr0 = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
extraAttr1 = res["results"].([]interface{})[1].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr0).To(BeEquivalentTo(map[interface{}]interface{}{"t1": "a"}))
Expect(extraAttr1).To(BeEquivalentTo(map[interface{}]interface{}{"t1": "b"}))
options = &redis.FTAggregateOptions{SortBy: []redis.FTAggregateSortBy{{FieldName: "@t1"}}, SortByMax: 1}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "*", options).Result()
Expect(err).NotTo(HaveOccurred())
results := res["results"].([]interface{})
Expect(len(results)).To(BeEquivalentTo(1))
options = &redis.FTAggregateOptions{SortBy: []redis.FTAggregateSortBy{{FieldName: "@t1"}}, Limit: 1, LimitOffset: 1}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "*", options).Result()
Expect(err).NotTo(HaveOccurred())
results = res["results"].([]interface{})
extraAttr0 = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(len(results)).To(BeEquivalentTo(1))
Expect(extraAttr0).To(BeEquivalentTo(map[interface{}]interface{}{"t1": "b"}))
})
It("should FTAggregate load ", Label("search", "ftaggregate"), func() {
text1 := &redis.FieldSchema{FieldName: "t1", FieldType: redis.SearchFieldTypeText}
text2 := &redis.FieldSchema{FieldName: "t2", FieldType: redis.SearchFieldTypeText}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, text1, text2).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.HSet(ctx, "doc1", "t1", "hello", "t2", "world")
options := &redis.FTAggregateOptions{Load: []redis.FTAggregateLoad{{Field: "t1"}}}
res, err := client.FTAggregateWithArgs(ctx, "idx1", "*", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr0 := res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr0).To(BeEquivalentTo(map[interface{}]interface{}{"t1": "hello"}))
options = &redis.FTAggregateOptions{Load: []redis.FTAggregateLoad{{Field: "t2"}}}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "*", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr0 = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr0).To(BeEquivalentTo(map[interface{}]interface{}{"t2": "world"}))
options = &redis.FTAggregateOptions{LoadAll: true}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "*", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr0 = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr0).To(BeEquivalentTo(map[interface{}]interface{}{"t2": "world", "t1": "hello"}))
})
It("should FTAggregate apply", Label("search", "ftaggregate"), func() {
text1 := &redis.FieldSchema{FieldName: "PrimaryKey", FieldType: redis.SearchFieldTypeText, Sortable: true}
num1 := &redis.FieldSchema{FieldName: "CreatedDateTimeUTC", FieldType: redis.SearchFieldTypeNumeric, Sortable: true}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, text1, num1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.HSet(ctx, "doc1", "PrimaryKey", "9::362330", "CreatedDateTimeUTC", "637387878524969984")
client.HSet(ctx, "doc2", "PrimaryKey", "9::362329", "CreatedDateTimeUTC", "637387875859270016")
options := &redis.FTAggregateOptions{Apply: []redis.FTAggregateApply{{Field: "@CreatedDateTimeUTC * 10", As: "CreatedDateTimeUTC"}}}
res, err := client.FTAggregateWithArgs(ctx, "idx1", "*", options).Result()
Expect(err).NotTo(HaveOccurred())
extraAttr0 := res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
extraAttr1 := res["results"].([]interface{})[1].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect([]interface{}{extraAttr0["CreatedDateTimeUTC"], extraAttr1["CreatedDateTimeUTC"]}).To(ContainElements("6373878785249699840", "6373878758592700416"))
})
It("should FTAggregate filter", Label("search", "ftaggregate"), func() {
text1 := &redis.FieldSchema{FieldName: "name", FieldType: redis.SearchFieldTypeText, Sortable: true}
num1 := &redis.FieldSchema{FieldName: "age", FieldType: redis.SearchFieldTypeNumeric, Sortable: true}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, text1, num1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.HSet(ctx, "doc1", "name", "bar", "age", "25")
client.HSet(ctx, "doc2", "name", "foo", "age", "19")
for _, dlc := range []int{1, 2} {
options := &redis.FTAggregateOptions{Filter: "@name=='foo' && @age < 20", DialectVersion: dlc}
res, err := client.FTAggregateWithArgs(ctx, "idx1", "*", options).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(res["results"].([]interface{}))).To(BeEquivalentTo(1))
extraAttr0 := res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr0).To(BeEquivalentTo(map[interface{}]interface{}{"name": "foo", "age": "19"}))
options = &redis.FTAggregateOptions{Filter: "@age > 15", DialectVersion: dlc, SortBy: []redis.FTAggregateSortBy{{FieldName: "@age"}}}
res, err = client.FTAggregateWithArgs(ctx, "idx1", "*", options).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(res["results"].([]interface{}))).To(BeEquivalentTo(2))
extraAttr0 = res["results"].([]interface{})[0].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
extraAttr1 := res["results"].([]interface{})[1].(map[interface{}]interface{})["extra_attributes"].(map[interface{}]interface{})
Expect(extraAttr0).To(BeEquivalentTo(map[interface{}]interface{}{"age": "19"}))
Expect(extraAttr1).To(BeEquivalentTo(map[interface{}]interface{}{"age": "25"}))
}
})
It("should FTSearch SkipInitalScan", Label("search", "ftsearch"), func() {
client.HSet(ctx, "doc1", "foo", "bar")
text1 := &redis.FieldSchema{FieldName: "foo", FieldType: redis.SearchFieldTypeText}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{SkipInitalScan: true}, text1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
res, err := client.FTSearch(ctx, "idx1", "@foo:bar").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res.(map[interface{}]interface{})["total_results"]).To(BeEquivalentTo(int64(0)))
})
It("should FTCreate json", Label("search", "ftcreate"), func() {
text1 := &redis.FieldSchema{FieldName: "$.name", FieldType: redis.SearchFieldTypeText}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{OnJSON: true, Prefix: []interface{}{"king:"}}, text1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.JSONSet(ctx, "king:1", "$", `{"name": "henry"}`)
client.JSONSet(ctx, "king:2", "$", `{"name": "james"}`)
res, err := client.FTSearch(ctx, "idx1", "henry").Result()
Expect(err).NotTo(HaveOccurred())
totalResults := res.(map[interface{}]interface{})["total_results"]
Expect(totalResults).To(BeEquivalentTo(1))
results0 := res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})
Expect(results0["id"]).To(BeEquivalentTo("king:1"))
Expect(results0["extra_attributes"].(map[interface{}]interface{})["$"]).To(BeEquivalentTo(`{"name":"henry"}`))
})
It("should FTCreate json fields as names", Label("search", "ftcreate"), func() {
text1 := &redis.FieldSchema{FieldName: "$.name", FieldType: redis.SearchFieldTypeText, As: "name"}
num1 := &redis.FieldSchema{FieldName: "$.age", FieldType: redis.SearchFieldTypeNumeric, As: "just_a_number"}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{OnJSON: true}, text1, num1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.JSONSet(ctx, "doc:1", "$", `{"name": "Jon", "age": 25}`)
res, err := client.FTSearchWithArgs(ctx, "idx1", "Jon", &redis.FTSearchOptions{Return: []redis.FTSearchReturn{{FieldName: "name"}, {FieldName: "just_a_number"}}}).Result()
Expect(err).NotTo(HaveOccurred())
results := res.(map[interface{}]interface{})["results"].([]interface{})
Expect(len(results)).To(BeEquivalentTo(1))
results0 := results[0].(map[interface{}]interface{})
Expect(results0["id"]).To(BeEquivalentTo("doc:1"))
Expect(results0["extra_attributes"].(map[interface{}]interface{})["name"]).To(BeEquivalentTo("Jon"))
Expect(results0["extra_attributes"].(map[interface{}]interface{})["just_a_number"]).To(BeEquivalentTo("25"))
})
It("should FTCreate CaseSensitive", Label("search", "ftcreate"), func() {
tag1 := &redis.FieldSchema{FieldName: "t", FieldType: redis.SearchFieldTypeTag, CaseSensitive: false}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, tag1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.HSet(ctx, "1", "t", "HELLO")
client.HSet(ctx, "2", "t", "hello")
res, err := client.FTSearch(ctx, "idx1", "@t:{HELLO}").Result()
Expect(err).NotTo(HaveOccurred())
results := res.(map[interface{}]interface{})["results"].([]interface{})
Expect(len(results)).To(BeEquivalentTo(2))
results0 := results[0].(map[interface{}]interface{})
results1 := results[1].(map[interface{}]interface{})
Expect(results0["id"]).To(BeEquivalentTo("1"))
Expect(results1["id"]).To(BeEquivalentTo("2"))
res, err = client.FTDropIndex(ctx, "idx1").Result()
Expect(err).NotTo(HaveOccurred())
Expect(res).To(BeEquivalentTo("OK"))
tag2 := &redis.FieldSchema{FieldName: "t", FieldType: redis.SearchFieldTypeTag, CaseSensitive: true}
val, err = client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, tag2).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
res, err = client.FTSearch(ctx, "idx1", "@t:{HELLO}").Result()
Expect(err).NotTo(HaveOccurred())
results = res.(map[interface{}]interface{})["results"].([]interface{})
Expect(len(results)).To(BeEquivalentTo(1))
results0 = results[0].(map[interface{}]interface{})
Expect(results0["id"]).To(BeEquivalentTo("1"))
})
It("should FTSearch ReturnFields", Label("search", "ftsearch"), func() {
resJson, err := client.JSONSet(ctx, "doc:1", "$", `{"t": "riceratops","t2": "telmatosaurus", "n": 9072, "flt": 97.2}`).Result()
Expect(err).NotTo(HaveOccurred())
Expect(resJson).To(BeEquivalentTo("OK"))
text1 := &redis.FieldSchema{FieldName: "$.t", FieldType: redis.SearchFieldTypeText}
num1 := &redis.FieldSchema{FieldName: "$.flt", FieldType: redis.SearchFieldTypeNumeric}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{OnJSON: true}, text1, num1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
res, err := client.FTSearchWithArgs(ctx, "idx1", "*", &redis.FTSearchOptions{Return: []redis.FTSearchReturn{{FieldName: "$.t", As: "txt"}}}).Result()
Expect(err).NotTo(HaveOccurred())
results := res.(map[interface{}]interface{})["results"].([]interface{})
Expect(len(results)).To(BeEquivalentTo(1))
results0 := results[0].(map[interface{}]interface{})
Expect(results0["id"]).To(BeEquivalentTo("doc:1"))
Expect(results0["extra_attributes"].(map[interface{}]interface{})["txt"]).To(BeEquivalentTo("riceratops"))
res, err = client.FTSearchWithArgs(ctx, "idx1", "*", &redis.FTSearchOptions{Return: []redis.FTSearchReturn{{FieldName: "$.t2", As: "txt"}}}).Result()
Expect(err).NotTo(HaveOccurred())
results = res.(map[interface{}]interface{})["results"].([]interface{})
Expect(len(results)).To(BeEquivalentTo(1))
results0 = results[0].(map[interface{}]interface{})
Expect(results0["id"]).To(BeEquivalentTo("doc:1"))
Expect(results0["extra_attributes"].(map[interface{}]interface{})["txt"]).To(BeEquivalentTo("telmatosaurus"))
})
It("should FTSynUpdate", Label("search", "ftsynupdate"), func() {
text1 := &redis.FieldSchema{FieldName: "title", FieldType: redis.SearchFieldTypeText}
text2 := &redis.FieldSchema{FieldName: "body", FieldType: redis.SearchFieldTypeText}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{OnHash: true}, text1, text2).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
resSynUpdate, err := client.FTSynUpdateWithArgs(ctx, "idx1", "id1", &redis.FTSynUpdateOptions{SkipInitialScan: true}, []interface{}{"boy", "child", "offspring"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(resSynUpdate).To(BeEquivalentTo("OK"))
client.HSet(ctx, "doc1", "title", "he is a baby", "body", "this is a test")
resSynUpdate, err = client.FTSynUpdateWithArgs(ctx, "idx1", "id1", &redis.FTSynUpdateOptions{SkipInitialScan: true}, []interface{}{"baby"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(resSynUpdate).To(BeEquivalentTo("OK"))
client.HSet(ctx, "doc2", "title", "he is another baby", "body", "another test")
res, err := client.FTSearchWithArgs(ctx, "idx1", "child", &redis.FTSearchOptions{Expander: "SYNONYM"}).Result()
Expect(err).NotTo(HaveOccurred())
results0 := res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})
Expect(results0["id"]).To(BeEquivalentTo("doc2"))
Expect(results0["extra_attributes"].(map[interface{}]interface{})["title"]).To(BeEquivalentTo("he is another baby"))
Expect(results0["extra_attributes"].(map[interface{}]interface{})["body"]).To(BeEquivalentTo("another test"))
})
It("should FTSynDump", Label("search", "ftsyndump"), func() {
text1 := &redis.FieldSchema{FieldName: "title", FieldType: redis.SearchFieldTypeText}
text2 := &redis.FieldSchema{FieldName: "body", FieldType: redis.SearchFieldTypeText}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{OnHash: true}, text1, text2).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
resSynUpdate, err := client.FTSynUpdate(ctx, "idx1", "id1", []interface{}{"boy", "child", "offspring"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(resSynUpdate).To(BeEquivalentTo("OK"))
resSynUpdate, err = client.FTSynUpdate(ctx, "idx1", "id1", []interface{}{"baby", "child"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(resSynUpdate).To(BeEquivalentTo("OK"))
resSynUpdate, err = client.FTSynUpdate(ctx, "idx1", "id1", []interface{}{"tree", "wood"}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(resSynUpdate).To(BeEquivalentTo("OK"))
resSynDump, err := client.FTSynDump(ctx, "idx1").Result()
Expect(err).NotTo(HaveOccurred())
Expect(resSynDump).To(BeEquivalentTo(map[string][]interface{}{
"offspring": {"id1"},
"baby": {"id1"},
"wood": {"id1"},
"boy": {"id1"},
"tree": {"id1"},
"child": {"id1", "id1"}}))
})
It("should FTCreate json with alias", Label("search", "ftcreate"), func() {
text1 := &redis.FieldSchema{FieldName: "$.name", FieldType: redis.SearchFieldTypeText, As: "name"}
num1 := &redis.FieldSchema{FieldName: "$.num", FieldType: redis.SearchFieldTypeNumeric, As: "num"}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{OnJSON: true, Prefix: []interface{}{"king:"}}, text1, num1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.JSONSet(ctx, "king:1", "$", `{"name": "henry", "num": 42}`)
client.JSONSet(ctx, "king:2", "$", `{"name": "james", "num": 3.14}`)
res, err := client.FTSearch(ctx, "idx1", "@name:henry").Result()
Expect(err).NotTo(HaveOccurred())
totalResults := res.(map[interface{}]interface{})["total_results"]
Expect(totalResults).To(BeEquivalentTo(1))
results0 := res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})
Expect(results0["id"]).To(BeEquivalentTo("king:1"))
Expect(results0["extra_attributes"].(map[interface{}]interface{})["$"]).To(BeEquivalentTo(`{"name":"henry","num":42}`))
res, err = client.FTSearch(ctx, "idx1", "@num:[0 10]").Result()
Expect(err).NotTo(HaveOccurred())
totalResults = res.(map[interface{}]interface{})["total_results"]
Expect(totalResults).To(BeEquivalentTo(1))
results0 = res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})
Expect(results0["id"]).To(BeEquivalentTo("king:2"))
Expect(results0["extra_attributes"].(map[interface{}]interface{})["$"]).To(BeEquivalentTo(`{"name":"james","num":3.14}`))
})
It("should FTCreate json with multipath", Label("search", "ftcreate"), func() {
tag1 := &redis.FieldSchema{FieldName: "$..name", FieldType: redis.SearchFieldTypeTag, As: "name"}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{OnJSON: true, Prefix: []interface{}{"king:"}}, tag1).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.JSONSet(ctx, "king:1", "$", `{"name": "henry", "country": {"name": "england"}}`)
res, err := client.FTSearch(ctx, "idx1", "@name:{england}").Result()
Expect(err).NotTo(HaveOccurred())
totalResults := res.(map[interface{}]interface{})["total_results"]
Expect(totalResults).To(BeEquivalentTo(1))
results0 := res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})
Expect(results0["id"]).To(BeEquivalentTo("king:1"))
Expect(results0["extra_attributes"].(map[interface{}]interface{})["$"]).To(BeEquivalentTo(`{"name":"henry","country":{"name":"england"}}`))
})
It("should FTCreate json with jsonpath", Label("search", "ftcreate"), func() {
text1 := &redis.FieldSchema{FieldName: `$["prod:name"]`, FieldType: redis.SearchFieldTypeText, As: "name"}
text2 := &redis.FieldSchema{FieldName: `$.prod:name`, FieldType: redis.SearchFieldTypeText, As: "name_unsupported"}
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{OnJSON: true}, text1, text2).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.JSONSet(ctx, "doc:1", "$", `{"prod:name": "RediSearch"}`)
res, err := client.FTSearch(ctx, "idx1", "@name:RediSearch").Result()
Expect(err).NotTo(HaveOccurred())
totalResults := res.(map[interface{}]interface{})["total_results"]
Expect(totalResults).To(BeEquivalentTo(1))
results0 := res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})
Expect(results0["id"]).To(BeEquivalentTo("doc:1"))
Expect(results0["extra_attributes"].(map[interface{}]interface{})["$"]).To(BeEquivalentTo(`{"prod:name":"RediSearch"}`))
res, err = client.FTSearch(ctx, "idx1", "@name_unsupported:RediSearch").Result()
Expect(err).NotTo(HaveOccurred())
totalResults = res.(map[interface{}]interface{})["total_results"]
Expect(totalResults).To(BeEquivalentTo(1))
res, err = client.FTSearchWithArgs(ctx, "idx1", "@name:RediSearch", &redis.FTSearchOptions{Return: []redis.FTSearchReturn{{FieldName: "name"}}}).Result()
Expect(err).NotTo(HaveOccurred())
totalResults = res.(map[interface{}]interface{})["total_results"]
Expect(totalResults).To(BeEquivalentTo(1))
results0 = res.(map[interface{}]interface{})["results"].([]interface{})[0].(map[interface{}]interface{})
Expect(results0["id"]).To(BeEquivalentTo("doc:1"))
Expect(results0["extra_attributes"].(map[interface{}]interface{})["name"]).To(BeEquivalentTo("RediSearch"))
})
It("should FTProfile Search and Aggregate", Label("search", "ftprofile"), func() {
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, &redis.FieldSchema{FieldName: "t", FieldType: redis.SearchFieldTypeText}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.HSet(ctx, "1", "t", "hello")
client.HSet(ctx, "2", "t", "world")
// FTProfile Search
query := redis.FTSearchQuery("hello|world", &redis.FTSearchOptions{NoContent: true})
res1, err := client.FTProfile(ctx, "idx1", false, query).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(res1["results"].([]interface{}))).To(BeEquivalentTo(2))
resProfile := res1["profile"].(map[interface{}]interface{})
Expect(resProfile["Parsing time"].(float64) < 0.5).To(BeTrue())
iterProfile0 := resProfile["Iterators profile"].([]interface{})[0].(map[interface{}]interface{})
Expect(iterProfile0["Counter"]).To(BeEquivalentTo(2.0))
Expect(iterProfile0["Type"]).To(BeEquivalentTo("UNION"))
// FTProfile Aggregate
aggQuery := redis.FTAggregateQuery("*", &redis.FTAggregateOptions{
Load: []redis.FTAggregateLoad{{Field: "t"}},
Apply: []redis.FTAggregateApply{{Field: "startswith(@t, 'hel')", As: "prefix"}}})
res2, err := client.FTProfile(ctx, "idx1", false, aggQuery).Result()
Expect(err).NotTo(HaveOccurred())
Expect(len(res2["results"].([]interface{}))).To(BeEquivalentTo(2))
resProfile = res2["profile"].(map[interface{}]interface{})
iterProfile0 = resProfile["Iterators profile"].([]interface{})[0].(map[interface{}]interface{})
Expect(iterProfile0["Counter"]).To(BeEquivalentTo(2))
Expect(iterProfile0["Type"]).To(BeEquivalentTo("WILDCARD"))
})
It("should FTProfile Search Limited", Label("search", "ftprofile"), func() {
val, err := client.FTCreate(ctx, "idx1", &redis.FTCreateOptions{}, &redis.FieldSchema{FieldName: "t", FieldType: redis.SearchFieldTypeText}).Result()
Expect(err).NotTo(HaveOccurred())
Expect(val).To(BeEquivalentTo("OK"))
WaitForIndexing(client, "idx1")
client.HSet(ctx, "1", "t", "hello")
client.HSet(ctx, "2", "t", "hell")
client.HSet(ctx, "3", "t", "help")
client.HSet(ctx, "4", "t", "helowa")
// FTProfile Search
query := redis.FTSearchQuery("%hell% hel*", &redis.FTSearchOptions{})
res1, err := client.FTProfile(ctx, "idx1", true, query).Result()
Expect(err).NotTo(HaveOccurred())
resProfile := res1["profile"].(map[interface{}]interface{})
iterProfile0 := resProfile["Iterators profile"].([]interface{})[0].(map[interface{}]interface{})
Expect(iterProfile0["Type"]).To(BeEquivalentTo("INTERSECT"))
Expect(len(res1["results"].([]interface{}))).To(BeEquivalentTo(3))
Expect(iterProfile0["Child iterators"].([]interface{})[0].(map[interface{}]interface{})["Child iterators"]).To(BeEquivalentTo("The number of iterators in the union is 3"))
Expect(iterProfile0["Child iterators"].([]interface{})[1].(map[interface{}]interface{})["Child iterators"]).To(BeEquivalentTo("The number of iterators in the union is 4"))
})
It("should FTProfile Search query params", Label("search", "ftprofile"), func() {
hnswOptions := &redis.FTHNSWOptions{Type: "FLOAT32", Dim: 2, DistanceMetric: "L2"}