-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Expand file tree
/
Copy pathsearch_builders.go
More file actions
825 lines (707 loc) · 23.7 KB
/
search_builders.go
File metadata and controls
825 lines (707 loc) · 23.7 KB
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
package redis
import (
"context"
)
// ----------------------
// Search Module Builders
// ----------------------
// SearchBuilder provides a fluent API for FT.SEARCH
// (see original FTSearchOptions for all options).
// EXPERIMENTAL: this API is subject to change, use with caution.
type SearchBuilder struct {
c *Client
ctx context.Context
index string
query string
options *FTSearchOptions
}
// NewSearchBuilder creates a new SearchBuilder for FT.SEARCH commands.
// EXPERIMENTAL: this API is subject to change, use with caution.
func (c *Client) NewSearchBuilder(ctx context.Context, index, query string) *SearchBuilder {
b := &SearchBuilder{c: c, ctx: ctx, index: index, query: query, options: &FTSearchOptions{LimitOffset: -1}}
return b
}
// WithScores includes WITHSCORES.
func (b *SearchBuilder) WithScores() *SearchBuilder {
b.options.WithScores = true
return b
}
// NoContent includes NOCONTENT.
func (b *SearchBuilder) NoContent() *SearchBuilder { b.options.NoContent = true; return b }
// Verbatim includes VERBATIM.
func (b *SearchBuilder) Verbatim() *SearchBuilder { b.options.Verbatim = true; return b }
// NoStopWords includes NOSTOPWORDS.
func (b *SearchBuilder) NoStopWords() *SearchBuilder { b.options.NoStopWords = true; return b }
// WithPayloads includes WITHPAYLOADS.
func (b *SearchBuilder) WithPayloads() *SearchBuilder {
b.options.WithPayloads = true
return b
}
// WithSortKeys includes WITHSORTKEYS.
func (b *SearchBuilder) WithSortKeys() *SearchBuilder {
b.options.WithSortKeys = true
return b
}
// Filter adds a FILTER clause: FILTER <field> <min> <max>.
func (b *SearchBuilder) Filter(field string, min, max interface{}) *SearchBuilder {
b.options.Filters = append(b.options.Filters, FTSearchFilter{
FieldName: field,
Min: min,
Max: max,
})
return b
}
// GeoFilter adds a GEOFILTER clause: GEOFILTER <field> <lon> <lat> <radius> <unit>.
func (b *SearchBuilder) GeoFilter(field string, lon, lat, radius float64, unit string) *SearchBuilder {
b.options.GeoFilter = append(b.options.GeoFilter, FTSearchGeoFilter{
FieldName: field,
Longitude: lon,
Latitude: lat,
Radius: radius,
Unit: unit,
})
return b
}
// InKeys restricts the search to the given keys.
func (b *SearchBuilder) InKeys(keys ...interface{}) *SearchBuilder {
b.options.InKeys = append(b.options.InKeys, keys...)
return b
}
// InFields restricts the search to the given fields.
func (b *SearchBuilder) InFields(fields ...interface{}) *SearchBuilder {
b.options.InFields = append(b.options.InFields, fields...)
return b
}
// ReturnFields adds simple RETURN <n> <field>...
func (b *SearchBuilder) ReturnFields(fields ...string) *SearchBuilder {
for _, f := range fields {
b.options.Return = append(b.options.Return, FTSearchReturn{FieldName: f})
}
return b
}
// ReturnAs adds RETURN <field> AS <alias>.
func (b *SearchBuilder) ReturnAs(field, alias string) *SearchBuilder {
b.options.Return = append(b.options.Return, FTSearchReturn{FieldName: field, As: alias})
return b
}
// Slop adds SLOP <n>.
func (b *SearchBuilder) Slop(slop int) *SearchBuilder {
b.options.Slop = slop
return b
}
// Timeout adds TIMEOUT <ms>.
func (b *SearchBuilder) Timeout(timeout int) *SearchBuilder {
b.options.Timeout = timeout
return b
}
// InOrder includes INORDER.
func (b *SearchBuilder) InOrder() *SearchBuilder {
b.options.InOrder = true
return b
}
// Language sets LANGUAGE <lang>.
func (b *SearchBuilder) Language(lang string) *SearchBuilder {
b.options.Language = lang
return b
}
// Expander sets EXPANDER <expander>.
func (b *SearchBuilder) Expander(expander string) *SearchBuilder {
b.options.Expander = expander
return b
}
// Scorer sets SCORER <scorer>.
func (b *SearchBuilder) Scorer(scorer string) *SearchBuilder {
b.options.Scorer = scorer
return b
}
// ExplainScore includes EXPLAINSCORE.
func (b *SearchBuilder) ExplainScore() *SearchBuilder {
b.options.ExplainScore = true
return b
}
// Payload sets PAYLOAD <payload>.
func (b *SearchBuilder) Payload(payload string) *SearchBuilder {
b.options.Payload = payload
return b
}
// SortBy adds SORTBY <field> ASC|DESC.
func (b *SearchBuilder) SortBy(field string, asc bool) *SearchBuilder {
b.options.SortBy = append(b.options.SortBy, FTSearchSortBy{
FieldName: field,
Asc: asc,
Desc: !asc,
})
return b
}
// WithSortByCount includes WITHCOUNT (when used with SortBy).
func (b *SearchBuilder) WithSortByCount() *SearchBuilder {
b.options.SortByWithCount = true
return b
}
// Param adds a single PARAMS <k> <v>.
func (b *SearchBuilder) Param(key string, value interface{}) *SearchBuilder {
if b.options.Params == nil {
b.options.Params = make(map[string]interface{}, 1)
}
b.options.Params[key] = value
return b
}
// ParamsMap adds multiple PARAMS at once.
func (b *SearchBuilder) ParamsMap(p map[string]interface{}) *SearchBuilder {
if b.options.Params == nil {
b.options.Params = make(map[string]interface{}, len(p))
}
for k, v := range p {
b.options.Params[k] = v
}
return b
}
// Dialect sets DIALECT <version>.
func (b *SearchBuilder) Dialect(version int) *SearchBuilder {
b.options.DialectVersion = version
return b
}
// Limit sets OFFSET and COUNT. CountOnly uses LIMIT 0 0.
func (b *SearchBuilder) Limit(offset, count int) *SearchBuilder {
b.options.LimitOffset = offset
b.options.Limit = count
return b
}
func (b *SearchBuilder) CountOnly() *SearchBuilder { b.options.CountOnly = true; return b }
// Run executes FT.SEARCH and returns a typed result.
func (b *SearchBuilder) Run() (FTSearchResult, error) {
cmd := b.c.FTSearchWithArgs(b.ctx, b.index, b.query, b.options)
return cmd.Result()
}
// ----------------------
// AggregateBuilder for FT.AGGREGATE
// ----------------------
type AggregateBuilder struct {
c *Client
ctx context.Context
index string
query string
options *FTAggregateOptions
}
// NewAggregateBuilder creates a new AggregateBuilder for FT.AGGREGATE commands.
// EXPERIMENTAL: this API is subject to change, use with caution.
func (c *Client) NewAggregateBuilder(ctx context.Context, index, query string) *AggregateBuilder {
return &AggregateBuilder{c: c, ctx: ctx, index: index, query: query, options: &FTAggregateOptions{LimitOffset: -1}}
}
// Verbatim includes VERBATIM.
func (b *AggregateBuilder) Verbatim() *AggregateBuilder { b.options.Verbatim = true; return b }
// AddScores includes ADDSCORES.
func (b *AggregateBuilder) AddScores() *AggregateBuilder { b.options.AddScores = true; return b }
// Scorer sets SCORER <scorer>.
func (b *AggregateBuilder) Scorer(s string) *AggregateBuilder {
b.options.Scorer = s
return b
}
// LoadAll includes LOAD * (mutually exclusive with Load).
func (b *AggregateBuilder) LoadAll() *AggregateBuilder {
b.options.LoadAll = true
return b
}
// Load adds LOAD <n> <field> [AS alias]...
// You can call it multiple times for multiple fields.
func (b *AggregateBuilder) Load(field string, alias ...string) *AggregateBuilder {
// each Load entry becomes one element in options.Load
l := FTAggregateLoad{Field: field}
if len(alias) > 0 {
l.As = alias[0]
}
b.options.Load = append(b.options.Load, l)
return b
}
// Timeout sets TIMEOUT <ms>.
func (b *AggregateBuilder) Timeout(ms int) *AggregateBuilder {
b.options.Timeout = ms
return b
}
// Apply adds APPLY <field> [AS alias].
func (b *AggregateBuilder) Apply(field string, alias ...string) *AggregateBuilder {
a := FTAggregateApply{Field: field}
if len(alias) > 0 {
a.As = alias[0]
}
b.options.Apply = append(b.options.Apply, a)
return b
}
// GroupBy starts a new GROUPBY <fields...> clause.
func (b *AggregateBuilder) GroupBy(fields ...interface{}) *AggregateBuilder {
b.options.GroupBy = append(b.options.GroupBy, FTAggregateGroupBy{
Fields: fields,
})
return b
}
// Reduce adds a REDUCE <fn> [<#args> <args...>] clause to the *last* GROUPBY.
func (b *AggregateBuilder) Reduce(fn SearchAggregator, args ...interface{}) *AggregateBuilder {
if len(b.options.GroupBy) == 0 {
// no GROUPBY yet — nothing to attach to
return b
}
idx := len(b.options.GroupBy) - 1
b.options.GroupBy[idx].Reduce = append(b.options.GroupBy[idx].Reduce, FTAggregateReducer{
Reducer: fn,
Args: args,
})
return b
}
// ReduceAs does the same but also sets an alias: REDUCE <fn> … AS <alias>
func (b *AggregateBuilder) ReduceAs(fn SearchAggregator, alias string, args ...interface{}) *AggregateBuilder {
if len(b.options.GroupBy) == 0 {
return b
}
idx := len(b.options.GroupBy) - 1
b.options.GroupBy[idx].Reduce = append(b.options.GroupBy[idx].Reduce, FTAggregateReducer{
Reducer: fn,
Args: args,
As: alias,
})
return b
}
// SortBy adds SORTBY <field> ASC|DESC.
func (b *AggregateBuilder) SortBy(field string, asc bool) *AggregateBuilder {
sb := FTAggregateSortBy{FieldName: field, Asc: asc, Desc: !asc}
b.options.SortBy = append(b.options.SortBy, sb)
return b
}
// SortByMax sets MAX <n> (only if SortBy was called).
func (b *AggregateBuilder) SortByMax(max int) *AggregateBuilder {
b.options.SortByMax = max
return b
}
// Filter sets FILTER <expr>.
func (b *AggregateBuilder) Filter(expr string) *AggregateBuilder {
b.options.Filter = expr
return b
}
// WithCursor enables WITHCURSOR [COUNT <n>] [MAXIDLE <ms>].
func (b *AggregateBuilder) WithCursor(count, maxIdle int) *AggregateBuilder {
b.options.WithCursor = true
if b.options.WithCursorOptions == nil {
b.options.WithCursorOptions = &FTAggregateWithCursor{}
}
b.options.WithCursorOptions.Count = count
b.options.WithCursorOptions.MaxIdle = maxIdle
return b
}
// Params adds PARAMS <k v> pairs.
func (b *AggregateBuilder) Params(p map[string]interface{}) *AggregateBuilder {
if b.options.Params == nil {
b.options.Params = make(map[string]interface{}, len(p))
}
for k, v := range p {
b.options.Params[k] = v
}
return b
}
// Dialect sets DIALECT <version>.
func (b *AggregateBuilder) Dialect(version int) *AggregateBuilder {
b.options.DialectVersion = version
return b
}
// Run executes FT.AGGREGATE and returns a typed result.
func (b *AggregateBuilder) Run() (*FTAggregateResult, error) {
cmd := b.c.FTAggregateWithArgs(b.ctx, b.index, b.query, b.options)
return cmd.Result()
}
// ----------------------
// CreateIndexBuilder for FT.CREATE
// ----------------------
// CreateIndexBuilder is builder for FT.CREATE
// EXPERIMENTAL: this API is subject to change, use with caution.
type CreateIndexBuilder struct {
c *Client
ctx context.Context
index string
options *FTCreateOptions
schema []*FieldSchema
}
// NewCreateIndexBuilder creates a new CreateIndexBuilder for FT.CREATE commands.
// EXPERIMENTAL: this API is subject to change, use with caution.
func (c *Client) NewCreateIndexBuilder(ctx context.Context, index string) *CreateIndexBuilder {
return &CreateIndexBuilder{c: c, ctx: ctx, index: index, options: &FTCreateOptions{}}
}
// OnHash sets ON HASH.
func (b *CreateIndexBuilder) OnHash() *CreateIndexBuilder { b.options.OnHash = true; return b }
// OnJSON sets ON JSON.
func (b *CreateIndexBuilder) OnJSON() *CreateIndexBuilder { b.options.OnJSON = true; return b }
// Prefix sets PREFIX.
func (b *CreateIndexBuilder) Prefix(prefixes ...interface{}) *CreateIndexBuilder {
b.options.Prefix = prefixes
return b
}
// Filter sets FILTER.
func (b *CreateIndexBuilder) Filter(filter string) *CreateIndexBuilder {
b.options.Filter = filter
return b
}
// DefaultLanguage sets LANGUAGE.
func (b *CreateIndexBuilder) DefaultLanguage(lang string) *CreateIndexBuilder {
b.options.DefaultLanguage = lang
return b
}
// LanguageField sets LANGUAGE_FIELD.
func (b *CreateIndexBuilder) LanguageField(field string) *CreateIndexBuilder {
b.options.LanguageField = field
return b
}
// Score sets SCORE.
func (b *CreateIndexBuilder) Score(score float64) *CreateIndexBuilder {
b.options.Score = score
return b
}
// ScoreField sets SCORE_FIELD.
func (b *CreateIndexBuilder) ScoreField(field string) *CreateIndexBuilder {
b.options.ScoreField = field
return b
}
// PayloadField sets PAYLOAD_FIELD.
func (b *CreateIndexBuilder) PayloadField(field string) *CreateIndexBuilder {
b.options.PayloadField = field
return b
}
// NoOffsets includes NOOFFSETS.
func (b *CreateIndexBuilder) NoOffsets() *CreateIndexBuilder { b.options.NoOffsets = true; return b }
// Temporary sets TEMPORARY seconds.
func (b *CreateIndexBuilder) Temporary(sec int) *CreateIndexBuilder {
b.options.Temporary = sec
return b
}
// NoHL includes NOHL.
func (b *CreateIndexBuilder) NoHL() *CreateIndexBuilder { b.options.NoHL = true; return b }
// NoFields includes NOFIELDS.
func (b *CreateIndexBuilder) NoFields() *CreateIndexBuilder { b.options.NoFields = true; return b }
// NoFreqs includes NOFREQS.
func (b *CreateIndexBuilder) NoFreqs() *CreateIndexBuilder { b.options.NoFreqs = true; return b }
// StopWords sets STOPWORDS.
func (b *CreateIndexBuilder) StopWords(words ...interface{}) *CreateIndexBuilder {
b.options.StopWords = words
return b
}
// SkipInitialScan includes SKIPINITIALSCAN.
func (b *CreateIndexBuilder) SkipInitialScan() *CreateIndexBuilder {
b.options.SkipInitialScan = true
return b
}
// Schema adds a FieldSchema.
func (b *CreateIndexBuilder) Schema(field *FieldSchema) *CreateIndexBuilder {
b.schema = append(b.schema, field)
return b
}
// Run executes FT.CREATE and returns the status.
func (b *CreateIndexBuilder) Run() (string, error) {
cmd := b.c.FTCreate(b.ctx, b.index, b.options, b.schema...)
return cmd.Result()
}
// ----------------------
// DropIndexBuilder for FT.DROPINDEX
// ----------------------
// DropIndexBuilder is a builder for FT.DROPINDEX
// EXPERIMENTAL: this API is subject to change, use with caution.
type DropIndexBuilder struct {
c *Client
ctx context.Context
index string
options *FTDropIndexOptions
}
// NewDropIndexBuilder creates a new DropIndexBuilder for FT.DROPINDEX commands.
// EXPERIMENTAL: this API is subject to change, use with caution.
func (c *Client) NewDropIndexBuilder(ctx context.Context, index string) *DropIndexBuilder {
return &DropIndexBuilder{c: c, ctx: ctx, index: index}
}
// DeleteRuncs includes DD.
func (b *DropIndexBuilder) DeleteDocs() *DropIndexBuilder { b.options.DeleteDocs = true; return b }
// Run executes FT.DROPINDEX.
func (b *DropIndexBuilder) Run() (string, error) {
cmd := b.c.FTDropIndexWithArgs(b.ctx, b.index, b.options)
return cmd.Result()
}
// ----------------------
// AliasBuilder for FT.ALIAS* commands
// ----------------------
// AliasBuilder is builder for FT.ALIAS* commands
// EXPERIMENTAL: this API is subject to change, use with caution.
type AliasBuilder struct {
c *Client
ctx context.Context
alias string
index string
action string // add|del|update
}
// NewAliasBuilder creates a new AliasBuilder for FT.ALIAS* commands.
// EXPERIMENTAL: this API is subject to change, use with caution.
func (c *Client) NewAliasBuilder(ctx context.Context, alias string) *AliasBuilder {
return &AliasBuilder{c: c, ctx: ctx, alias: alias}
}
// Action sets the action for the alias builder.
func (b *AliasBuilder) Action(action string) *AliasBuilder {
b.action = action
return b
}
// Add sets the action to "add" and requires an index.
func (b *AliasBuilder) Add(index string) *AliasBuilder {
b.action = "add"
b.index = index
return b
}
// Del sets the action to "del".
func (b *AliasBuilder) Del() *AliasBuilder {
b.action = "del"
return b
}
// Update sets the action to "update" and requires an index.
func (b *AliasBuilder) Update(index string) *AliasBuilder {
b.action = "update"
b.index = index
return b
}
// Run executes the configured alias command.
func (b *AliasBuilder) Run() (string, error) {
switch b.action {
case "add":
cmd := b.c.FTAliasAdd(b.ctx, b.index, b.alias)
return cmd.Result()
case "del":
cmd := b.c.FTAliasDel(b.ctx, b.alias)
return cmd.Result()
case "update":
cmd := b.c.FTAliasUpdate(b.ctx, b.index, b.alias)
return cmd.Result()
}
return "", nil
}
// ----------------------
// ExplainBuilder for FT.EXPLAIN
// ----------------------
// ExplainBuilder is builder for FT.EXPLAIN
// EXPERIMENTAL: this API is subject to change, use with caution.
type ExplainBuilder struct {
c *Client
ctx context.Context
index string
query string
options *FTExplainOptions
}
// NewExplainBuilder creates a new ExplainBuilder for FT.EXPLAIN commands.
// EXPERIMENTAL: this API is subject to change, use with caution.
func (c *Client) NewExplainBuilder(ctx context.Context, index, query string) *ExplainBuilder {
return &ExplainBuilder{c: c, ctx: ctx, index: index, query: query, options: &FTExplainOptions{}}
}
// Dialect sets dialect for EXPLAINCLI.
func (b *ExplainBuilder) Dialect(d string) *ExplainBuilder { b.options.Dialect = d; return b }
// Run executes FT.EXPLAIN and returns the plan.
func (b *ExplainBuilder) Run() (string, error) {
cmd := b.c.FTExplainWithArgs(b.ctx, b.index, b.query, b.options)
return cmd.Result()
}
// ----------------------
// InfoBuilder for FT.INFO
// ----------------------
type FTInfoBuilder struct {
c *Client
ctx context.Context
index string
}
// NewSearchInfoBuilder creates a new FTInfoBuilder for FT.INFO commands.
func (c *Client) NewSearchInfoBuilder(ctx context.Context, index string) *FTInfoBuilder {
return &FTInfoBuilder{c: c, ctx: ctx, index: index}
}
// Run executes FT.INFO and returns detailed info.
func (b *FTInfoBuilder) Run() (FTInfoResult, error) {
cmd := b.c.FTInfo(b.ctx, b.index)
return cmd.Result()
}
// ----------------------
// SpellCheckBuilder for FT.SPELLCHECK
// ----------------------
// SpellCheckBuilder is builder for FT.SPELLCHECK
// EXPERIMENTAL: this API is subject to change, use with caution.
type SpellCheckBuilder struct {
c *Client
ctx context.Context
index string
query string
options *FTSpellCheckOptions
}
// NewSpellCheckBuilder creates a new SpellCheckBuilder for FT.SPELLCHECK commands.
// EXPERIMENTAL: this API is subject to change, use with caution.
func (c *Client) NewSpellCheckBuilder(ctx context.Context, index, query string) *SpellCheckBuilder {
return &SpellCheckBuilder{c: c, ctx: ctx, index: index, query: query, options: &FTSpellCheckOptions{}}
}
// Distance sets MAXDISTANCE.
func (b *SpellCheckBuilder) Distance(d int) *SpellCheckBuilder { b.options.Distance = d; return b }
// Terms sets INCLUDE or EXCLUDE terms.
func (b *SpellCheckBuilder) Terms(include bool, dictionary string, terms ...interface{}) *SpellCheckBuilder {
if b.options.Terms == nil {
b.options.Terms = &FTSpellCheckTerms{}
}
if include {
b.options.Terms.Inclusion = "INCLUDE"
} else {
b.options.Terms.Inclusion = "EXCLUDE"
}
b.options.Terms.Dictionary = dictionary
b.options.Terms.Terms = terms
return b
}
// Dialect sets dialect version.
func (b *SpellCheckBuilder) Dialect(d int) *SpellCheckBuilder { b.options.Dialect = d; return b }
// Run executes FT.SPELLCHECK and returns suggestions.
func (b *SpellCheckBuilder) Run() ([]SpellCheckResult, error) {
cmd := b.c.FTSpellCheckWithArgs(b.ctx, b.index, b.query, b.options)
return cmd.Result()
}
// ----------------------
// DictBuilder for FT.DICT* commands
// ----------------------
// DictBuilder is builder for FT.DICT* commands
// EXPERIMENTAL: this API is subject to change, use with caution.
type DictBuilder struct {
c *Client
ctx context.Context
dict string
terms []interface{}
action string // add|del|dump
}
// NewDictBuilder creates a new DictBuilder for FT.DICT* commands.
// EXPERIMENTAL: this API is subject to change, use with caution.
func (c *Client) NewDictBuilder(ctx context.Context, dict string) *DictBuilder {
return &DictBuilder{c: c, ctx: ctx, dict: dict}
}
// Action sets the action for the dictionary builder.
func (b *DictBuilder) Action(action string) *DictBuilder {
b.action = action
return b
}
// Add sets the action to "add" and requires terms.
func (b *DictBuilder) Add(terms ...interface{}) *DictBuilder {
b.action = "add"
b.terms = terms
return b
}
// Del sets the action to "del" and requires terms.
func (b *DictBuilder) Del(terms ...interface{}) *DictBuilder {
b.action = "del"
b.terms = terms
return b
}
// Dump sets the action to "dump".
func (b *DictBuilder) Dump() *DictBuilder {
b.action = "dump"
return b
}
// Run executes the configured dictionary command.
func (b *DictBuilder) Run() (interface{}, error) {
switch b.action {
case "add":
cmd := b.c.FTDictAdd(b.ctx, b.dict, b.terms...)
return cmd.Result()
case "del":
cmd := b.c.FTDictDel(b.ctx, b.dict, b.terms...)
return cmd.Result()
case "dump":
cmd := b.c.FTDictDump(b.ctx, b.dict)
return cmd.Result()
}
return nil, nil
}
// ----------------------
// TagValsBuilder for FT.TAGVALS
// ----------------------
// TagValsBuilder is builder for FT.TAGVALS
// EXPERIMENTAL: this API is subject to change, use with caution.
type TagValsBuilder struct {
c *Client
ctx context.Context
index string
field string
}
// NewTagValsBuilder creates a new TagValsBuilder for FT.TAGVALS commands.
// EXPERIMENTAL: this API is subject to change, use with caution.
func (c *Client) NewTagValsBuilder(ctx context.Context, index, field string) *TagValsBuilder {
return &TagValsBuilder{c: c, ctx: ctx, index: index, field: field}
}
// Run executes FT.TAGVALS and returns tag values.
func (b *TagValsBuilder) Run() ([]string, error) {
cmd := b.c.FTTagVals(b.ctx, b.index, b.field)
return cmd.Result()
}
// ----------------------
// CursorBuilder for FT.CURSOR*
// ----------------------
// CursorBuilder is builder for FT.CURSOR* commands
// EXPERIMENTAL: this API is subject to change, use with caution.
type CursorBuilder struct {
c *Client
ctx context.Context
index string
cursorId int64
count int
action string // read|del
}
// NewCursorBuilder creates a new CursorBuilder for FT.CURSOR* commands.
// EXPERIMENTAL: this API is subject to change, use with caution.
func (c *Client) NewCursorBuilder(ctx context.Context, index string, cursorId int64) *CursorBuilder {
return &CursorBuilder{c: c, ctx: ctx, index: index, cursorId: cursorId}
}
// Action sets the action for the cursor builder.
func (b *CursorBuilder) Action(action string) *CursorBuilder {
b.action = action
return b
}
// Read sets the action to "read".
func (b *CursorBuilder) Read() *CursorBuilder {
b.action = "read"
return b
}
// Del sets the action to "del".
func (b *CursorBuilder) Del() *CursorBuilder {
b.action = "del"
return b
}
// Count for READ.
func (b *CursorBuilder) Count(count int) *CursorBuilder { b.count = count; return b }
// Run executes the cursor command.
func (b *CursorBuilder) Run() (interface{}, error) {
switch b.action {
case "read":
cmd := b.c.FTCursorRead(b.ctx, b.index, int(b.cursorId), b.count)
return cmd.Result()
case "del":
cmd := b.c.FTCursorDel(b.ctx, b.index, int(b.cursorId))
return cmd.Result()
}
return nil, nil
}
// ----------------------
// SynUpdateBuilder for FT.SYNUPDATE
// ----------------------
// SyncUpdateBuilder is builder for FT.SYNCUPDATE
// EXPERIMENTAL: this API is subject to change, use with caution.
type SynUpdateBuilder struct {
c *Client
ctx context.Context
index string
groupId interface{}
options *FTSynUpdateOptions
terms []interface{}
}
// NewSynUpdateBuilder creates a new SynUpdateBuilder for FT.SYNUPDATE commands.
// EXPERIMENTAL: this API is subject to change, use with caution.
func (c *Client) NewSynUpdateBuilder(ctx context.Context, index string, groupId interface{}) *SynUpdateBuilder {
return &SynUpdateBuilder{c: c, ctx: ctx, index: index, groupId: groupId, options: &FTSynUpdateOptions{}}
}
// SkipInitialScan includes SKIPINITIALSCAN.
func (b *SynUpdateBuilder) SkipInitialScan() *SynUpdateBuilder {
b.options.SkipInitialScan = true
return b
}
// Terms adds synonyms to the group.
func (b *SynUpdateBuilder) Terms(terms ...interface{}) *SynUpdateBuilder { b.terms = terms; return b }
// Run executes FT.SYNUPDATE.
func (b *SynUpdateBuilder) Run() (string, error) {
cmd := b.c.FTSynUpdateWithArgs(b.ctx, b.index, b.groupId, b.options, b.terms)
return cmd.Result()
}