Elasticsearch Mappings: Examples on how to Create, Edit, Remove

Last updated:

Mappings are the way you can define some sort of schema for a document type that will live in a given index.

Examples for Elasticsearch version 1.5 unless otherwise noted. They will likely work with newer versions too.

It may not always be needed to define mappings for your types because ES adds it automatically; if you add a document with an extra property, the mapping for this type will be updated automatically.

Mappings are generally used when you need to make sure that some properties are indexed the way you want (think dates vs normal strings, etc) and when you need to configure which fields are indexed, which are analyzed, and so on.

All examples are in Sense format, so that you can just copy and paste into Sense (Available as a Chrome plugin or a Kibana app)

Add a new mapping to an existing index

Suppose you want to add a new mapping for a type called myType, in index myIndex index:

PUT http://path.to.my.cluster/myIndex/_mapping/myType
{
  "myType": {
    "properties": {
      "timestamp": {
        "type": "date",
        "format": "date_optional_time"
      },
      "field_1": {
        "type": "string",
        "index": "not_analyzed"
      },
      "field_2": {
        "type": "double"
      }
    }
  }
}

Now here's an example for mappings that include nested objects.

PUT http://path.to.my.cluster/myIndex/_mapping/cars
{
  "cars":{
    "properties":{
      "owner":{
        "properties":{
          "name":{
            "type": "string",
            "index": "not_analyzed"
          },
          "age":{
            "type":"integer"
          }
        }
      },
      "model": {
        "type":"string",
        "index":"not_analyzed"
      },
      "manufacturer":{
        "type" :"string",
        "index":"not_analyzed"
      }
    }
  }
}

The above mapping tells Elasticsearch that you want to index documents such as the following:

{
  "model": "C-Class",
  "manufacturer":"Mercedes-Benz",
  "owner":{
    "name": "John Doe",
    "age": 45
  }
}

Add a property to an existing mapping

Say you wish to add another property, called FooBar, to the mapping for myType :

PUT http://path.to.my.cluster/myIndex/_mapping/myType
{
  "properties":{
    "FooBar":{
      "type":"string"
    }
  }
}

So what happens to documents you've added before you have added this new property? Nothing. The are unaffected, i.e. they will not have this property added to them.

Update a TTL mapping for an existing type

_ttl (time to leave) is also part of the mapping (but not part of the properties) object.

You can update it the same way as for other mappings (such as properties):

2580480000 is the number of milliseconds in 32 days (roughly one month)

PUT http://path.to.my.cluster/myIndex/_mapping/myType
{
    "_ttl":{
        "enabled": true,
        "default": 2580480000
    }
}

Remove a property from an existing mapping

It seems this is currently impossible to do; but an extra property mapping does not affect your other objects, so you should be fine.

Delete an existing mapping

As of version 2.3, you cannot delete a single mapping anymore. Delete the whole index and recreate it with the desired mappings

Let's say you want to delete the mapping for type myType in your index:

DELETE http://path.to.my.cluster/myIndex/myType

Dynamic templates for attributes

Dynamic mappings allow you to set options for attributes before they are even added.

Note that you can only do this if it doesn't conflict with existing types otherwise you'll get an error

For example, if you want to tell Elasticsearch to create a new index called myNewIndex and have all fields ending on "_debug" of type string under type myCustomType not be analyzed, this is what you should do:

PUT http://path.to.my.cluster/myIndex
{
  "mappings": {
    "myCustomType": {
      "dynamic_templates": [
        { 
          "notanalyzed": {
            "match": "*_debug", 
            "match_mapping_type": "string",
            "mapping": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      ]
    }
  }
}

Dynamic templates for indices

Whereas the above recipe defines default mappings for attributes in a single index (the index you are creating), what if you want to tell Elasticsearch that your want all indices created (whose names match some rule like "custom-index-*") to have such and such mappings for their attributes?

The following PUT request applies the same dynamic template as was seen above, for every new index created, whose name starts with "custom-index-"

PUT http://path.to.my.cluster/_template/my-custom-index-template
{
  "template": "custom-index-*",
  "mappings":{
    "myCustomType": {
      "dynamic_templates": [
        { 
          "notanalyzed": {
            "match": "*_debug", 
            "match_mapping_type": "string",
            "mapping": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        }
      ]
    }
  }
}

See also:

Dialogue & Discussion