Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FT.ALTER in OM JSON and Hash repo #645

Merged
merged 5 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading