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

Dynamic Templates by Path/Name/Type for Stable Mapping Contracts

Use ordered dynamic-template rules to map fields by detected type, field name, and dotted path while keeping flexible AtlasMart metadata inside a governed search contract.

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

Learning outcomes

AtlasMart must accept a bounded set of merchant extensions without letting every merchant invent a new global schema. Dynamic templates provide conditional mapping rules, but they are code: order, match scope and output type determine the permanent mapping created when the first concrete value arrives.

01

Design dynamic-template rules using match_mapping_type, match/unmatch and path_match/path_unmatch.

02

Explain first-match ordering and why a broad rule placed too early can shadow a precise rule.

03

Keep product-owned fields explicit while exposing a constrained merchant extension namespace.

04

Validate template behavior by indexing boundary fixtures and inspecting mapping/field capabilities.

05

Recognize where Elasticsearch and OpenSearch dynamic-template features diverge and keep the portable core narrow.

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. Both products support the core dynamic-template matching family used in the mandatory lab. Elasticsearch also documents runtime-field dynamic-template options; OpenSearch has different dynamic-mode extensions. Treat product-specific output mappings as separate artifacts when portability matters.

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. A dynamic template is an ordered conditional mapping rule

Selector Question it answers AtlasMart use
match_mapping_type What JSON/detected type did the parser see? Only boolean merchant flags receive boolean mapping.
match / unmatch What is the leaf field name? Fields ending in _label become keyword.
path_match / path_unmatch What is the full dotted field path? Only merchant.codes.* becomes keyword.
match_pattern Should name/path patterns use simple wildcard or regex semantics? Use the simplest pattern sufficient for the contract.
mapping What permanent mapping is created when this rule wins? keyword/text/boolean/etc with explicit options.

Template arrays are ordered. Design from most specific to most general and test overlaps deliberately. A broad string rule that appears first can capture a field intended for a later merchant-code rule.

2. Build a constrained AtlasMart extension surface

Dev Tools · portable dynamic-template index
DELETE atlasmart-products-dynamic-v1
PUT atlasmart-products-dynamic-v1
{
  "settings": {"number_of_shards":1,"number_of_replicas":0},
  "mappings": {
    "dynamic": true,
    "dynamic_templates": [
      {
        "merchant_flags": {
          "path_match": "merchant.flags.*",
          "match_mapping_type": "boolean",
          "mapping": {"type":"boolean"}
        }
      },
      {
        "merchant_codes": {
          "path_match": "merchant.codes.*",
          "match_mapping_type": "string",
          "mapping": {"type":"keyword","ignore_above":128}
        }
      },
      {
        "labels_by_name": {
          "match": "*_label",
          "match_mapping_type": "string",
          "mapping": {"type":"keyword","ignore_above":128}
        }
      },
      {
        "other_strings": {
          "match_mapping_type": "string",
          "mapping": {
            "type":"text",
            "fields":{"keyword":{"type":"keyword","ignore_above":256}}
          }
        }
      }
    ],
    "properties": {
      "product_id":{"type":"keyword"},
      "price":{"type":"scaled_float","scaling_factor":100}
    }
  }
}
Dev Tools · boundary documents
PUT atlasmart-products-dynamic-v1/_doc/P-9101?refresh=true
{
  "product_id":"P-9101",
  "price":129.95,
  "campaign_label":"autumn",
  "merchant": {
    "flags":{"fragile":true},
    "codes":{"warehouse":"THR-07"}
  },
  "description":"Wireless headset"
}

GET atlasmart-products-dynamic-v1/_mapping
GET atlasmart-products-dynamic-v1/_field_caps?fields=campaign_label,merchant.flags.*,merchant.codes.*,description*

The acceptance test is type-level evidence: campaign_label is aggregatable as keyword; merchant.codes.warehouse is keyword; merchant.flags.fragile is boolean; and description follows the fallback text-plus-keyword contract. Do not accept “indexing returned 201” as sufficient proof.

