1 package redis
2
3 import (
4 "context"
5 )
6
7
8
9
10
11
12
13
14 type SearchBuilder struct {
15 c *Client
16 ctx context.Context
17 index string
18 query string
19 options *FTSearchOptions
20 }
21
22
23
24 func (c *Client) NewSearchBuilder(ctx context.Context, index, query string) *SearchBuilder {
25 b := &SearchBuilder{c: c, ctx: ctx, index: index, query: query, options: &FTSearchOptions{LimitOffset: -1}}
26 return b
27 }
28
29
30 func (b *SearchBuilder) WithScores() *SearchBuilder {
31 b.options.WithScores = true
32 return b
33 }
34
35
36 func (b *SearchBuilder) NoContent() *SearchBuilder { b.options.NoContent = true; return b }
37
38
39 func (b *SearchBuilder) Verbatim() *SearchBuilder { b.options.Verbatim = true; return b }
40
41
42 func (b *SearchBuilder) NoStopWords() *SearchBuilder { b.options.NoStopWords = true; return b }
43
44
45 func (b *SearchBuilder) WithPayloads() *SearchBuilder {
46 b.options.WithPayloads = true
47 return b
48 }
49
50
51 func (b *SearchBuilder) WithSortKeys() *SearchBuilder {
52 b.options.WithSortKeys = true
53 return b
54 }
55
56
57 func (b *SearchBuilder) Filter(field string, min, max interface{}) *SearchBuilder {
58 b.options.Filters = append(b.options.Filters, FTSearchFilter{
59 FieldName: field,
60 Min: min,
61 Max: max,
62 })
63 return b
64 }
65
66
67 func (b *SearchBuilder) GeoFilter(field string, lon, lat, radius float64, unit string) *SearchBuilder {
68 b.options.GeoFilter = append(b.options.GeoFilter, FTSearchGeoFilter{
69 FieldName: field,
70 Longitude: lon,
71 Latitude: lat,
72 Radius: radius,
73 Unit: unit,
74 })
75 return b
76 }
77
78
79 func (b *SearchBuilder) InKeys(keys ...interface{}) *SearchBuilder {
80 b.options.InKeys = append(b.options.InKeys, keys...)
81 return b
82 }
83
84
85 func (b *SearchBuilder) InFields(fields ...interface{}) *SearchBuilder {
86 b.options.InFields = append(b.options.InFields, fields...)
87 return b
88 }
89
90
91 func (b *SearchBuilder) ReturnFields(fields ...string) *SearchBuilder {
92 for _, f := range fields {
93 b.options.Return = append(b.options.Return, FTSearchReturn{FieldName: f})
94 }
95 return b
96 }
97
98
99 func (b *SearchBuilder) ReturnAs(field, alias string) *SearchBuilder {
100 b.options.Return = append(b.options.Return, FTSearchReturn{FieldName: field, As: alias})
101 return b
102 }
103
104
105 func (b *SearchBuilder) Slop(slop int) *SearchBuilder {
106 b.options.Slop = slop
107 return b
108 }
109
110
111 func (b *SearchBuilder) Timeout(timeout int) *SearchBuilder {
112 b.options.Timeout = timeout
113 return b
114 }
115
116
117 func (b *SearchBuilder) InOrder() *SearchBuilder {
118 b.options.InOrder = true
119 return b
120 }
121
122
123 func (b *SearchBuilder) Language(lang string) *SearchBuilder {
124 b.options.Language = lang
125 return b
126 }
127
128
129 func (b *SearchBuilder) Expander(expander string) *SearchBuilder {
130 b.options.Expander = expander
131 return b
132 }
133
134
135 func (b *SearchBuilder) Scorer(scorer string) *SearchBuilder {
136 b.options.Scorer = scorer
137 return b
138 }
139
140
141 func (b *SearchBuilder) ExplainScore() *SearchBuilder {
142 b.options.ExplainScore = true
143 return b
144 }
145
146
147 func (b *SearchBuilder) Payload(payload string) *SearchBuilder {
148 b.options.Payload = payload
149 return b
150 }
151
152
153 func (b *SearchBuilder) SortBy(field string, asc bool) *SearchBuilder {
154 b.options.SortBy = append(b.options.SortBy, FTSearchSortBy{
155 FieldName: field,
156 Asc: asc,
157 Desc: !asc,
158 })
159 return b
160 }
161
162
163 func (b *SearchBuilder) WithSortByCount() *SearchBuilder {
164 b.options.SortByWithCount = true
165 return b
166 }
167
168
169 func (b *SearchBuilder) Param(key string, value interface{}) *SearchBuilder {
170 if b.options.Params == nil {
171 b.options.Params = make(map[string]interface{}, 1)
172 }
173 b.options.Params[key] = value
174 return b
175 }
176
177
178 func (b *SearchBuilder) ParamsMap(p map[string]interface{}) *SearchBuilder {
179 if b.options.Params == nil {
180 b.options.Params = make(map[string]interface{}, len(p))
181 }
182 for k, v := range p {
183 b.options.Params[k] = v
184 }
185 return b
186 }
187
188
189 func (b *SearchBuilder) Dialect(version int) *SearchBuilder {
190 b.options.DialectVersion = version
191 return b
192 }
193
194
195 func (b *SearchBuilder) Limit(offset, count int) *SearchBuilder {
196 b.options.LimitOffset = offset
197 b.options.Limit = count
198 return b
199 }
200 func (b *SearchBuilder) CountOnly() *SearchBuilder { b.options.CountOnly = true; return b }
201
202
203 func (b *SearchBuilder) Run() (FTSearchResult, error) {
204 cmd := b.c.FTSearchWithArgs(b.ctx, b.index, b.query, b.options)
205 return cmd.Result()
206 }
207
208
209
210
211
212 type AggregateBuilder struct {
213 c *Client
214 ctx context.Context
215 index string
216 query string
217 options *FTAggregateOptions
218 }
219
220
221
222 func (c *Client) NewAggregateBuilder(ctx context.Context, index, query string) *AggregateBuilder {
223 return &AggregateBuilder{c: c, ctx: ctx, index: index, query: query, options: &FTAggregateOptions{LimitOffset: -1}}
224 }
225
226
227 func (b *AggregateBuilder) Verbatim() *AggregateBuilder { b.options.Verbatim = true; return b }
228
229
230 func (b *AggregateBuilder) AddScores() *AggregateBuilder { b.options.AddScores = true; return b }
231
232
233 func (b *AggregateBuilder) Scorer(s string) *AggregateBuilder {
234 b.options.Scorer = s
235 return b
236 }
237
238
239 func (b *AggregateBuilder) LoadAll() *AggregateBuilder {
240 b.options.LoadAll = true
241 return b
242 }
243
244
245
246 func (b *AggregateBuilder) Load(field string, alias ...string) *AggregateBuilder {
247
248 l := FTAggregateLoad{Field: field}
249 if len(alias) > 0 {
250 l.As = alias[0]
251 }
252 b.options.Load = append(b.options.Load, l)
253 return b
254 }
255
256
257 func (b *AggregateBuilder) Timeout(ms int) *AggregateBuilder {
258 b.options.Timeout = ms
259 return b
260 }
261
262
263 func (b *AggregateBuilder) Apply(field string, alias ...string) *AggregateBuilder {
264 a := FTAggregateApply{Field: field}
265 if len(alias) > 0 {
266 a.As = alias[0]
267 }
268 b.options.Apply = append(b.options.Apply, a)
269 return b
270 }
271
272
273 func (b *AggregateBuilder) GroupBy(fields ...interface{}) *AggregateBuilder {
274 b.options.GroupBy = append(b.options.GroupBy, FTAggregateGroupBy{
275 Fields: fields,
276 })
277 return b
278 }
279
280
281 func (b *AggregateBuilder) Reduce(fn SearchAggregator, args ...interface{}) *AggregateBuilder {
282 if len(b.options.GroupBy) == 0 {
283
284 return b
285 }
286 idx := len(b.options.GroupBy) - 1
287 b.options.GroupBy[idx].Reduce = append(b.options.GroupBy[idx].Reduce, FTAggregateReducer{
288 Reducer: fn,
289 Args: args,
290 })
291 return b
292 }
293
294
295 func (b *AggregateBuilder) ReduceAs(fn SearchAggregator, alias string, args ...interface{}) *AggregateBuilder {
296 if len(b.options.GroupBy) == 0 {
297 return b
298 }
299 idx := len(b.options.GroupBy) - 1
300 b.options.GroupBy[idx].Reduce = append(b.options.GroupBy[idx].Reduce, FTAggregateReducer{
301 Reducer: fn,
302 Args: args,
303 As: alias,
304 })
305 return b
306 }
307
308
309 func (b *AggregateBuilder) SortBy(field string, asc bool) *AggregateBuilder {
310 sb := FTAggregateSortBy{FieldName: field, Asc: asc, Desc: !asc}
311 b.options.SortBy = append(b.options.SortBy, sb)
312 return b
313 }
314
315
316 func (b *AggregateBuilder) SortByMax(max int) *AggregateBuilder {
317 b.options.SortByMax = max
318 return b
319 }
320
321
322 func (b *AggregateBuilder) Filter(expr string) *AggregateBuilder {
323 b.options.Filter = expr
324 return b
325 }
326
327
328 func (b *AggregateBuilder) WithCursor(count, maxIdle int) *AggregateBuilder {
329 b.options.WithCursor = true
330 if b.options.WithCursorOptions == nil {
331 b.options.WithCursorOptions = &FTAggregateWithCursor{}
332 }
333 b.options.WithCursorOptions.Count = count
334 b.options.WithCursorOptions.MaxIdle = maxIdle
335 return b
336 }
337
338
339 func (b *AggregateBuilder) Params(p map[string]interface{}) *AggregateBuilder {
340 if b.options.Params == nil {
341 b.options.Params = make(map[string]interface{}, len(p))
342 }
343 for k, v := range p {
344 b.options.Params[k] = v
345 }
346 return b
347 }
348
349
350 func (b *AggregateBuilder) Dialect(version int) *AggregateBuilder {
351 b.options.DialectVersion = version
352 return b
353 }
354
355
356 func (b *AggregateBuilder) Run() (*FTAggregateResult, error) {
357 cmd := b.c.FTAggregateWithArgs(b.ctx, b.index, b.query, b.options)
358 return cmd.Result()
359 }
360
361
362
363
364
365
366 type CreateIndexBuilder struct {
367 c *Client
368 ctx context.Context
369 index string
370 options *FTCreateOptions
371 schema []*FieldSchema
372 }
373
374
375
376 func (c *Client) NewCreateIndexBuilder(ctx context.Context, index string) *CreateIndexBuilder {
377 return &CreateIndexBuilder{c: c, ctx: ctx, index: index, options: &FTCreateOptions{}}
378 }
379
380
381 func (b *CreateIndexBuilder) OnHash() *CreateIndexBuilder { b.options.OnHash = true; return b }
382
383
384 func (b *CreateIndexBuilder) OnJSON() *CreateIndexBuilder { b.options.OnJSON = true; return b }
385
386
387 func (b *CreateIndexBuilder) Prefix(prefixes ...interface{}) *CreateIndexBuilder {
388 b.options.Prefix = prefixes
389 return b
390 }
391
392
393 func (b *CreateIndexBuilder) Filter(filter string) *CreateIndexBuilder {
394 b.options.Filter = filter
395 return b
396 }
397
398
399 func (b *CreateIndexBuilder) DefaultLanguage(lang string) *CreateIndexBuilder {
400 b.options.DefaultLanguage = lang
401 return b
402 }
403
404
405 func (b *CreateIndexBuilder) LanguageField(field string) *CreateIndexBuilder {
406 b.options.LanguageField = field
407 return b
408 }
409
410
411 func (b *CreateIndexBuilder) Score(score float64) *CreateIndexBuilder {
412 b.options.Score = score
413 return b
414 }
415
416
417 func (b *CreateIndexBuilder) ScoreField(field string) *CreateIndexBuilder {
418 b.options.ScoreField = field
419 return b
420 }
421
422
423 func (b *CreateIndexBuilder) PayloadField(field string) *CreateIndexBuilder {
424 b.options.PayloadField = field
425 return b
426 }
427
428
429 func (b *CreateIndexBuilder) NoOffsets() *CreateIndexBuilder { b.options.NoOffsets = true; return b }
430
431
432 func (b *CreateIndexBuilder) Temporary(sec int) *CreateIndexBuilder {
433 b.options.Temporary = sec
434 return b
435 }
436
437
438 func (b *CreateIndexBuilder) NoHL() *CreateIndexBuilder { b.options.NoHL = true; return b }
439
440
441 func (b *CreateIndexBuilder) NoFields() *CreateIndexBuilder { b.options.NoFields = true; return b }
442
443
444 func (b *CreateIndexBuilder) NoFreqs() *CreateIndexBuilder { b.options.NoFreqs = true; return b }
445
446
447 func (b *CreateIndexBuilder) StopWords(words ...interface{}) *CreateIndexBuilder {
448 b.options.StopWords = words
449 return b
450 }
451
452
453 func (b *CreateIndexBuilder) SkipInitialScan() *CreateIndexBuilder {
454 b.options.SkipInitialScan = true
455 return b
456 }
457
458
459 func (b *CreateIndexBuilder) Schema(field *FieldSchema) *CreateIndexBuilder {
460 b.schema = append(b.schema, field)
461 return b
462 }
463
464
465 func (b *CreateIndexBuilder) Run() (string, error) {
466 cmd := b.c.FTCreate(b.ctx, b.index, b.options, b.schema...)
467 return cmd.Result()
468 }
469
470
471
472
473
474
475 type DropIndexBuilder struct {
476 c *Client
477 ctx context.Context
478 index string
479 options *FTDropIndexOptions
480 }
481
482
483
484 func (c *Client) NewDropIndexBuilder(ctx context.Context, index string) *DropIndexBuilder {
485 return &DropIndexBuilder{c: c, ctx: ctx, index: index}
486 }
487
488
489 func (b *DropIndexBuilder) DeleteDocs() *DropIndexBuilder { b.options.DeleteDocs = true; return b }
490
491
492 func (b *DropIndexBuilder) Run() (string, error) {
493 cmd := b.c.FTDropIndexWithArgs(b.ctx, b.index, b.options)
494 return cmd.Result()
495 }
496
497
498
499
500
501
502 type AliasBuilder struct {
503 c *Client
504 ctx context.Context
505 alias string
506 index string
507 action string
508 }
509
510
511
512 func (c *Client) NewAliasBuilder(ctx context.Context, alias string) *AliasBuilder {
513 return &AliasBuilder{c: c, ctx: ctx, alias: alias}
514 }
515
516
517 func (b *AliasBuilder) Action(action string) *AliasBuilder {
518 b.action = action
519 return b
520 }
521
522
523 func (b *AliasBuilder) Add(index string) *AliasBuilder {
524 b.action = "add"
525 b.index = index
526 return b
527 }
528
529
530 func (b *AliasBuilder) Del() *AliasBuilder {
531 b.action = "del"
532 return b
533 }
534
535
536 func (b *AliasBuilder) Update(index string) *AliasBuilder {
537 b.action = "update"
538 b.index = index
539 return b
540 }
541
542
543 func (b *AliasBuilder) Run() (string, error) {
544 switch b.action {
545 case "add":
546 cmd := b.c.FTAliasAdd(b.ctx, b.index, b.alias)
547 return cmd.Result()
548 case "del":
549 cmd := b.c.FTAliasDel(b.ctx, b.alias)
550 return cmd.Result()
551 case "update":
552 cmd := b.c.FTAliasUpdate(b.ctx, b.index, b.alias)
553 return cmd.Result()
554 }
555 return "", nil
556 }
557
558
559
560
561
562
563 type ExplainBuilder struct {
564 c *Client
565 ctx context.Context
566 index string
567 query string
568 options *FTExplainOptions
569 }
570
571
572
573 func (c *Client) NewExplainBuilder(ctx context.Context, index, query string) *ExplainBuilder {
574 return &ExplainBuilder{c: c, ctx: ctx, index: index, query: query, options: &FTExplainOptions{}}
575 }
576
577
578 func (b *ExplainBuilder) Dialect(d string) *ExplainBuilder { b.options.Dialect = d; return b }
579
580
581 func (b *ExplainBuilder) Run() (string, error) {
582 cmd := b.c.FTExplainWithArgs(b.ctx, b.index, b.query, b.options)
583 return cmd.Result()
584 }
585
586
587
588
589
590 type FTInfoBuilder struct {
591 c *Client
592 ctx context.Context
593 index string
594 }
595
596
597 func (c *Client) NewSearchInfoBuilder(ctx context.Context, index string) *FTInfoBuilder {
598 return &FTInfoBuilder{c: c, ctx: ctx, index: index}
599 }
600
601
602 func (b *FTInfoBuilder) Run() (FTInfoResult, error) {
603 cmd := b.c.FTInfo(b.ctx, b.index)
604 return cmd.Result()
605 }
606
607
608
609
610
611
612 type SpellCheckBuilder struct {
613 c *Client
614 ctx context.Context
615 index string
616 query string
617 options *FTSpellCheckOptions
618 }
619
620
621
622 func (c *Client) NewSpellCheckBuilder(ctx context.Context, index, query string) *SpellCheckBuilder {
623 return &SpellCheckBuilder{c: c, ctx: ctx, index: index, query: query, options: &FTSpellCheckOptions{}}
624 }
625
626
627 func (b *SpellCheckBuilder) Distance(d int) *SpellCheckBuilder { b.options.Distance = d; return b }
628
629
630 func (b *SpellCheckBuilder) Terms(include bool, dictionary string, terms ...interface{}) *SpellCheckBuilder {
631 if b.options.Terms == nil {
632 b.options.Terms = &FTSpellCheckTerms{}
633 }
634 if include {
635 b.options.Terms.Inclusion = "INCLUDE"
636 } else {
637 b.options.Terms.Inclusion = "EXCLUDE"
638 }
639 b.options.Terms.Dictionary = dictionary
640 b.options.Terms.Terms = terms
641 return b
642 }
643
644
645 func (b *SpellCheckBuilder) Dialect(d int) *SpellCheckBuilder { b.options.Dialect = d; return b }
646
647
648 func (b *SpellCheckBuilder) Run() ([]SpellCheckResult, error) {
649 cmd := b.c.FTSpellCheckWithArgs(b.ctx, b.index, b.query, b.options)
650 return cmd.Result()
651 }
652
653
654
655
656
657
658 type DictBuilder struct {
659 c *Client
660 ctx context.Context
661 dict string
662 terms []interface{}
663 action string
664 }
665
666
667
668 func (c *Client) NewDictBuilder(ctx context.Context, dict string) *DictBuilder {
669 return &DictBuilder{c: c, ctx: ctx, dict: dict}
670 }
671
672
673 func (b *DictBuilder) Action(action string) *DictBuilder {
674 b.action = action
675 return b
676 }
677
678
679 func (b *DictBuilder) Add(terms ...interface{}) *DictBuilder {
680 b.action = "add"
681 b.terms = terms
682 return b
683 }
684
685
686 func (b *DictBuilder) Del(terms ...interface{}) *DictBuilder {
687 b.action = "del"
688 b.terms = terms
689 return b
690 }
691
692
693 func (b *DictBuilder) Dump() *DictBuilder {
694 b.action = "dump"
695 return b
696 }
697
698
699 func (b *DictBuilder) Run() (interface{}, error) {
700 switch b.action {
701 case "add":
702 cmd := b.c.FTDictAdd(b.ctx, b.dict, b.terms...)
703 return cmd.Result()
704 case "del":
705 cmd := b.c.FTDictDel(b.ctx, b.dict, b.terms...)
706 return cmd.Result()
707 case "dump":
708 cmd := b.c.FTDictDump(b.ctx, b.dict)
709 return cmd.Result()
710 }
711 return nil, nil
712 }
713
714
715
716
717
718
719 type TagValsBuilder struct {
720 c *Client
721 ctx context.Context
722 index string
723 field string
724 }
725
726
727
728 func (c *Client) NewTagValsBuilder(ctx context.Context, index, field string) *TagValsBuilder {
729 return &TagValsBuilder{c: c, ctx: ctx, index: index, field: field}
730 }
731
732
733 func (b *TagValsBuilder) Run() ([]string, error) {
734 cmd := b.c.FTTagVals(b.ctx, b.index, b.field)
735 return cmd.Result()
736 }
737
738
739
740
741
742
743 type CursorBuilder struct {
744 c *Client
745 ctx context.Context
746 index string
747 cursorId int64
748 count int
749 action string
750 }
751
752
753
754 func (c *Client) NewCursorBuilder(ctx context.Context, index string, cursorId int64) *CursorBuilder {
755 return &CursorBuilder{c: c, ctx: ctx, index: index, cursorId: cursorId}
756 }
757
758
759 func (b *CursorBuilder) Action(action string) *CursorBuilder {
760 b.action = action
761 return b
762 }
763
764
765 func (b *CursorBuilder) Read() *CursorBuilder {
766 b.action = "read"
767 return b
768 }
769
770
771 func (b *CursorBuilder) Del() *CursorBuilder {
772 b.action = "del"
773 return b
774 }
775
776
777 func (b *CursorBuilder) Count(count int) *CursorBuilder { b.count = count; return b }
778
779
780 func (b *CursorBuilder) Run() (interface{}, error) {
781 switch b.action {
782 case "read":
783 cmd := b.c.FTCursorRead(b.ctx, b.index, int(b.cursorId), b.count)
784 return cmd.Result()
785 case "del":
786 cmd := b.c.FTCursorDel(b.ctx, b.index, int(b.cursorId))
787 return cmd.Result()
788 }
789 return nil, nil
790 }
791
792
793
794
795
796
797 type SynUpdateBuilder struct {
798 c *Client
799 ctx context.Context
800 index string
801 groupId interface{}
802 options *FTSynUpdateOptions
803 terms []interface{}
804 }
805
806
807
808 func (c *Client) NewSynUpdateBuilder(ctx context.Context, index string, groupId interface{}) *SynUpdateBuilder {
809 return &SynUpdateBuilder{c: c, ctx: ctx, index: index, groupId: groupId, options: &FTSynUpdateOptions{}}
810 }
811
812
813 func (b *SynUpdateBuilder) SkipInitialScan() *SynUpdateBuilder {
814 b.options.SkipInitialScan = true
815 return b
816 }
817
818
819 func (b *SynUpdateBuilder) Terms(terms ...interface{}) *SynUpdateBuilder { b.terms = terms; return b }
820
821
822 func (b *SynUpdateBuilder) Run() (string, error) {
823 cmd := b.c.FTSynUpdateWithArgs(b.ctx, b.index, b.groupId, b.options, b.terms)
824 return cmd.Result()
825 }
826
View as plain text