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.
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}