How can I identify schema changes for a given index?

Last updated 12, Apr 2024

Question

Is it possible to identify schema changes for an index defined with FT.CREATE?

Answer

Redis does not support index versioning. Because of that, it is impossible to identify the latest changes or consult the history of changes made to a schema. However, the command FT.ALTER can add new attributes to an index. Tracking changes to Redis indexes using the alias functionality is also possible. With Redis, you can create an alias and instruct the application to use it. Creating new indexes with the desired changes can be done anytime: by pointing the alias to the latest index, the application will immediately use it transparently. Let's consider the following example. We store some data:

HSET item:1 name "book" price 9.99
HSET item:2 name "computer" price 399.99
HSET item:3 name "phone" price 199.99

Then, we define an index:

FT.CREATE item_first_idx PREFIX 1 item: SCHEMA name TAG

And associate it with the alias:

FT.ALIASADD item_idx item_first_idx

Now we can search if there is a book using the alias:

FT.SEARCH item_idx @name:{book} RETURN 1 price
1) (integer) 1
2) "item:1"
3) 1) "price"
   2) "9.99

Now, provided the index was only created on the name field, searches by price won't work.

FT.SEARCH item_idx '@price:[100 200]' RETURN 1 name
1) (integer) 0

Let's then introduce a new field in a second version of the index:

FT.CREATE item_second_idx PREFIX 1 item: SCHEMA name TAG price NUMERIC SORTABLE

And point the alias to the new index using the command FT.ALIASUPDATE:

FT.ALIASUPDATE item_idx item_second_idx

The search will work as expected:

FT.SEARCH item_idx '@price:[100 200]' RETURN 1 name
1) (integer) 1
2) "item:3"
3) 1) "name"
   2) "phone"

At this point, we have two indexes, but one is currently referenced by the alias. It is possible to compare the two indexes using FT.INFO and identify the changes in the schema. Remember that to recover the memory used by the older versions of the index, you should delete them using the command FT.DROPINDEX: it will drop the index but keep the documents in the database.

FT.DROPINDEX item_first_idx