Chapter 09 · Dynamic Templates, Index Templates, Component Templates, and Schema Evolution

Dynamic Field Detection, Coercion, Date / Numeric Detection, and Failure Modes from Uncontrolled Input

Observe exactly how new JSON fields become mappings, when coercion or date/numeric detection changes the contract, and why uncontrolled payloads can create irreversible schema mistakes.

Intermediate100–120 minutesSchema evolution labElasticsearch 9.5.3 · OpenSearch 3.8.0Last reviewed: September 2026

Learning outcomes

AtlasMart receives product events from catalog, marketplace and merchant systems. One feed sends "price":"19.99", another sends 19.99; an optional merchant field called launch_date sometimes looks like a date and sometimes like an arbitrary label. If the first payload silently decides the mapping, later documents can be rejected or—worse—accepted under a search contract nobody intentionally designed. This lesson makes those decisions observable.

01

Predict how a previously unseen JSON value is dynamically mapped and distinguish detection from coercion.

02

Explain why date detection and numeric detection are convenience heuristics rather than production schema ownership.

03

Use dynamic true/false/strict controls and identify the OpenSearch-specific allow-templates modes versus Elasticsearch runtime mode.

04

Reproduce a mapping conflict and field-growth failure safely, then repair the contract rather than hiding the symptom.

05

Decide which AtlasMart fields may evolve dynamically and which must be explicit before ingestion.

Chapter baseline reviewed 11 September 2026

The reproducible examples target self-managed Elasticsearch 9.5.3 and OpenSearch 3.8.0 using the existing AtlasMart local-course conventions: Elasticsearch on https://localhost:9200 with its copied CA certificate, OpenSearch on https://localhost:9201 with the disposable demo certificate explicitly treated as local-only, and no moving latest tags. Template and mapping syntax is verified against current official documentation. A material product difference matters here: Elasticsearch 9.5 supports dynamic: true|false|strict|runtime; OpenSearch 3.8 additionally documents false_allow_templates and strict_allow_templates. Do not ship one value to both products without a compatibility branch.

Execution and safety note

The generation environment does not run the two search servers, so commands are specified as deterministic labs and expected invariants rather than represented as captured live output. Run them only against the disposable AtlasMart course indices/templates, record the actual API responses from your pinned versions, and never test alias cutover or destructive cleanup against production names.

1. Dynamic mapping is executable schema creation

Mapping is the index-time contract that tells the engine how each field is parsed, indexed, stored for sorting/aggregation, and queried. With dynamic mapping enabled, the first concrete value for a new field can create that contract. A null value or empty array may create no mapping at all, so “we sent the field” does not prove “the field now has a type.”

Input shape Typical dynamic consequence Governance risk
JSON integer long A later decimal may conflict with the first inferred type or lose intended precision policy.
JSON floating point float in default dynamic mapping Precision may be inappropriate for money; AtlasMart uses scaled_float explicitly.
true/false boolean String variants can behave differently and should not define the contract accidentally.
String matching a detected date format date when date detection is enabled An identifier such as 2026-09 can be misclassified as time.
Ordinary string text plus keyword-style multi-field in common defaults Field may become searchable/aggregatable even when it should be constrained or ignored.
Object object A later scalar for the same path is a hard mapping conflict.
Mechanism

Detection decides a field type when no mapping exists. Coercion decides whether a value can be converted to an already-mapped field type. Those are different stages and different failure modes.

2. Reproduce first-document ownership, then inspect the evidence

Dev Tools · disposable detection index
DELETE atlasmart-schema-detect-v1
PUT atlasmart-schema-detect-v1
{
  "settings": {"number_of_shards":1,"number_of_replicas":0},
  "mappings": {
    "date_detection": true,
    "numeric_detection": false
  }
}

PUT atlasmart-schema-detect-v1/_doc/first?refresh=true
{
  "merchant_code": "10001",
  "launch_hint": "2026-09-11",
  "price_guess": 19.99,
  "promo": {"code":"FALL"}
}

GET atlasmart-schema-detect-v1/_mapping
GET atlasmart-schema-detect-v1/_field_caps?fields=*

The mapping/field-capabilities responses are the evidence. Do not infer the final type from the original JSON alone. Verify whether launch_hint became a date, whether merchant_code stayed a string-derived field, and how price_guess was inferred on your exact server version.

3. Coercion can make bad producers look healthy

