Core Architecture
Shards, nodes, clusters, and how Elasticsearch distributes data for scale, resilience, and near-real-time search.
Documents & Indices
Everything in Elasticsearch starts with a document — a JSON object that represents a single unit of data. Documents are the atomic unit of indexing and search. Unlike rows in a relational database, documents are and self-contained.
# Every document has metadata fields:
{
"_index": "products", ← which index this doc belongs to
"_id": "abc123", ← unique identifier (auto-generated or explicit)
"_version": 3, ← incremented on every update
"_source": { ← the actual JSON you indexed
"name": "Running Shoes",
"price": 129.99,
"category": "footwear",
"description": "Lightweight trail running shoes"
}
}
Key properties:
• Documents are JSON — nested objects, arrays, all valid
• Documents are immutable — you cannot modify a document in place
• Updates = delete old version + reindex new version (internally)
• _id is unique within an index (not globally)
• _source stores the original JSON (retrievable, but not searched directly)
🔑 Immutability is Fundamental
When you "update" a document, Elasticsearch internally marks the old version as deleted and indexes a completely new document. This is because Lucene segments are immutable — once written, they never change. This design enables lock-free concurrent reads and makes crash recovery straightforward.
Indices — Collections of Documents
An index is a collection of documents that share similar characteristics. It's the top-level container — analogous to a , but more flexible. Each index has its own mapping (schema), settings (shard count, analyzers), and data.
Index: "products"
├── Mapping (schema): defines field types and analyzers
├── Settings: number_of_shards=5, number_of_replicas=1
├── Aliases: "products-live" → "products-v2"
└── Documents: millions of product JSON objects
Common patterns:
• One index per entity type: products, users, orders
• Time-based indices: logs-2024-01-15, logs-2024-01-16
• Versioned indices: products-v1, products-v2 (swap via alias)
Index naming rules:
• Lowercase only
• No special characters (except hyphens and underscores)
• Cannot start with - or _
• Max 255 characters
Index Aliases — Zero-Downtime Reindexing
An alias is a pointer to one or more indices. Clients query the alias, not the index directly. This lets you swap the underlying index without any client changes — essential for zero-downtime reindexing when you need to change mappings.
# Step 1: Create new index with updated mapping
PUT /products-v2
{ "mappings": { ... }, "settings": { ... } }
# Step 2: Reindex all documents from old to new
POST /_reindex
{ "source": { "index": "products-v1" }, "dest": { "index": "products-v2" } }
# Step 3: Atomic alias swap (clients never notice)
POST /_aliases
{
"actions": [
{ "remove": { "index": "products-v1", "alias": "products" } },
{ "add": { "index": "products-v2", "alias": "products" } }
]
}
# Clients always query "products" alias — zero downtime
# Old index can be deleted after verification
When to Use Aliases
- ✅Zero-downtime reindexing when mappings change
- ✅Blue-green deployments for index upgrades
- ✅Filtering aliases — route queries to a subset of data
- ✅Time-based rollover — 'logs-current' always points to today's index
- ✅Multi-tenant isolation — each tenant alias points to their data