Skip to content

Commit

Permalink
Add FT.ALTER in OM JSON and Hash repo (#645)
Browse files Browse the repository at this point in the history
* Add FT.ALTER in OM JSON and Hash repo
Signed-off-by: Vatsal <[email protected]>

* Add FT.ALTER in OM JSON and Hash repo
Signed-off-by: Vatsal <[email protected]>

* Add FT.ALTER in OM JSON and Hash repo
Signed-off-by: Vatsal <[email protected]>

* Add FT.ALTER in OM JSON and Hash repo
Signed-off-by: Vatsal <[email protected]>

* Add FT.ALTER in OM JSON and Hash repo
Signed-off-by: Vatsal <[email protected]>
  • Loading branch information
imvtsl authored Oct 25, 2024
1 parent 25821d0 commit b743fe0
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 0 deletions.
6 changes: 6 additions & 0 deletions om/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ func (r *HashRepository[T]) Remove(ctx context.Context, id string) error {
return r.client.Do(ctx, r.client.B().Del().Key(key(r.prefix, id)).Build()).Error()
}

// AlterIndex uses FT.ALTER from the RediSearch module to alter index under the name `hashidx:{prefix}`
// You can use the cmdFn parameter to mutate the index alter command.
func (r *HashRepository[T]) AlterIndex(ctx context.Context, cmdFn func(alter FtAlterIndex) rueidis.Completed) error {
return r.client.Do(ctx, cmdFn(r.client.B().FtAlter().Index(r.idx))).Error()
}

// CreateIndex uses FT.CREATE from the RediSearch module to create inverted index under the name `hashidx:{prefix}`
// You can use the cmdFn parameter to mutate the index construction command.
func (r *HashRepository[T]) CreateIndex(ctx context.Context, cmdFn func(schema FtCreateSchema) rueidis.Completed) error {
Expand Down
58 changes: 58 additions & 0 deletions om/hash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package om
import (
"context"
"encoding/json"
"fmt"
"math/rand"
"reflect"
"strings"
Expand Down Expand Up @@ -240,6 +241,63 @@ func TestNewHashRepository(t *testing.T) {
t.Fatalf("should not be found, but got %v", e)
}
})

t.Run("Alter Index", func(t *testing.T) {
err := repo.CreateIndex(ctx, func(schema FtCreateSchema) rueidis.Completed {
return schema.FieldName("Val").Text().Build()
})
if err != nil {
t.Fatal(err)
}
time.Sleep(time.Second)
var entities []*HashTestStruct
for i := 3; i >= 1; i-- {
e := repo.NewEntity()
e.Val = []byte("any")
e.Vec32 = []float32{3, 2, 1}
e.Vec64 = []float64{1, 2, 3}
e.JSON = []byte(fmt.Sprintf("[%d]", i))
err = repo.Save(ctx, e)
if err != nil {
t.Fatal(err)
}
entities = append(entities, e)
}
time.Sleep(time.Second)
_, _, err = repo.Search(ctx, func(search FtSearchIndex) rueidis.Completed {
return search.Query("*").Sortby("JSON").Build()
})
if err == nil {
t.Fatalf("search by property not loaded nor in schema")
}
err = repo.AlterIndex(ctx, func(alter FtAlterIndex) rueidis.Completed {
return alter.
Schema().Add().Field("JSON").Options("TEXT").
Build()
})
if err != nil {
t.Fatal(err)
}
time.Sleep(time.Second)
n, records, err := repo.Search(ctx, func(search FtSearchIndex) rueidis.Completed {
return search.Query("*").Sortby("JSON").Build()
})
if err != nil {
t.Fatal(err)
}
if n != 3 {
t.Fatalf("unexpected total count %v", n)
}
if len(records) != 3 {
t.Fatalf("unexpected return count %v", n)
}
if !reflect.DeepEqual(entities[2], records[0]) {
t.Fatalf("entities[0] should be the same as records[2]")
}
if err = repo.DropIndex(ctx); err != nil {
t.Fatal(err)
}
})
})

