Skip to content

Commit

Permalink
Add schema support ( FT.ALTER ) (#28)
Browse files Browse the repository at this point in the history
* Add schema support ( FT.ALTER )

Co-authored-by: filipe oliveira <[email protected]>
  • Loading branch information
felixls and filipecosta90 authored May 1, 2020
1 parent 9e670fa commit 8eec4dd
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 82 deletions.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
- run: go test -v ./... -race -coverprofile=coverage.txt -covermode=atomic
- run: bash <(curl -s https://codecov.io/bash) -t ${CODECOV_TOKEN}

build_nightly: # test nightly with redisearch:edge
build_nightly: # test nightly with redisearch:edge
docker:
- image: circleci/golang:1.9
- image: redislabs/redisearch:edge
Expand All @@ -40,4 +40,4 @@ workflows:
only:
- master
jobs:
- build_nightly
- build_nightly
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func ExampleClient() {
| [FT.CREATE](https://oss.redislabs.com/redisearch/Commands.html#ftcreate) | [CreateIndex](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.CreateIndex) |
| [FT.ADD](https://oss.redislabs.com/redisearch/Commands.html#ftadd) | [IndexOptions](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.IndexOptions) |
| [FT.ADDHASH](https://oss.redislabs.com/redisearch/Commands.html#ftaddhash) | [AddHash](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.AddHash) |
| [FT.ALTER](https://oss.redislabs.com/redisearch/Commands.html#ftalter) | N/A |
| [FT.ALTER](https://oss.redislabs.com/redisearch/Commands.html#ftalter) | [AddField](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.AddField) |
| [FT.ALIASADD](https://oss.redislabs.com/redisearch/Commands.html#ftaliasadd) | [AliasAdd](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.AliasAdd) |
| [FT.ALIASUPDATE](https://oss.redislabs.com/redisearch/Commands.html#ftaliasupdate) | [AliasUpdate](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.AliasUpdate) |
| [FT.ALIASDEL](https://oss.redislabs.com/redisearch/Commands.html#ftaliasdel) | [AliasDel](https://godoc.org/github.com/RediSearch/redisearch-go/redisearch#Client.AliasDel) |
Expand Down
15 changes: 14 additions & 1 deletion redisearch/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"reflect"
"strconv"
"strings"

"github.com/gomodule/redigo/redis"
)

Expand Down Expand Up @@ -62,6 +61,20 @@ func (i *Client) CreateIndex(s *Schema) (err error) {
return err
}

// AddField Adds a new field to the index.
func (i *Client) AddField(f Field) error {
args := redis.Args{i.name}
args = append(args, "SCHEMA", "ADD")
args,err := serializeField(f,args)
if err != nil {
return err
}
conn := i.pool.Get()
defer conn.Close()
_, err = conn.Do("FT.ALTER", args...)
return err
}

// Index indexes a list of documents with the default options
func (i *Client) Index(docs ...Document) error {
return i.IndexOptions(DefaultIndexingOptions, docs...)
Expand Down
14 changes: 14 additions & 0 deletions redisearch/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -530,3 +530,17 @@ func TestClient_AddHash(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, "OK", ret)
}

func TestClient_AddField(t *testing.T) {
c := createClient("alterTest")
sc := NewSchema(DefaultOptions).
AddField(NewTextField("name")).
AddField(NewTextField("addr"))
c.Drop()
err := c.CreateIndex(sc)
assert.Nil(t, err)
err = c.AddField(NewNumericField("age"))
assert.Nil(t, err)
err = c.Index(NewDocument("doc-n1",1.0).Set("age",15 ))
assert.Nil(t, err)
}
161 changes: 83 additions & 78 deletions redisearch/schema.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package redisearch

import (
"errors"
"fmt"
"github.com/gomodule/redigo/redis"
)
Expand Down Expand Up @@ -203,100 +202,106 @@ func (m *Schema) AddField(f Field) *Schema {
return m
}

func SerializeSchema(s *Schema, args redis.Args) (redis.Args, error) {
func SerializeSchema(s *Schema, args redis.Args) (argsOut redis.Args, err error) {
argsOut = args
if s.Options.NoFieldFlags {
args = append(args, "NOFIELDS")
argsOut = append(argsOut, "NOFIELDS")
}
if s.Options.NoFrequencies {
args = append(args, "NOFREQS")
argsOut = append(argsOut, "NOFREQS")
}
if s.Options.NoOffsetVectors {
args = append(args, "NOOFFSETS")
argsOut = append(argsOut, "NOOFFSETS")
}
if s.Options.Stopwords != nil {
args = args.Add("STOPWORDS", len(s.Options.Stopwords))
argsOut = argsOut.Add("STOPWORDS", len(s.Options.Stopwords))
if len(s.Options.Stopwords) > 0 {
args = args.AddFlat(s.Options.Stopwords)
argsOut = argsOut.AddFlat(s.Options.Stopwords)
}
}

args = append(args, "SCHEMA")
argsOut = append(argsOut, "SCHEMA")
for _, f := range s.Fields {
argsOut, err = serializeField(f, argsOut)
if err != nil {
return nil,err
}
}
return
}

switch f.Type {
case TextField:

args = append(args, f.Name, "TEXT")
if f.Options != nil {
opts, ok := f.Options.(TextFieldOptions)
if !ok {
return nil, errors.New("Invalid text field options type")
}

if opts.Weight != 0 && opts.Weight != 1 {
args = append(args, "WEIGHT", opts.Weight)
}
if opts.NoStem {
args = append(args, "NOSTEM")
}

if opts.Sortable {
args = append(args, "SORTABLE")
}

if opts.NoIndex {
args = append(args, "NOINDEX")
}
func serializeField(f Field, args redis.Args) (argsOut redis.Args, err error) {
argsOut = args
switch f.Type {
case TextField:
argsOut = append(argsOut, f.Name, "TEXT")
if f.Options != nil {
opts, ok := f.Options.(TextFieldOptions)
if !ok {
err = fmt.Errorf("Error on TextField serialization")
return
}

case NumericField:
args = append(args, f.Name, "NUMERIC")
if f.Options != nil {
opts, ok := f.Options.(NumericFieldOptions)
if !ok {
return nil, errors.New("Invalid numeric field options type")
}

if opts.Sortable {
args = append(args, "SORTABLE")
}
if opts.NoIndex {
args = append(args, "NOINDEX")
}
if opts.Weight != 0 && opts.Weight != 1 {
argsOut = append(argsOut, "WEIGHT", opts.Weight)
}
if opts.NoStem {
argsOut = append(argsOut, "NOSTEM")
}
case TagField:
args = append(args, f.Name, "TAG")
if f.Options != nil {
opts, ok := f.Options.(TagFieldOptions)
if !ok {
return nil, errors.New("Invalid tag field options type")
}
if opts.Separator != 0 {
args = append(args, "SEPARATOR", fmt.Sprintf("%c", opts.Separator))

}
if opts.Sortable {
args = append(args, "SORTABLE")
}
if opts.NoIndex {
args = append(args, "NOINDEX")
}
if opts.Sortable {
argsOut = append(argsOut, "SORTABLE")
}
case GeoField:
args = append(args, f.Name, "GEO")
if f.Options != nil {
opts, ok := f.Options.(GeoFieldOptions)
if !ok {
return nil, errors.New("Invalid geo field options type")
}
if opts.NoIndex {
args = append(args, "NOINDEX")
}
if opts.NoIndex {
argsOut = append(argsOut, "NOINDEX")
}
default:
return nil, fmt.Errorf("Unsupported field type %v", f.Type)
}

case NumericField:
argsOut = append(argsOut, f.Name, "NUMERIC")
if f.Options != nil {
opts, ok := f.Options.(NumericFieldOptions)
if !ok {
err = fmt.Errorf("Error on NumericField serialization")
return
}
if opts.Sortable {
argsOut = append(argsOut, "SORTABLE")
}
if opts.NoIndex {
argsOut = append(argsOut, "NOINDEX")
}
}
case TagField:
argsOut = append(argsOut, f.Name, "TAG")
if f.Options != nil {
opts, ok := f.Options.(TagFieldOptions)
if !ok {
err = fmt.Errorf("Error on TagField serialization")
return
}
if opts.Separator != 0 {
argsOut = append(argsOut, "SEPARATOR", fmt.Sprintf("%c", opts.Separator))
}
if opts.Sortable {
argsOut = append(argsOut, "SORTABLE")
}
if opts.NoIndex {
argsOut = append(argsOut, "NOINDEX")
}
}
case GeoField:
argsOut = append(argsOut, f.Name, "GEO")
if f.Options != nil {
opts, ok := f.Options.(GeoFieldOptions)
if !ok {
err = fmt.Errorf("Error on GeoField serialization")
return
}
if opts.NoIndex {
argsOut = append(argsOut, "NOINDEX")
}
}
default:
err = fmt.Errorf("Unrecognized field type %v serialization", f.Type )
return
}
return args, nil
return
}

0 comments on commit 8eec4dd

Please sign in to comment.