Creating an index sets the foundation for reliable search by defining how documents are stored and how fields are interpreted during queries. Getting index settings and mappings right early avoids painful rework such as reindexing, broken aggregations, or inconsistent query results later.

In Elasticsearch, an index is a logical container for JSON documents. Index settings control shard layout and replica behavior, while mappings define field types (such as date, keyword, or text) and how data is analyzed for full-text search.

Some index choices are difficult or impossible to change after creation, especially number_of_shards and many mapping decisions. Many Elasticsearch 8.x installations also enable TLS and authentication by default, so API calls may require HTTPS plus credentials; the examples use a local endpoint at http://localhost:9200 and may need adjustment in secured environments.

Steps to create an index in Elasticsearch:

  1. Create an index with custom settings and an explicit mapping.
    $ curl -s -H "Content-Type: application/json" -X PUT "http://localhost:9200/logs-2025.01?pretty" -d '{
      "settings": {
        "number_of_shards": 1,
        "number_of_replicas": 0
      },
      "mappings": {
        "properties": {
          "timestamp": { "type": "date" },
          "level": { "type": "keyword" },
          "message": { "type": "text" }
        }
      }
    }'
    {
      "acknowledged" : true,
      "shards_acknowledged" : true,
      "index" : "logs-2025.01"
    }

    number_of_replicas is set to 0 for a single-node cluster to keep index health from staying yellow due to unassigned replicas.

  2. Confirm the index exists.
    $ curl -s "http://localhost:9200/_cat/indices/logs-2025.01?v"
    health status index        uuid                   pri rep docs.count docs.deleted store.size pri.store.size dataset.size
    green  open   logs-2025.01 98GlrCaeQae_bXpWVIp22g   1   0          0            0       227b           227b         227b
  3. Confirm the index mapping matches the intended field types.
    $ curl -s "http://localhost:9200/logs-2025.01/_mapping?pretty"
    {
      "logs-2025.01" : {
        "mappings" : {
          "properties" : {
            "level" : {
              "type" : "keyword"
            },
            "message" : {
              "type" : "text"
            },
            "timestamp" : {
              "type" : "date"
            }
          }
        }
      }
    }
  4. Index a test document into the new index.
    $ curl -s -H "Content-Type: application/json" -X POST "http://localhost:9200/logs-2025.01/_doc?pretty&refresh=wait_for" -d '{
      "timestamp": "2025-01-21T10:20:00Z",
      "level": "INFO",
      "message": "index created"
    }'
    {
      "_index" : "logs-2025.01",
      "_id" : "xgIHk5sB7KnOsFhxuOFE",
      "_version" : 1,
      "result" : "created",
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "failed" : 0
      },
      "_seq_no" : 0,
      "_primary_term" : 1
    }

    refresh=wait_for waits for the next refresh cycle so the document is searchable immediately in the verification step.

  5. Verify the document is searchable.
    $ curl -s -H "Content-Type: application/json" -X POST "http://localhost:9200/logs-2025.01/_search?pretty" -d '{
      "query": {
        "match": {
          "message": "created"
        }
      }
    }'
    {
      "took" : 55,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 1,
          "relation" : "eq"
        },
        "max_score" : 0.2876821,
        "hits" : [
          {
            "_index" : "logs-2025.01",
            "_id" : "xgIHk5sB7KnOsFhxuOFE",
            "_score" : 0.2876821,
            "_source" : {
              "timestamp" : "2025-01-21T10:20:00Z",
              "level" : "INFO",
              "message" : "index created"
            }
          }
        ]
      }
    }