Command Palette

Search for a command to run...

Level 1 · 20 min

Mapping

Mapping defines the schema of your Elasticsearch index — how fields are stored, indexed, and searched. Getting mapping right from the start prevents costly reindexing and avoids mapping explosion in production.

Dynamic vs Explicit Mapping

Dynamic mapping auto-detects field types when new documents are indexed. While convenient for development, it is risky in production: a single document with an unexpected field shape can change the mapping for the entire index. For example, a field first seen as a number will be mapped as long — then a document with a string value for that field will be rejected. Explicit mapping (defined before indexing) prevents this by rejecting unknown fields or ignoring them (dynamic: strict or dynamic: false). Best practice: always define explicit mappings for production indices.

Field Types: text vs keyword

text fields are analyzed: the value is passed through an analyzer (tokenization, lowercasing, stemming) and stored as a list of tokens. This enables full-text search but prevents exact-match filtering and aggregations. keyword fields are not analyzed: the value is stored as-is, enabling exact-match filtering, sorting, and aggregations. A product name that needs both free-text search and faceted filtering must use a multi-field: name mapped as text for search and name.keyword mapped as keyword for aggregation. Gormley and Tong explain the inverted index mechanism: "By default, every field in a document is indexed (has an inverted index) and thus is searchable. A field without an inverted index is not searchable." — Clinton Gormley & Zachary Tong, Elasticsearch: The Definitive Guide. Dynamic mapping applies automatic type inference rules: a JSON whole number maps to long, a floating point to double, a valid date string to date, and any other string to text. Critically, if a number arrives as a quoted string ("123"), it maps as text, not long — a silent schema corruption that breaks range queries. doc_values are an on-disk columnar structure (enabled by default for all non-text fields) that allow efficient sorting and aggregations without loading field data into heap memory. Disabling doc_values on a field saves disk space but permanently removes sorting and aggregation capability for that field — a trade-off that must be made at index creation time and requires reindexing to undo.

Multi-fields and Index Templates

Multi-fields allow a single field to be indexed in multiple ways simultaneously. The mapping specifies a fields sub-object: name: type text, fields: keyword: type keyword. Index templates (composable templates in ES 7.8+) apply a mapping to all indices matching a pattern (e.g., logs-*). They separate concerns: component templates hold reusable mapping fragments, index templates compose them. This ensures every new index in a data stream inherits the correct mapping without manual intervention.

Key Takeaways

  • Dynamic mapping is risky in production — one unexpected document can corrupt the mapping for all future documents. Always use explicit mappings.
  • text is for full-text search (analyzed, tokenized). keyword is for exact matching, sorting, and aggregations (not analyzed). Most fields need both via multi-fields.
  • Index templates enforce mapping at index creation time. Use component templates to share mapping fragments across multiple index templates.

Code example

PUT /products\n{\n  "mappings": {\n    "dynamic": "strict",\n    "properties": {\n      "name": {\n        "type": "text",\n        "fields": {\n          "keyword": {"type": "keyword"}\n        }\n      },\n      "price": {"type": "float"},\n      "tags": {"type": "keyword"},\n      "description": {"type": "text"}\n    }\n  }\n}