An alias in front of every index, from the first day

A mapping change usually cannot be applied in place, so it means building a new index — and if the application names the index directly, that is a coordinated deploy in the middle of a reindex.

POST /_aliases
{ "actions": [{ "add": { "index": "orders-v1", "alias": "orders" }}]}

PUT  /orders-v2 { "mappings": { ... } }
POST /_reindex { "source": {"index":"orders-v1"}, "dest": {"index":"orders-v2"} }

POST /_aliases
{ "actions": [
  { "remove": { "index": "orders-v1", "alias": "orders" }},
  { "add":    { "index": "orders-v2", "alias": "orders" }}
]}

Both actions in one request is what makes the swap atomic; two requests leave a window where queries fail. Writes arriving during the reindex are the part that needs thought — either dual-write for the duration or reindex again from a timestamp afterwards. Starting every index behind an alias costs nothing on day one and is the decision that makes all of this possible later.