Reindexing into a new index leaves two: the old one still serving and the new one ready. Pointing the application at the new one by editing configuration means a deploy, and a window where the two disagree. An alias makes it one atomic call.
POST /_aliases
{
"actions": [
{ "remove": { "index": "products_v3", "alias": "products" } },
{ "add": { "index": "products_v4", "alias": "products" } }
]
}
Both actions apply in one operation, so there is no instant where the alias points at nothing or at both. The application only ever knows the alias. Keeping the previous index around for a day makes the rollback the same call with the arguments reversed, which is the cheapest rollback in the stack. An alias can also point at several indices at once, which is how time-based data gets queried as a unit.