Changing an analyser means reindexing, and reindexing in place means a search index that is half old and half new for twenty minutes.
# build the new index alongside
PUT /products-2023-02
POST /_reindex { "source": {"index":"products-2023-01"},
"dest": {"index":"products-2023-02"} }
# and the switch, which is atomic
POST /_aliases
{ "actions": [
{ "remove": { "index": "products-2023-01", "alias": "products" }},
{ "add": { "index": "products-2023-02", "alias": "products" }}
]}
The application must only ever address the alias, which is the discipline that makes this possible and is easy to violate once — a single hard-coded index name in a health check kept us on the old index for a week without anybody noticing. Keeping the previous index for a few days makes rollback another atomic alias swap, and costs disk that is worth it.