how to add new index to old ones
So i have these indexes on the first startup:
if err := r.Repository.CreateIndex(context.Background(), func(schema om.FtCreateSchema) rueidis.Completed {
return schema.
FieldName("$.user.owner").As("owner").Tag().
FieldName("$.user.name").As("name").Tag().
Build()
}); err != nil {
logs.Warning(err)
}
now I need to add a new index:
if err := r.Repository.CreateIndex(context.Background(), func(schema om.FtCreateSchema) rueidis.Completed {
return schema.
FieldName("$.user.owner").As("owner").Tag().
FieldName("$.user.name").As("name").Tag().
FieldName("$.user.id").As("id").Tag().
Build()
}); err != nil {
logs.Warning(err)
}
But I get an index already exists error. I need my Redis to be persistent and can't flush everything.
Hi @hamidrabedi,
You need to use FT.ALTER on your own currently, just like what CreateIndex does under the hood.
https://github.com/redis/rueidis/blob/5135acdc65c815cdce8e8b0c12c1e5aa939504bd/om/json.go#L139
We may also add an AlterIndex method to the repository interface.
Yes that would be a nice feature to have, writing raw code or removing and recreating indexes doesn't seem to be a good solution.
Hey @rueian Can I have a go at this issue?
Just to clarify few things before I begin working on the fix:
1- We want to add AlterIndex method to this repository.
2- This method would perform the same functionality as FT.ALTER.
Is this a correct understanding of the requirement?
Hey @rueian Can I have a go at this issue?
Just to clarify few things before I begin working on the fix: 1- We want to add
AlterIndexmethod to this repository. 2- This method would perform the same functionality as FT.ALTER.Is this a correct understanding of the requirement?
Sure, thanks for your interest in this.
- Add
AlterIndexto thetype Repository[T any] interfaceand implement it in bothtype JSONRepository[T any] structandtype HashRepository[T any] struct. The implementations should be similar to the existingCreateIndex. - Yes, the implementations should use the
FT.ALTERcommand byr.client.B().FtAlter(). - Come up with test cases to show that the implementations work in the
hash_test.goandjson_test.gofiles.
Thanks for the quick response. I will begin working on this.
Hi @rueian Just wanted to give an update. I created above PR and verified that it is working as expected by checking manually using redis-cli. I am working on test cases for the change. Thanks!
@imvtsl will there be automatic update if index fields were changed ? that would be nice
Hi @hamidrabedi, do you have a feeling about what an automatic update API should look like?
@rueian, suppose you have a new Redis instance and you call the create index function. If the index has not been created before, it will be created.
Obviously, most of the time there will be updates to your projects, and you might need to remove or add indexes. So instead of using CreateIndex, I want to use something like CreateOrUpdateIndex. This function checks the existing indexes in Redis and ensures that my indexes are present; if not, it adds them.
Regarding deleting an index, I have observed that many migration libraries do not handle deletion for various reasons, so users should handle deleting indexes themselves. However, we could have an option for it—like an argument in the CreateOrUpdateIndex function that, if provided by the user, would indicate that index deletion should happen as well.
This is just a basic usage that users can encounter, right now for this problem all I can do is to call flushall on initialization of my project, or handling the index Updates by connecting to the redis. I can't think of any other usecases at the moment, but I think basic auto update will do the trick for now.
This looks like it requires a set of high-level APIs, probably including our own indexes DSL.
But I am thinking of another approach, how about always creating a new index with FT.CREATE and transparently redirecting application queries to it by using FT. ALIASADD? I think that will be much easier.
Oh yeah much easier, or like dropping and recreating the index, but I think alias is better and you have lower downtime because the old index won't be affected. can delete the old index afterwards.
Is there still work to be done here? @rueian
Yes, I think we need a new smarter API for creating and aliasing a new index. The API should:
- Be similar to the existing CreatIndex.
- Optionally check if a new index is needed.
- Create a new index.
- Alias the new index.
- Drop the old index.
I guess this may require an additional state management so please let me know how would you like to approach this.
Closed by https://github.com/redis/rueidis/pull/813