3. Demonstrate the ordering bug

Wrong rule order · conceptual diff
WRONG order:
1. any string -> text + keyword
2. merchant.codes.* string -> keyword

The first matching rule wins, so merchant.codes.warehouse becomes text+keyword.

CORRECT order:
1. merchant.codes.* string -> keyword
2. narrow name/path rules
3. general string fallback

A rule can be syntactically valid yet semantically wrong. Store the expected resolved mapping as a regression fixture, not merely the template JSON. This catches accidental reordering during refactors.

Failure mode

If a field has already been created with the wrong type, fixing the dynamic template does not rewrite the existing field. The corrected rule applies when a new field/index is created. An incompatible existing mapping still needs a new index and reindex/cutover.

4. Path governance beats global merchant keys

Allowing merchant_123_color, merchant_124_color, and thousands of peer fields creates global mapping growth. Prefer a stable extension object path and a bounded vocabulary where search semantics need first-class fields. If arbitrary key/value storage is required, consider a flattened-like representation supported by the target product and accept its query/typing limits rather than pretending every arbitrary key deserves a dedicated mapped field.

Requirement Preferred representation Reason
Facet/filter on a known attribute Explicit keyword/numeric/date field Strong type, doc values and predictable query semantics.
Small family of extension fields Dynamic template under bounded path Flexible but governed.
Thousands of arbitrary metadata keys Flattened-like/key-value strategy where supported Avoid one mapping field per key; accept reduced typing semantics.
Security/tenant identity Explicit field only Never allow arbitrary dynamic mutation of authorization boundaries.

5. Product-specific policy branch

OpenSearch-only concept · verify before use
# OpenSearch 3.8-specific governance option:
"dynamic": "strict_allow_templates"

# Meaning: an unknown field must match an approved dynamic template
# or the document is rejected.

# Do NOT copy this value into Elasticsearch 9.5.3.

For a cross-product course baseline, keep the mandatory template syntax portable and enforce the same policy through application validation and explicit mappings. If you choose OpenSearch-specific allow-template modes, version the deployment artifact by product.

6. Deterministic template tests

Test matrix · expected mapping contract
case: merchant boolean flag
input:  merchant.flags.fragile = true
expect: type boolean

case: merchant code
input:  merchant.codes.warehouse = "THR-07"
expect: type keyword, not analyzed text

case: leaf name suffix
input:  campaign_label = "autumn"
expect: type keyword

case: ordinary prose
input:  description = "Wireless headset"
expect: text + keyword multi-field

case: incompatible later value
input:  merchant.flags.fragile = "sometimes"
expect: rejection or producer-contract failure; never silent remapping

Check your understanding

  1. Why place specific path rules before the generic string rule?
  2. What does fixing a template do to an already-created wrong field?
  3. Why keep tenant/security fields out of a generic extension namespace?
  4. What should a dynamic-template test assert besides indexing success?
  5. Which OpenSearch dynamic governance mode is not portable to Elasticsearch?
Review the answers

1. Dynamic templates are ordered; an earlier broad match can shadow the intended specific rule.

2. Nothing retroactive. Existing mappings remain; create a new index/reindex if the change is incompatible.

3. Authorization-critical semantics must be explicit, stable, reviewed and not controlled by arbitrary payload keys.

4. The resolved mapping/field capabilities and query/aggregation behavior expected from the chosen type.

5. The allow-templates dynamic modes such as strict_allow_templates/false_allow_templates.

Production judgment

Dynamic templates should reduce repetitive schema declarations without outsourcing schema ownership to incoming data. Version template order, review path patterns for accidental breadth, cap extension-field growth, and monitor the rate at which new mappings appear. If a rule changes search semantics, treat it as a schema migration even when the JSON diff looks small.

Summary and next step

You can now express controlled flexibility with ordered type/name/path rules. The next lesson turns those mappings and settings into reusable component templates and a composable index template whose final resolution is simulated before any index is created.

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.