SproutStackSproutStack home
IntermediateSearch (Elasticsearch)

Changing a field type without downtime

A price field was mapped as text. Sorting and ranges need it as a number.

The setup today

The products index has 30 million documents. Its price field was dynamically mapped from strings like "19.99", so it became text. The app queries the index by its real name.

Current configuration

index: products   (30M docs, 5 primary shards, 1 replica)
mapping: price -> text (+ price.keyword)
app queries: GET products/_search

What you know

  • Sorting by price is alphabetical: "100.00" sorts before "20.00".
  • Range filters like price < 50 do not work.

The new requirement

Product needs correct price sorting and range filters, with no search downtime during the change.

Make the call

2 questions · first-try answers earn the most XP

1. How do you change price to a numeric type?
2. How do you switch the app to the new index with no downtime?
What a strong answer also covers
  • Writes keep arriving during the reindex: dual-write, or replay changes from the source after the copy.
  • For a faster bulk load, set replicas to 0 and refresh_interval to -1 on the new index, then restore them.
  • Keep the old index for a while after the switch, so rolling back is one alias change.
  • Version index names (products_v2) so it is always clear which one is live.
Variations to think through

Change one fact and decide again. There is no single right answer here.

  • Writes cannot be paused, and the reindex takes three hours. How do you avoid losing updates made meanwhile?
  • The new index also needs a different number of primary shards. Does that change the plan?
  • Two different apps write to the index. How do you coordinate the switch?

The background

More drills