ELK Stack — Elasticsearch Fundamentals Exercises

3 minute read

Practice Exercises — Elasticsearch Fundamentals

Test your understanding of indices, documents, mappings, shards, and the REST API.


Exercise 1 — Create an Index with Mapping

Question: Create an index called server-metrics with the following fields: hostname (keyword), cpu_percent (float), memory_used_mb (integer), disk_free_gb (float), timestamp (date), status (keyword). Use 1 shard and 0 replicas.

Show Solution
$ curl -X PUT -u elastic:changeme123 \
  "http://localhost:9200/server-metrics" \
  -H "Content-Type: application/json" \
  -d '{
    "mappings": {
      "properties": {
        "hostname": { "type": "keyword" },
        "cpu_percent": { "type": "float" },
        "memory_used_mb": { "type": "integer" },
        "disk_free_gb": { "type": "float" },
        "timestamp": { "type": "date" },
        "status": { "type": "keyword" }
      }
    },
    "settings": {
      "number_of_shards": 1,
      "number_of_replicas": 0
    }
  }'

Verify:

$ curl -u elastic:changeme123 "http://localhost:9200/server-metrics/_mapping?pretty"

Exercise 2 — Bulk Index and Query

Question: Using the _bulk API, index 5 server metric documents into server-metrics. Include at least one server with cpu_percent > 90 and one with status: "critical". Then write a query to find all critical servers.

Show Solution

Bulk index:

$ curl -X POST -u elastic:changeme123 \
  "http://localhost:9200/server-metrics/_bulk" \
  -H "Content-Type: application/x-ndjson" \
  -d '
{"index": {"_id": "1"}}
{"hostname": "web-01", "cpu_percent": 45.2, "memory_used_mb": 3200, "disk_free_gb": 120.5, "timestamp": "2025-03-15T10:00:00Z", "status": "healthy"}
{"index": {"_id": "2"}}
{"hostname": "web-02", "cpu_percent": 92.8, "memory_used_mb": 7500, "disk_free_gb": 15.2, "timestamp": "2025-03-15T10:00:00Z", "status": "critical"}
{"index": {"_id": "3"}}
{"hostname": "db-01", "cpu_percent": 65.0, "memory_used_mb": 12000, "disk_free_gb": 200.0, "timestamp": "2025-03-15T10:00:00Z", "status": "warning"}
{"index": {"_id": "4"}}
{"hostname": "api-01", "cpu_percent": 95.5, "memory_used_mb": 3800, "disk_free_gb": 50.0, "timestamp": "2025-03-15T10:00:00Z", "status": "critical"}
{"index": {"_id": "5"}}
{"hostname": "cache-01", "cpu_percent": 22.1, "memory_used_mb": 1500, "disk_free_gb": 500.0, "timestamp": "2025-03-15T10:00:00Z", "status": "healthy"}
'

Query critical servers:

$ curl -X POST -u elastic:changeme123 \
  "http://localhost:9200/server-metrics/_search?pretty" \
  -H "Content-Type: application/json" \
  -d '{
    "query": {
      "term": { "status": "critical" }
    }
  }'

Expected: 2 results (web-02 and api-01).


Exercise 3 — Update and Versioning

Question: Update the web-02 server’s status from "critical" to "healthy" and reduce its cpu_percent to 35.0. Then verify the document version changed.

Show Solution

Partial update:

$ curl -X POST -u elastic:changeme123 \
  "http://localhost:9200/server-metrics/_update/2" \
  -H "Content-Type: application/json" \
  -d '{
    "doc": {
      "status": "healthy",
      "cpu_percent": 35.0
    }
  }'

Verify:

$ curl -u elastic:changeme123 "http://localhost:9200/server-metrics/_doc/2?pretty"

Expected: "_version": 2, "status": "healthy", "cpu_percent": 35.0.

The version changed from 1 to 2, confirming the update was applied.


Exercise 4 — Shard Inspection

Question: Check the shard allocation for the server-metrics index. Explain what each column in the output means. Then change the replica count to 1 and observe what happens on a single-node cluster.

Show Solution

View shards:

$ curl -u elastic:changeme123 "http://localhost:9200/_cat/shards/server-metrics?v"

Output:

index           shard prirep state   docs store ip         node
server-metrics  0     p      STARTED    5  15kb 172.18.0.2 es-node-1

Column meanings:

  • shard — shard number (0 = first shard)
  • prirep — p = primary, r = replica
  • state — STARTED, INITIALIZING, RELOCATING, UNASSIGNED
  • docs — number of documents in this shard
  • store — disk space used
  • ip — IP of the node hosting this shard
  • node — node name

Change replicas to 1:

$ curl -X PUT -u elastic:changeme123 \
  "http://localhost:9200/server-metrics/_settings" \
  -H "Content-Type: application/json" \
  -d '{ "index": { "number_of_replicas": 1 } }'

Check shards again:

$ curl -u elastic:changeme123 "http://localhost:9200/_cat/shards/server-metrics?v"

Output:

index           shard prirep state      docs store ip         node
server-metrics  0     p      STARTED       5  15kb 172.18.0.2 es-node-1
server-metrics  0     r      UNASSIGNED

The replica shard is UNASSIGNED because there’s only one node — Elasticsearch can’t place a replica on the same node as the primary. Cluster health changes to yellow.

Revert to 0 replicas:

$ curl -X PUT -u elastic:changeme123 \
  "http://localhost:9200/server-metrics/_settings" \
  -H "Content-Type: application/json" \
  -d '{ "index": { "number_of_replicas": 0 } }'

Exercise 5 — Cat API Challenge

Question: Using only _cat APIs, find: (a) the total number of documents across all indices, (b) the largest index by storage size, (c) the current heap usage of your Elasticsearch node.

Show Solution

(a) Total document count:

$ curl -u elastic:changeme123 "http://localhost:9200/_cat/count?v"

Or sum from indices:

$ curl -u elastic:changeme123 "http://localhost:9200/_cat/indices?h=docs.count&s=docs.count:desc"

(b) Largest index by storage:

$ curl -u elastic:changeme123 "http://localhost:9200/_cat/indices?v&s=store.size:desc&h=index,store.size,docs.count"

The first row is the largest index.

(c) Heap usage:

$ curl -u elastic:changeme123 "http://localhost:9200/_cat/nodes?v&h=name,heap.percent,heap.current,heap.max"

Output:

name       heap.percent heap.current heap.max
es-node-1           35       350mb      1gb

What’s Next?

Excellent work! You now understand:

  • ✅ Indices and documents
  • ✅ Mappings and field types
  • ✅ Shards and replicas
  • ✅ CRUD operations
  • ✅ The REST API and cat APIs

Next up: Chapter 4 — Elasticsearch Querying — where you’ll learn Query DSL, match/term queries, bool queries, and aggregations.