Reindexing behind an alias, and a switch nobody noticed

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.