FluxaORM: A Golang ORM for MySQL and Redis
Guide
Plugins
GitHub
Guide
Plugins
GitHub
    • Introduction
    • Registry
    • Data pools
    • Entities
    • Entity fields
    • MySQL Indexes
    • Engine
    • ORM
    • Entity Schema
    • Schema Update
    • CRUD
    • Async flush
    • Searching for Entities
    • Redis Search Engine
    • MySQL Queries
    • Local Cache
    • Redis Operations
    • Distributed Lock
    • Queries Log
    • Plugins
    • Log tables

Redis Search Engine

In the previous section, you learned how to search for entities using MySQL queries. However, there is one major drawback when searching for data using a relational database such as MySQL — performance in high-traffic applications. Fortunately, there is an option to use the Redis Search engine, which provides much better performance than MySQL.

Defining Redis Search Fields

By default, an entity is not indexed in the Redis Search index. You must add a special tag redis_search to a specific entity field to instruct FluxaORM to create a Redis hash index for that entity, keeping data from the tagged fields. You can add this tag to more than one field. An entity is considered searchable via the Redis Search engine when at least one of its fields has the redis_search tag.

Example — entity with two fields indexed in Redis Search:

type PersonEntity struct {
	ID            uint64     `orm:"localCache;redisCache"`
	Age           uint8      `orm:"redis_search"`
	Name          string     `orm:"redis_search"`
}

Sortable Fields

By default, fields are not sortable. You can make a field sortable by adding the rs_sortable tag:

type PersonEntity struct {
	ID            uint64     `orm:"localCache;redisCache"`
	Age           uint8      `orm:"redis_search;rs_sortable"`
}

Defining a Redis Pool for the Search Index

If not specified, all entity Redis Search indexes are created in the fluxaorm.DefaultPoolCode Redis pool. This pool must be configured to use Redis DB number 0. Otherwise, FluxaORM will panic when validating the Registry.

You can define a different Redis pool using the redis_search_pool tag on the ID field:

type PersonEntity struct {
	ID            uint64     `orm:"localCache;redisCache;redis_search_pool=my_pool"`
	Age           uint8      `orm:"redis_search;rs_sortable"`
}

Entity Field Mapping

The table below shows how entity field types are mapped to Redis Search index field types:

goRedis Search IndexComments
int..., uint..., float...NUMERIC
*int..., *uint..., *float...NUMERICnil is stored as 0
string, *stringTEXTnil is stored as NULL
bool, *boolTAG0, 1, NULL
time.Time, *time.TimeNUMERICstored as unix timestamp, nil as 0
fluxaome.ReferenceNUMERICnil as 0
fluxaome.ENUM, []fluxaome.ENUMTAGnil as NULL

Forcing Type TAG

You can force a field to be stored in Redis as a TAG by adding the rs_tag tag:

type PersonEntity struct {
	ID            uint64     `orm:"localCache;redisCache;redis_search_pool=my_pool"`
	Age           uint8      `orm:"redis_search;rs_tag"`
}

NOSTEM

You can define the NOSTEM index option with the rs_no-stem tag:

type PersonEntity struct {
	ID            uint64     `orm:"localCache;redisCache;redis_search_pool=my_pool"`
	Name          string      `orm:"redis_search;rs_no-steam"`
}

Running Index Alter

If at least one of your entities uses Redis Search, you must run fluxabee.GetRedisSearchAlters() when your application starts:

redisSearchAlters := fluxabee.GetRedisSearchAlters(orm)
for _, alter := range redisSearchAlters {
    alter.Exec(ctx)
}

Warning

If alter.Exec(ctx) modifies the current index (e.g., adds a new field), the previous index is dropped and a new one is created. The new index is then filled with entity data from MySQL. If the entity table contains many rows (hundreds of thousands or more), this operation can take some time.

Reindexing an Entity Index

FluxaORM automatically updates the index when you add, update, or delete an entity. However, if your Redis index data was manually removed or MySQL data was manually updated and you need to refresh Redis, you can use the entity schema ReindexRedisIndex() method:

schema := GetEntitySchema[UserEntity](orm)
schema.ReindexRedisIndex(ctx)

This operation can take some time (depending on how many entities are stored in MySQL). You can monitor progress using the FTInfo() Redis command:

schema := GetEntitySchema[UserEntity](orm)
r := ctx.Engine().Redis(schema.GetRedisSearchPoolCode())
info, _ := r.FTInfo(orm, schema.GetRedisSearchIndexName())
fmt.Printf("Indexed: %d", info.PercentIndexed)

Searching for Entities

The RedisSearch() function searches for entities using a Redis Search query condition.

Example:

options = &fluxaorm.RedisSearchOptions{}
options.Pager = fluxaorm.NewPager(1, 100)
options.AddSortBy("Age", false) // sort by Age ASC
options.AddFilter("Owner", 1, 1) // Owner = 1
options.AddSortBy("Age", 18, nil) // Age >= 18
iterator, total := fluxaorm.RedisSearch[UserEntity](orm, "@Status:{active}", options)
for iterator.Next() {
    user := iterator.Entity()
}

The Pager object is optional — if nil, FluxaORM searches all rows.

If you only need entity primary keys, use RedisSearchIDs():

options = &fluxaorm.RedisSearchOptions{}
options.Pager = fluxaorm.NewPager(1, 100)
ids, total := fluxaorm.RedisSearchIDs[UserEntity](orm, "*", options)

Searching for a Single Entity

Use RedisSearchOne() to retrieve a single entity:

user, found := fluxaorm.RedisSearchOne[UserEntity](orm, "@Email:{test@example.com}", nil)

Tips

This function always adds LIMIT 1 to the query. If more than one row matches, only the first will be returned.

Edit this page
Last Updated: 8/10/25, 7:30 PM
Prev
Searching for Entities
Next
MySQL Queries