Dev Tools · explicit field with coercion
DELETE atlasmart-schema-coerce-v1
PUT atlasmart-schema-coerce-v1
{
  "mappings": {
    "properties": {
      "stock": {"type":"integer", "coerce":true},
      "product_id": {"type":"keyword"}
    }
  }
}

PUT atlasmart-schema-coerce-v1/_doc/1?refresh=true
{"product_id":"P-9001", "stock":"12"}

GET atlasmart-schema-coerce-v1/_doc/1

If the write succeeds, it proves only that the mapped field accepted the value under current coercion semantics. It does not prove the producer emitted the agreed JSON type. For critical contracts, validate at the producer/API boundary and keep coercion policy explicit. Do not use coercion to compensate indefinitely for upstream schema drift.

Boundary case

Integer coercion may also accept values that are surprising for business semantics. Test the actual boundary values your API permits; the search engine should not be the first validator for money, inventory, tenant identity, or authorization fields.

4. Controlled failures: conflict and field explosion

Dev Tools · provoke an object/scalar conflict
PUT atlasmart-schema-detect-v1/_doc/conflict
{
  "promo": "FALL"
}

The existing promo path was created as an object, so indexing a scalar at the same path should be rejected. Capture the HTTP status and root cause. Repair the producer or route the incompatible payload to a versioned destination; do not try to “change the field type in place.”

Generate only in a disposable index · field-growth thought experiment
# Pseudocode: do not point this at a shared cluster.
for i in range(1, 501):
    document[f"merchant_attribute_{i}"] = "x"

# Observe _mapping growth and index.mapping.total_fields.limit.
# The lesson is the growth curve, not how high you can push the limit.

Unbounded merchant-defined keys multiply mapping metadata, per-segment field structures and cluster-state work. Increasing a field-count limit is not a schema strategy. Prefer an allowlisted explicit schema, a governed dynamic-template family, or a flattened-like representation where the product supports it and query semantics fit.

5. Product-specific dynamic controls are governance tools

Intent Elasticsearch 9.5.3 OpenSearch 3.8.0
Accept and map unknown fields dynamic: true dynamic: true
Keep unknown fields in _source but do not map them dynamic: false dynamic: false
Reject unknown fields dynamic: strict dynamic: strict
Create unknown fields as runtime fields dynamic: runtime Do not assume the Elastic mode exists; verify supported alternatives.
Allow only unknown fields that match dynamic templates No equivalent dynamic value; design templates plus explicit governance false_allow_templates / strict_allow_templates are OpenSearch-specific controls

The names are not cosmetic. They change whether ingestion succeeds, whether a new field is searchable, and whether the mapping changes. Make the selected mode part of the schema artifact and integration tests.

6. AtlasMart decision: explicit core, controlled extension surface

For products, AtlasMart owns product_id, name, category, price, available, and updated_at explicitly. Merchant extensions are accepted only under a documented path with bounded naming/type rules introduced in the next lesson. This prevents arbitrary request bodies from mutating the search contract.

Check your understanding

  1. What is the difference between detection and coercion?
  2. Why is numeric_detection a poor substitute for an explicit money mapping?
  3. What should happen when an object path later receives a scalar?
  4. Why not simply raise total_fields.limit during field explosion?
  5. Which dynamic modes are product-specific?
Review the answers

1. Detection chooses a mapping for an unmapped field; coercion converts an incoming value to an already-declared field type when allowed.

2. It infers from string shape and cannot encode the business precision/scaling contract required for currency.

3. Treat it as a schema conflict: reject/quarantine/fix the producer or migrate to a new version; do not mutate the existing field type.

4. It moves the failure boundary while preserving uncontrolled mapping growth and resource/cluster-state cost.

5. Elasticsearch documents runtime mode; OpenSearch documents allow-templates variants. Compatibility requires an explicit branch.

Production judgment

Schema governance starts before the write reaches the cluster. Track rejected-document rate, new-field rate, mapping size, indexing p95/p99, and producer/version identity. A tolerant mapping can improve availability but can also turn upstream defects into expensive permanent index structures. Backups/snapshots protect bytes; they do not make an accidental mapping compatible with a future contract.

Summary and next step

Dynamic mapping is automated schema mutation. You can now distinguish detection, coercion, date/numeric heuristics and product-specific dynamic modes. Next, we replace arbitrary flexibility with ordered dynamic templates that match by type, field name and path.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only Ethereum or ERC-20 compatible assets to this address.