t.Run("SaveMulti", func(t *testing.T) {
Expand Down
6 changes: 6 additions & 0 deletions om/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ func (r *JSONRepository[T]) Remove(ctx context.Context, id string) error {
return r.client.Do(ctx, r.client.B().Del().Key(key(r.prefix, id)).Build()).Error()
}

// AlterIndex uses FT.ALTER from the RediSearch module to alter index under the name `jsonidx:{prefix}`
// You can use the cmdFn parameter to mutate the index alter command.
func (r *JSONRepository[T]) AlterIndex(ctx context.Context, cmdFn func(alter FtAlterIndex) rueidis.Completed) error {
return r.client.Do(ctx, cmdFn(r.client.B().FtAlter().Index(r.idx))).Error()
}

// CreateIndex uses FT.CREATE from the RediSearch module to create inverted index under the name `jsonidx:{prefix}`
// You can use the cmdFn parameter to mutate the index construction command,
// and note that the field name should be specified with JSON path syntax, otherwise the index may not work as expected.
Expand Down
60 changes: 60 additions & 0 deletions om/json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package om

import (
"context"
"fmt"
"reflect"
"testing"
"time"
Expand Down Expand Up @@ -204,6 +205,65 @@ func TestNewJSONRepository(t *testing.T) {
t.Fatalf("should not be found, but got %v", e)
}
})

t.Run("Alter Index", func(t *testing.T) {
err := repo.CreateIndex(ctx, func(schema FtCreateSchema) rueidis.Completed {
return schema.FieldName("$.Val").Text().Build()
})
if err != nil {
t.Fatal(err)
}
time.Sleep(time.Second)
var entities []*JSONTestStruct
for i := 3; i >= 1; i-- {
e := repo.NewEntity()
e.Val = []byte("any")
e.Nested = struct {
F1 string
}{
F1: fmt.Sprintf("%d", i),
}
err = repo.Save(ctx, e)
if err != nil {
t.Fatal(err)
}
entities = append(entities, e)
}
time.Sleep(time.Second)
n, records, err := repo.Search(ctx, func(search FtSearchIndex) rueidis.Completed {
return search.Query("*").Sortby("$.Nested.F1").Build()
})
if err == nil {
t.Fatalf("search by property not loaded nor in schema")
}
err = repo.AlterIndex(ctx, func(alter FtAlterIndex) rueidis.Completed {
return alter.
Schema().Add().Field("$.Nested.F1").Options("TEXT").
Build()
})
if err != nil {
t.Fatal(err)
}
time.Sleep(time.Second)
n, records, err = repo.Search(ctx, func(search FtSearchIndex) rueidis.Completed {
return search.Query("*").Sortby("$.Nested.F1").Build()
})
if err != nil {
t.Fatal(err)
}
if n != 3 {
t.Fatalf("unexpected total count %v", n)
}
if len(records) != 3 {
t.Fatalf("unexpected return count %v", n)
}
if !reflect.DeepEqual(entities[2], records[0]) {
t.Fatalf("entities[0] should be the same as records[2]")
}
if err = repo.DropIndex(ctx); err != nil {
t.Fatal(err)
}
})
})

t.Run("SaveMulti", func(t *testing.T) {
Expand Down
3 changes: 3 additions & 0 deletions om/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ type (
FtSearchIndex = cmds.FtSearchIndex
// FtAggregateIndex is the FT.AGGREGATE command builder
FtAggregateIndex = cmds.FtAggregateIndex
// FtAlterSchema is the FT.ALTERINDEX command builder
FtAlterIndex = cmds.FtAlterIndex
// Arbitrary is alias to cmds.Arbitrary. This allows user build arbitrary command in Repository.CreateIndex
Arbitrary = cmds.Arbitrary
)
Expand Down Expand Up @@ -43,6 +45,7 @@ type Repository[T any] interface {
SaveMulti(ctx context.Context, entity ...*T) (errs []error)
Remove(ctx context.Context, id string) error
CreateIndex(ctx context.Context, cmdFn func(schema FtCreateSchema) rueidis.Completed) error
AlterIndex(ctx context.Context, cmdFn func(alter FtAlterIndex) rueidis.Completed) error
DropIndex(ctx context.Context) error
IndexName() string
}
Expand Down

0 comments on commit b743fe0

Please sign in to comment.