...

Source file src/github.com/redis/go-redis/v9/search_builders.go

Documentation: github.com/redis/go-redis/v9

     1  package redis
     2  
     3  import (
     4  	"context"
     5  )
     6  
     7  // ----------------------
     8  // Search Module Builders
     9  // ----------------------
    10  
    11  // SearchBuilder provides a fluent API for FT.SEARCH
    12  // (see original FTSearchOptions for all options).
    13  // EXPERIMENTAL: this API is subject to change, use with caution.
    14  type SearchBuilder struct {
    15  	c       *Client
    16  	ctx     context.Context
    17  	index   string
    18  	query   string
    19  	options *FTSearchOptions
    20  }
    21  
    22  // NewSearchBuilder creates a new SearchBuilder for FT.SEARCH commands.
    23  // EXPERIMENTAL: this API is subject to change, use with caution.
    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  // WithScores includes WITHSCORES.
    30  func (b *SearchBuilder) WithScores() *SearchBuilder {
    31  	b.options.WithScores = true
    32  	return b
    33  }
    34  
    35  // NoContent includes NOCONTENT.
    36  func (b *SearchBuilder) NoContent() *SearchBuilder { b.options.NoContent = true; return b }
    37  
    38  // Verbatim includes VERBATIM.
    39  func (b *SearchBuilder) Verbatim() *SearchBuilder { b.options.Verbatim = true; return b }
    40  
    41  // NoStopWords includes NOSTOPWORDS.
    42  func (b *SearchBuilder) NoStopWords() *SearchBuilder { b.options.NoStopWords = true; return b }
    43  
    44  // WithPayloads includes WITHPAYLOADS.
    45  func (b *SearchBuilder) WithPayloads() *SearchBuilder {
    46  	b.options.WithPayloads = true
    47  	return b
    48  }
    49  
    50  // WithSortKeys includes WITHSORTKEYS.
    51  func (b *SearchBuilder) WithSortKeys() *SearchBuilder {
    52  	b.options.WithSortKeys = true
    53  	return b
    54  }
    55  
    56  // Filter adds a FILTER clause: FILTER <field> <min> <max>.
    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  // GeoFilter adds a GEOFILTER clause: GEOFILTER <field> <lon> <lat> <radius> <unit>.
    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  // InKeys restricts the search to the given keys.
    79  func (b *SearchBuilder) InKeys(keys ...interface{}) *SearchBuilder {
    80  	b.options.InKeys = append(b.options.InKeys, keys...)
    81  	return b
    82  }
    83  
    84  // InFields restricts the search to the given fields.
    85  func (b *SearchBuilder) InFields(fields ...interface{}) *SearchBuilder {
    86  	b.options.InFields = append(b.options.InFields, fields...)
    87  	return b
    88  }
    89  
    90  // ReturnFields adds simple RETURN <n> <field>...
    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  // ReturnAs adds RETURN <field> AS <alias>.
    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  // Slop adds SLOP <n>.
   105  func (b *SearchBuilder) Slop(slop int) *SearchBuilder {
   106  	b.options.Slop = slop
   107  	return b
   108  }
   109  
   110  // Timeout adds TIMEOUT <ms>.
   111  func (b *SearchBuilder) Timeout(timeout int) *SearchBuilder {
   112  	b.options.Timeout = timeout
   113  	return b
   114  }
   115  
   116  // InOrder includes INORDER.
   117  func (b *SearchBuilder) InOrder() *SearchBuilder {
   118  	b.options.InOrder = true
   119  	return b
   120  }
   121  
   122  // Language sets LANGUAGE <lang>.
   123  func (b *SearchBuilder) Language(lang string) *SearchBuilder {
   124  	b.options.Language = lang
   125  	return b
   126  }
   127  
   128  // Expander sets EXPANDER <expander>.
   129  func (b *SearchBuilder) Expander(expander string) *SearchBuilder {
   130  	b.options.Expander = expander
   131  	return b
   132  }
   133  
   134  // Scorer sets SCORER <scorer>.
   135  func (b *SearchBuilder) Scorer(scorer string) *SearchBuilder {
   136  	b.options.Scorer = scorer
   137  	return b
   138  }
   139  
   140  // ExplainScore includes EXPLAINSCORE.
   141  func (b *SearchBuilder) ExplainScore() *SearchBuilder {
   142  	b.options.ExplainScore = true
   143  	return b
   144  }
   145  
   146  // Payload sets PAYLOAD <payload>.
   147  func (b *SearchBuilder) Payload(payload string) *SearchBuilder {
   148  	b.options.Payload = payload
   149  	return b
   150  }
   151  
   152  // SortBy adds SORTBY <field> ASC|DESC.
   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  // WithSortByCount includes WITHCOUNT (when used with SortBy).
   163  func (b *SearchBuilder) WithSortByCount() *SearchBuilder {
   164  	b.options.SortByWithCount = true
   165  	return b
   166  }
   167  
   168  // Param adds a single PARAMS <k> <v>.
   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  // ParamsMap adds multiple PARAMS at once.
   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  // Dialect sets DIALECT <version>.
   189  func (b *SearchBuilder) Dialect(version int) *SearchBuilder {
   190  	b.options.DialectVersion = version
   191  	return b
   192  }
   193  
   194  // Limit sets OFFSET and COUNT. CountOnly uses LIMIT 0 0.
   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  // Run executes FT.SEARCH and returns a typed result.
   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  // AggregateBuilder for FT.AGGREGATE
   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  // NewAggregateBuilder creates a new AggregateBuilder for FT.AGGREGATE commands.
   221  // EXPERIMENTAL: this API is subject to change, use with caution.
   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  // Verbatim includes VERBATIM.
   227  func (b *AggregateBuilder) Verbatim() *AggregateBuilder { b.options.Verbatim = true; return b }
   228  
   229  // AddScores includes ADDSCORES.
   230  func (b *AggregateBuilder) AddScores() *AggregateBuilder { b.options.AddScores = true; return b }
   231  
   232  // Scorer sets SCORER <scorer>.
   233  func (b *AggregateBuilder) Scorer(s string) *AggregateBuilder {
   234  	b.options.Scorer = s
   235  	return b
   236  }
   237  
   238  // LoadAll includes LOAD * (mutually exclusive with Load).
   239  func (b *AggregateBuilder) LoadAll() *AggregateBuilder {
   240  	b.options.LoadAll = true
   241  	return b
   242  }
   243  
   244  // Load adds LOAD <n> <field> [AS alias]...
   245  // You can call it multiple times for multiple fields.
   246  func (b *AggregateBuilder) Load(field string, alias ...string) *AggregateBuilder {
   247  	// each Load entry becomes one element in options.Load
   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  // Timeout sets TIMEOUT <ms>.
   257  func (b *AggregateBuilder) Timeout(ms int) *AggregateBuilder {
   258  	b.options.Timeout = ms
   259  	return b
   260  }
   261  
   262  // Apply adds APPLY <field> [AS alias].
   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  // GroupBy starts a new GROUPBY <fields...> clause.
   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  // Reduce adds a REDUCE <fn> [<#args> <args...>] clause to the *last* GROUPBY.
   281  func (b *AggregateBuilder) Reduce(fn SearchAggregator, args ...interface{}) *AggregateBuilder {
   282  	if len(b.options.GroupBy) == 0 {
   283  		// no GROUPBY yet — nothing to attach to
   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  // ReduceAs does the same but also sets an alias: REDUCE <fn> … AS <alias>
   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  // SortBy adds SORTBY <field> ASC|DESC.
   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  // SortByMax sets MAX <n> (only if SortBy was called).
   316  func (b *AggregateBuilder) SortByMax(max int) *AggregateBuilder {
   317  	b.options.SortByMax = max
   318  	return b
   319  }
   320  
   321  // Filter sets FILTER <expr>.
   322  func (b *AggregateBuilder) Filter(expr string) *AggregateBuilder {
   323  	b.options.Filter = expr
   324  	return b
   325  }
   326  
   327  // WithCursor enables WITHCURSOR [COUNT <n>] [MAXIDLE <ms>].
   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  // Params adds PARAMS <k v> pairs.
   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  // Dialect sets DIALECT <version>.
   350  func (b *AggregateBuilder) Dialect(version int) *AggregateBuilder {
   351  	b.options.DialectVersion = version
   352  	return b
   353  }
   354  
   355  // Run executes FT.AGGREGATE and returns a typed result.
   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  // CreateIndexBuilder for FT.CREATE
   363  // ----------------------
   364  // CreateIndexBuilder is builder for FT.CREATE
   365  // EXPERIMENTAL: this API is subject to change, use with caution.
   366  type CreateIndexBuilder struct {
   367  	c       *Client
   368  	ctx     context.Context
   369  	index   string
   370  	options *FTCreateOptions
   371  	schema  []*FieldSchema
   372  }
   373  
   374  // NewCreateIndexBuilder creates a new CreateIndexBuilder for FT.CREATE commands.
   375  // EXPERIMENTAL: this API is subject to change, use with caution.
   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  // OnHash sets ON HASH.
   381  func (b *CreateIndexBuilder) OnHash() *CreateIndexBuilder { b.options.OnHash = true; return b }
   382  
   383  // OnJSON sets ON JSON.
   384  func (b *CreateIndexBuilder) OnJSON() *CreateIndexBuilder { b.options.OnJSON = true; return b }
   385  
   386  // Prefix sets PREFIX.
   387  func (b *CreateIndexBuilder) Prefix(prefixes ...interface{}) *CreateIndexBuilder {
   388  	b.options.Prefix = prefixes
   389  	return b
   390  }
   391  
   392  // Filter sets FILTER.
   393  func (b *CreateIndexBuilder) Filter(filter string) *CreateIndexBuilder {
   394  	b.options.Filter = filter
   395  	return b
   396  }
   397  
   398  // DefaultLanguage sets LANGUAGE.
   399  func (b *CreateIndexBuilder) DefaultLanguage(lang string) *CreateIndexBuilder {
   400  	b.options.DefaultLanguage = lang
   401  	return b
   402  }
   403  
   404  // LanguageField sets LANGUAGE_FIELD.
   405  func (b *CreateIndexBuilder) LanguageField(field string) *CreateIndexBuilder {
   406  	b.options.LanguageField = field
   407  	return b
   408  }
   409  
   410  // Score sets SCORE.
   411  func (b *CreateIndexBuilder) Score(score float64) *CreateIndexBuilder {
   412  	b.options.Score = score
   413  	return b
   414  }
   415  
   416  // ScoreField sets SCORE_FIELD.
   417  func (b *CreateIndexBuilder) ScoreField(field string) *CreateIndexBuilder {
   418  	b.options.ScoreField = field
   419  	return b
   420  }
   421  
   422  // PayloadField sets PAYLOAD_FIELD.
   423  func (b *CreateIndexBuilder) PayloadField(field string) *CreateIndexBuilder {
   424  	b.options.PayloadField = field
   425  	return b
   426  }
   427  
   428  // NoOffsets includes NOOFFSETS.
   429  func (b *CreateIndexBuilder) NoOffsets() *CreateIndexBuilder { b.options.NoOffsets = true; return b }
   430  
   431  // Temporary sets TEMPORARY seconds.
   432  func (b *CreateIndexBuilder) Temporary(sec int) *CreateIndexBuilder {
   433  	b.options.Temporary = sec
   434  	return b
   435  }
   436  
   437  // NoHL includes NOHL.
   438  func (b *CreateIndexBuilder) NoHL() *CreateIndexBuilder { b.options.NoHL = true; return b }
   439  
   440  // NoFields includes NOFIELDS.
   441  func (b *CreateIndexBuilder) NoFields() *CreateIndexBuilder { b.options.NoFields = true; return b }
   442  
   443  // NoFreqs includes NOFREQS.
   444  func (b *CreateIndexBuilder) NoFreqs() *CreateIndexBuilder { b.options.NoFreqs = true; return b }
   445  
   446  // StopWords sets STOPWORDS.
   447  func (b *CreateIndexBuilder) StopWords(words ...interface{}) *CreateIndexBuilder {
   448  	b.options.StopWords = words
   449  	return b
   450  }
   451  
   452  // SkipInitialScan includes SKIPINITIALSCAN.
   453  func (b *CreateIndexBuilder) SkipInitialScan() *CreateIndexBuilder {
   454  	b.options.SkipInitialScan = true
   455  	return b
   456  }
   457  
   458  // Schema adds a FieldSchema.
   459  func (b *CreateIndexBuilder) Schema(field *FieldSchema) *CreateIndexBuilder {
   460  	b.schema = append(b.schema, field)
   461  	return b
   462  }
   463  
   464  // Run executes FT.CREATE and returns the status.
   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  // DropIndexBuilder for FT.DROPINDEX
   472  // ----------------------
   473  // DropIndexBuilder is a builder for FT.DROPINDEX
   474  // EXPERIMENTAL: this API is subject to change, use with caution.
   475  type DropIndexBuilder struct {
   476  	c       *Client
   477  	ctx     context.Context
   478  	index   string
   479  	options *FTDropIndexOptions
   480  }
   481  
   482  // NewDropIndexBuilder creates a new DropIndexBuilder for FT.DROPINDEX commands.
   483  // EXPERIMENTAL: this API is subject to change, use with caution.
   484  func (c *Client) NewDropIndexBuilder(ctx context.Context, index string) *DropIndexBuilder {
   485  	return &DropIndexBuilder{c: c, ctx: ctx, index: index}
   486  }
   487  
   488  // DeleteRuncs includes DD.
   489  func (b *DropIndexBuilder) DeleteDocs() *DropIndexBuilder { b.options.DeleteDocs = true; return b }
   490  
   491  // Run executes FT.DROPINDEX.
   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  // AliasBuilder for FT.ALIAS* commands
   499  // ----------------------
   500  // AliasBuilder is builder for FT.ALIAS* commands
   501  // EXPERIMENTAL: this API is subject to change, use with caution.
   502  type AliasBuilder struct {
   503  	c      *Client
   504  	ctx    context.Context
   505  	alias  string
   506  	index  string
   507  	action string // add|del|update
   508  }
   509  
   510  // NewAliasBuilder creates a new AliasBuilder for FT.ALIAS* commands.
   511  // EXPERIMENTAL: this API is subject to change, use with caution.
   512  func (c *Client) NewAliasBuilder(ctx context.Context, alias string) *AliasBuilder {
   513  	return &AliasBuilder{c: c, ctx: ctx, alias: alias}
   514  }
   515  
   516  // Action sets the action for the alias builder.
   517  func (b *AliasBuilder) Action(action string) *AliasBuilder {
   518  	b.action = action
   519  	return b
   520  }
   521  
   522  // Add sets the action to "add" and requires an index.
   523  func (b *AliasBuilder) Add(index string) *AliasBuilder {
   524  	b.action = "add"
   525  	b.index = index
   526  	return b
   527  }
   528  
   529  // Del sets the action to "del".
   530  func (b *AliasBuilder) Del() *AliasBuilder {
   531  	b.action = "del"
   532  	return b
   533  }
   534  
   535  // Update sets the action to "update" and requires an index.
   536  func (b *AliasBuilder) Update(index string) *AliasBuilder {
   537  	b.action = "update"
   538  	b.index = index
   539  	return b
   540  }
   541  
   542  // Run executes the configured alias command.
   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  // ExplainBuilder for FT.EXPLAIN
   560  // ----------------------
   561  // ExplainBuilder is builder for FT.EXPLAIN
   562  // EXPERIMENTAL: this API is subject to change, use with caution.
   563  type ExplainBuilder struct {
   564  	c       *Client
   565  	ctx     context.Context
   566  	index   string
   567  	query   string
   568  	options *FTExplainOptions
   569  }
   570  
   571  // NewExplainBuilder creates a new ExplainBuilder for FT.EXPLAIN commands.
   572  // EXPERIMENTAL: this API is subject to change, use with caution.
   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  // Dialect sets dialect for EXPLAINCLI.
   578  func (b *ExplainBuilder) Dialect(d string) *ExplainBuilder { b.options.Dialect = d; return b }
   579  
   580  // Run executes FT.EXPLAIN and returns the plan.
   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  // InfoBuilder for FT.INFO
   588  // ----------------------
   589  
   590  type FTInfoBuilder struct {
   591  	c     *Client
   592  	ctx   context.Context
   593  	index string
   594  }
   595  
   596  // NewSearchInfoBuilder creates a new FTInfoBuilder for FT.INFO commands.
   597  func (c *Client) NewSearchInfoBuilder(ctx context.Context, index string) *FTInfoBuilder {
   598  	return &FTInfoBuilder{c: c, ctx: ctx, index: index}
   599  }
   600  
   601  // Run executes FT.INFO and returns detailed info.
   602  func (b *FTInfoBuilder) Run() (FTInfoResult, error) {
   603  	cmd := b.c.FTInfo(b.ctx, b.index)
   604  	return cmd.Result()
   605  }
   606  
   607  // ----------------------
   608  // SpellCheckBuilder for FT.SPELLCHECK
   609  // ----------------------
   610  // SpellCheckBuilder is builder for FT.SPELLCHECK
   611  // EXPERIMENTAL: this API is subject to change, use with caution.
   612  type SpellCheckBuilder struct {
   613  	c       *Client
   614  	ctx     context.Context
   615  	index   string
   616  	query   string
   617  	options *FTSpellCheckOptions
   618  }
   619  
   620  // NewSpellCheckBuilder creates a new SpellCheckBuilder for FT.SPELLCHECK commands.
   621  // EXPERIMENTAL: this API is subject to change, use with caution.
   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  // Distance sets MAXDISTANCE.
   627  func (b *SpellCheckBuilder) Distance(d int) *SpellCheckBuilder { b.options.Distance = d; return b }
   628  
   629  // Terms sets INCLUDE or EXCLUDE terms.
   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  // Dialect sets dialect version.
   645  func (b *SpellCheckBuilder) Dialect(d int) *SpellCheckBuilder { b.options.Dialect = d; return b }
   646  
   647  // Run executes FT.SPELLCHECK and returns suggestions.
   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  // DictBuilder for FT.DICT* commands
   655  // ----------------------
   656  // DictBuilder is builder for FT.DICT* commands
   657  // EXPERIMENTAL: this API is subject to change, use with caution.
   658  type DictBuilder struct {
   659  	c      *Client
   660  	ctx    context.Context
   661  	dict   string
   662  	terms  []interface{}
   663  	action string // add|del|dump
   664  }
   665  
   666  // NewDictBuilder creates a new DictBuilder for FT.DICT* commands.
   667  // EXPERIMENTAL: this API is subject to change, use with caution.
   668  func (c *Client) NewDictBuilder(ctx context.Context, dict string) *DictBuilder {
   669  	return &DictBuilder{c: c, ctx: ctx, dict: dict}
   670  }
   671  
   672  // Action sets the action for the dictionary builder.
   673  func (b *DictBuilder) Action(action string) *DictBuilder {
   674  	b.action = action
   675  	return b
   676  }
   677  
   678  // Add sets the action to "add" and requires terms.
   679  func (b *DictBuilder) Add(terms ...interface{}) *DictBuilder {
   680  	b.action = "add"
   681  	b.terms = terms
   682  	return b
   683  }
   684  
   685  // Del sets the action to "del" and requires terms.
   686  func (b *DictBuilder) Del(terms ...interface{}) *DictBuilder {
   687  	b.action = "del"
   688  	b.terms = terms
   689  	return b
   690  }
   691  
   692  // Dump sets the action to "dump".
   693  func (b *DictBuilder) Dump() *DictBuilder {
   694  	b.action = "dump"
   695  	return b
   696  }
   697  
   698  // Run executes the configured dictionary command.
   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  // TagValsBuilder for FT.TAGVALS
   716  // ----------------------
   717  // TagValsBuilder is builder for FT.TAGVALS
   718  // EXPERIMENTAL: this API is subject to change, use with caution.
   719  type TagValsBuilder struct {
   720  	c     *Client
   721  	ctx   context.Context
   722  	index string
   723  	field string
   724  }
   725  
   726  // NewTagValsBuilder creates a new TagValsBuilder for FT.TAGVALS commands.
   727  // EXPERIMENTAL: this API is subject to change, use with caution.
   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  // Run executes FT.TAGVALS and returns tag values.
   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  // CursorBuilder for FT.CURSOR*
   740  // ----------------------
   741  // CursorBuilder is builder for FT.CURSOR* commands
   742  // EXPERIMENTAL: this API is subject to change, use with caution.
   743  type CursorBuilder struct {
   744  	c        *Client
   745  	ctx      context.Context
   746  	index    string
   747  	cursorId int64
   748  	count    int
   749  	action   string // read|del
   750  }
   751  
   752  // NewCursorBuilder creates a new CursorBuilder for FT.CURSOR* commands.
   753  // EXPERIMENTAL: this API is subject to change, use with caution.
   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  // Action sets the action for the cursor builder.
   759  func (b *CursorBuilder) Action(action string) *CursorBuilder {
   760  	b.action = action
   761  	return b
   762  }
   763  
   764  // Read sets the action to "read".
   765  func (b *CursorBuilder) Read() *CursorBuilder {
   766  	b.action = "read"
   767  	return b
   768  }
   769  
   770  // Del sets the action to "del".
   771  func (b *CursorBuilder) Del() *CursorBuilder {
   772  	b.action = "del"
   773  	return b
   774  }
   775  
   776  // Count for READ.
   777  func (b *CursorBuilder) Count(count int) *CursorBuilder { b.count = count; return b }
   778  
   779  // Run executes the cursor command.
   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  // SynUpdateBuilder for FT.SYNUPDATE
   794  // ----------------------
   795  // SyncUpdateBuilder is builder for FT.SYNCUPDATE
   796  // EXPERIMENTAL: this API is subject to change, use with caution.
   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  // NewSynUpdateBuilder creates a new SynUpdateBuilder for FT.SYNUPDATE commands.
   807  // EXPERIMENTAL: this API is subject to change, use with caution.
   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  // SkipInitialScan includes SKIPINITIALSCAN.
   813  func (b *SynUpdateBuilder) SkipInitialScan() *SynUpdateBuilder {
   814  	b.options.SkipInitialScan = true
   815  	return b
   816  }
   817  
   818  // Terms adds synonyms to the group.
   819  func (b *SynUpdateBuilder) Terms(terms ...interface{}) *SynUpdateBuilder { b.terms = terms; return b }
   820  
   821  // Run executes FT.SYNUPDATE.
   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