# Dynamic Mapping Pitfalls and Explicit Mappings — Elasticsearch

Source: https://www.skillbyai.com/en/elasticsearch/m-dynamic

> Do not let the first document decide.

## Guesses become permanent

With **dynamic mapping**, Elasticsearch infers a type the first time it sees a field: JSON strings become `text` with a `.keyword` sub-field (unless they look like dates, which are detected by default), whole numbers become `long` and decimals `float`. Problems follow: a zip code becomes a number, an id stored as `"123"` gets an unnecessary analysed field, and free-form keys (user-supplied maps) cause a **mapping explosion** of thousands of fields (guarded by `index.mapping.total_fields.limit`, default 1000). You can **add** new fields to an existing mapping, but you cannot change the type of an existing field; that requires a new index and a reindex. Prefer explicit mappings, set `dynamic` to `strict` (reject unknown fields) or `false` (store but do not index them), and use **dynamic templates** or index templates for predictable defaults.

## Strict mapping and a dynamic template

Kibana Dev Tools console syntax; send the same requests with curl or a client library.

```http
PUT /customers
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "id":    { "type": "keyword" },
      "email": { "type": "keyword" },
      "zip":   { "type": "keyword" },
      "name":  { "type": "text" },
      "attributes": {
        "type": "object",
        "dynamic": true
      }
    },
    "dynamic_templates": [
      {
        "attr_strings_as_keywords": {
          "path_match": "attributes.*",
          "match_mapping_type": "string",
          "mapping": { "type": "keyword" }
        }
      }
    ]
  }
}

# inspect what is actually mapped
GET /customers/_mapping
```

## Review the mapping before production

Index a few realistic documents into a test index, read GET _mapping and fix anything that was guessed. It is far cheaper than a reindex of a large production index later.

**Quiz:** You need to change an existing field from text to keyword. What is required?

- [ ] Clear the cache
- [ ] Send PUT _mapping with the new type
- [ ] Restart the cluster
- [x] Create a new index with the new mapping and reindex the data

*Answer:* Create a new index with the new mapping and reindex the data. Existing field types cannot be changed in place.
