Update mapping API

edit

Adds new fields to an existing data stream or index. You can also use this API to change the search settings of existing fields.

For data streams, these changes are applied to all backing indices by default.

resp = client.indices.put_mapping(
    index="my-index-000001",
    properties={
        "email": {
            "type": "keyword"
        }
    },
)
print(resp)
response = client.indices.put_mapping(
  index: 'my-index-000001',
  body: {
    properties: {
      email: {
        type: 'keyword'
      }
    }
  }
)
puts response
const response = await client.indices.putMapping({
  index: "my-index-000001",
  properties: {
    email: {
      type: "keyword",
    },
  },
});
console.log(response);
PUT /my-index-000001/_mapping
{
  "properties": {
    "email": {
      "type": "keyword"
    }
  }
}

Request

edit

PUT /<target>/_mapping

Prerequisites

edit
  • If the Elasticsearch security features are enabled, you must have the manage index privilege for the target data stream, index, or alias.

    [7.9] Deprecated in 7.9. If the request targets an index or index alias, you can also update its mapping with the create, create_doc, index, or write index privilege.

Path parameters

edit
<target>
(Required, string) Comma-separated list of data streams, indices, and aliases used to limit the request. Supports wildcards (*). To target all data streams and indices, omit this parameter or use * or _all.

Query parameters

edit
allow_no_indices

(Optional, Boolean) If false, the request returns an error if any wildcard expression, index alias, or _all value targets only missing or closed indices. This behavior applies even if the request targets other open indices. For example, a request targeting foo*,bar* returns an error if an index starts with foo but no index starts with bar.

Defaults to false.

expand_wildcards

(Optional, string) Type of index that wildcard patterns can match. If the request can target data streams, this argument determines whether wildcard expressions match hidden data streams. Supports comma-separated values, such as open,hidden. Valid values are:

all
Match any data stream or index, including hidden ones.
open
Match open, non-hidden indices. Also matches any non-hidden data stream.
closed
Match closed, non-hidden indices. Also matches any non-hidden data stream. Data streams cannot be closed.
hidden
Match hidden data streams and hidden indices. Must be combined with open, closed, or both.
none
Wildcard patterns are not accepted.

Defaults to open.

ignore_unavailable
(Optional, Boolean) If false, the request returns an error if it targets a missing or closed index. Defaults to false.
master_timeout
(Optional, time units) Period to wait for the master node. If the master node is not available before the timeout expires, the request fails and returns an error. Defaults to 30s. Can also be set to -1 to indicate that the request should never timeout.
timeout
(Optional, time units) Period to wait for a response from all relevant nodes in the cluster after updating the cluster metadata. If no response is received before the timeout expires, the cluster metadata update still applies but the response will indicate that it was not completely acknowledged. Defaults to 30s. Can also be set to -1 to indicate that the request should never timeout.
write_index_only
(Optional, Boolean) If true, the mappings are applied only to the current write index for the target. Defaults to false.

Request body

edit
properties

(Required, mapping object) Mapping for a field. For new fields, this mapping can include:

For existing fields, see Change the mapping of an existing field.

Examples

edit

Example with single target

edit

The update mapping API requires an existing data stream or index. The following create index API request creates the publications index with no mapping.

$params = [
    'index' => 'publications',
];
$response = $client->indices()->create($params);
resp = client.indices.create(
    index="publications",
)
print(resp)
response = client.indices.create(
  index: 'publications'
)
puts response
res, err := es.Indices.Create("publications")
fmt.Println(res, err)
const response = await client.indices.create({
  index: "publications",
});
console.log(response);
PUT /publications

The following update mapping API request adds title, a new text field, to the publications index.

$params = [
    'index' => 'publications',
    'body' => [
        'properties' => [
            'title' => [
                'type' => 'text',
            ],
        ],
    ],
];
$response = $client->indices()->putMapping($params);
resp = client.indices.put_mapping(
    index="publications",
    properties={
        "title": {
            "type": "text"
        }
    },
)
print(resp)
response = client.indices.put_mapping(
  index: 'publications',
  body: {
    properties: {
      title: {
        type: 'text'
      }
    }
  }
)
puts response
res, err := es.Indices.PutMapping(
	[]string{"publications"},
	strings.NewReader(`{
	  "properties": {
	    "title": {
	      "type": "text"
	    }
	  }
	}`),
)
fmt.Println(res, err)
const response = await client.indices.putMapping({
  index: "publications",
  properties: {
    title: {
      type: "text",
    },
  },
});
console.log(response);
PUT /publications/_mapping
{
  "properties": {
    "title":  { "type": "text"}
  }
}

Multiple targets

edit

The update mapping API can be applied to multiple data streams or indices with a single request. For example, you can update mappings for the my-index-000001 and my-index-000002 indices at the same time:

resp = client.indices.create(
    index="my-index-000001",
)
print(resp)

resp1 = client.indices.create(
    index="my-index-000002",
)
print(resp1)

resp2 = client.indices.put_mapping(
    index="my-index-000001,my-index-000002",
    properties={
        "user": {
            "properties": {
                "name": {
                    "type": "keyword"
                }
            }
        }
    },
)
print(resp2)
response = client.indices.create(
  index: 'my-index-000001'
)
puts response

response = client.indices.create(
  index: 'my-index-000002'
)
puts response

response = client.indices.put_mapping(
  index: 'my-index-000001,my-index-000002',
  body: {
    properties: {
      user: {
        properties: {
          name: {
            type: 'keyword'
          }
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "my-index-000001",
});
console.log(response);

const response1 = await client.indices.create({
  index: "my-index-000002",
});
console.log(response1);

const response2 = await client.indices.putMapping({
  index: "my-index-000001,my-index-000002",
  properties: {
    user: {
      properties: {
        name: {
          type: "keyword",
        },
      },
    },
  },
});
console.log(response2);
# Create the two indices
PUT /my-index-000001
PUT /my-index-000002

# Update both mappings
PUT /my-index-000001,my-index-000002/_mapping
{
  "properties": {
    "user": {
      "properties": {
        "name": {
          "type": "keyword"
        }
      }
    }
  }
}

Add new properties to an existing object field

edit

You can use the update mapping API to add new properties to an existing object field. To see how this works, try the following example.

Use the create index API to create an index with the name object field and an inner first text field.

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "name": {
                "properties": {
                    "first": {
                        "type": "text"
                    }
                }
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        name: {
          properties: {
            first: {
              type: 'text'
            }
          }
        }
      }
    }
  }
)
puts response
res, err := es.Indices.Create(
	"my-index-000001",
	es.Indices.Create.WithBody(strings.NewReader(`{
	  "mappings": {
	    "properties": {
	      "name": {
	        "properties": {
	          "first": {
	            "type": "text"
	          }
	        }
	      }
	    }
	  }
	}`)),
)
fmt.Println(res, err)
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      name: {
        properties: {
          first: {
            type: "text",
          },
        },
      },
    },
  },
});
console.log(response);
PUT /my-index-000001
{
  "mappings": {
    "properties": {
      "name": {
        "properties": {
          "first": {
            "type": "text"
          }
        }
      }
    }
  }
}

Use the update mapping API to add a new inner last text field to the name field.

resp = client.indices.put_mapping(
    index="my-index-000001",
    properties={
        "name": {
            "properties": {
                "last": {
                    "type": "text"
                }
            }
        }
    },
)
print(resp)
response = client.indices.put_mapping(
  index: 'my-index-000001',
  body: {
    properties: {
      name: {
        properties: {
          last: {
            type: 'text'
          }
        }
      }
    }
  }
)
puts response
res, err := es.Indices.PutMapping(
	[]string{"my-index-000001"},
	strings.NewReader(`{
	  "properties": {
	    "name": {
	      "properties": {
	        "last": {
	          "type": "text"
	        }
	      }
	    }
	  }
	}`),
)
fmt.Println(res, err)
const response = await client.indices.putMapping({
  index: "my-index-000001",
  properties: {
    name: {
      properties: {
        last: {
          type: "text",
        },
      },
    },
  },
});
console.log(response);
PUT /my-index-000001/_mapping
{
  "properties": {
    "name": {
      "properties": {
        "last": {
          "type": "text"
        }
      }
    }
  }
}

Add multi-fields to an existing field

edit

Multi-fields let you index the same field in different ways. You can use the update mapping API to update the fields mapping parameter and enable multi-fields for an existing field.

If an index (or data stream) contains documents when you add a multi-field, those documents will not have values for the new multi-field. You can populate the new multi-field with the update by query API.

To see how this works, try the following example.

Use the create index API to create an index with the city text field.

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "city": {
                "type": "text"
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        city: {
          type: 'text'
        }
      }
    }
  }
)
puts response
res, err := es.Indices.Create(
	"my-index-000001",
	es.Indices.Create.WithBody(strings.NewReader(`{
	  "mappings": {
	    "properties": {
	      "city": {
	        "type": "text"
	      }
	    }
	  }
	}`)),
)
fmt.Println(res, err)
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      city: {
        type: "text",
      },
    },
  },
});
console.log(response);
PUT /my-index-000001
{
  "mappings": {
    "properties": {
      "city": {
        "type": "text"
      }
    }
  }
}

While text fields work well for full-text search, keyword fields are not analyzed and may work better for sorting or aggregations.

Use the update mapping API to enable a multi-field for the city field. This request adds the city.raw keyword multi-field, which can be used for sorting.

resp = client.indices.put_mapping(
    index="my-index-000001",
    properties={
        "city": {
            "type": "text",
            "fields": {
                "raw": {
                    "type": "keyword"
                }
            }
        }
    },
)
print(resp)
response = client.indices.put_mapping(
  index: 'my-index-000001',
  body: {
    properties: {
      city: {
        type: 'text',
        fields: {
          raw: {
            type: 'keyword'
          }
        }
      }
    }
  }
)
puts response
res, err := es.Indices.PutMapping(
	[]string{"my-index-000001"},
	strings.NewReader(`{
	  "properties": {
	    "city": {
	      "type": "text",
	      "fields": {
	        "raw": {
	          "type": "keyword"
	        }
	      }
	    }
	  }
	}`),
)
fmt.Println(res, err)
const response = await client.indices.putMapping({
  index: "my-index-000001",
  properties: {
    city: {
      type: "text",
      fields: {
        raw: {
          type: "keyword",
        },
      },
    },
  },
});
console.log(response);
PUT /my-index-000001/_mapping
{
  "properties": {
    "city": {
      "type": "text",
      "fields": {
        "raw": {
          "type": "keyword"
        }
      }
    }
  }
}

Change supported mapping parameters for an existing field

edit

The documentation for each mapping parameter indicates whether you can update it for an existing field using the update mapping API. For example, you can use the update mapping API to update the ignore_above parameter.

To see how this works, try the following example.

Use the create index API to create an index containing a user_id keyword field. The user_id field has an ignore_above parameter value of 20.

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "user_id": {
                "type": "keyword",
                "ignore_above": 20
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        user_id: {
          type: 'keyword',
          ignore_above: 20
        }
      }
    }
  }
)
puts response
res, err := es.Indices.Create(
	"my-index-000001",
	es.Indices.Create.WithBody(strings.NewReader(`{
	  "mappings": {
	    "properties": {
	      "user_id": {
	        "type": "keyword",
	        "ignore_above": 20
	      }
	    }
	  }
	}`)),
)
fmt.Println(res, err)
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      user_id: {
        type: "keyword",
        ignore_above: 20,
      },
    },
  },
});
console.log(response);
PUT /my-index-000001
{
  "mappings": {
    "properties": {
      "user_id": {
        "type": "keyword",
        "ignore_above": 20
      }
    }
  }
}

Use the update mapping API to change the ignore_above parameter value to 100.

resp = client.indices.put_mapping(
    index="my-index-000001",
    properties={
        "user_id": {
            "type": "keyword",
            "ignore_above": 100
        }
    },
)
print(resp)
response = client.indices.put_mapping(
  index: 'my-index-000001',
  body: {
    properties: {
      user_id: {
        type: 'keyword',
        ignore_above: 100
      }
    }
  }
)
puts response
res, err := es.Indices.PutMapping(
	[]string{"my-index-000001"},
	strings.NewReader(`{
	  "properties": {
	    "user_id": {
	      "type": "keyword",
	      "ignore_above": 100
	    }
	  }
	}`),
)
fmt.Println(res, err)
const response = await client.indices.putMapping({
  index: "my-index-000001",
  properties: {
    user_id: {
      type: "keyword",
      ignore_above: 100,
    },
  },
});
console.log(response);
PUT /my-index-000001/_mapping
{
  "properties": {
    "user_id": {
      "type": "keyword",
      "ignore_above": 100
    }
  }
}

Change the mapping of an existing field

edit

Except for supported mapping parameters, you can’t change the mapping or field type of an existing field. Changing an existing field could invalidate data that’s already indexed.

If you need to change the mapping of a field in a data stream’s backing indices, see Change mappings and settings for a data stream.

If you need to change the mapping of a field in other indices, create a new index with the correct mapping and reindex your data into that index.

To see how you can change the mapping of an existing field in an index, try the following example.

Use the create index API to create an index with the user_id field with the long field type.

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "user_id": {
                "type": "long"
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        user_id: {
          type: 'long'
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      user_id: {
        type: "long",
      },
    },
  },
});
console.log(response);
PUT /my-index-000001
{
  "mappings" : {
    "properties": {
      "user_id": {
        "type": "long"
      }
    }
  }
}

Use the index API to index several documents with user_id field values.

resp = client.index(
    index="my-index-000001",
    refresh="wait_for",
    document={
        "user_id": 12345
    },
)
print(resp)

resp1 = client.index(
    index="my-index-000001",
    refresh="wait_for",
    document={
        "user_id": 12346
    },
)
print(resp1)
response = client.index(
  index: 'my-index-000001',
  refresh: 'wait_for',
  body: {
    user_id: 12_345
  }
)
puts response

response = client.index(
  index: 'my-index-000001',
  refresh: 'wait_for',
  body: {
    user_id: 12_346
  }
)
puts response
const response = await client.index({
  index: "my-index-000001",
  refresh: "wait_for",
  document: {
    user_id: 12345,
  },
});
console.log(response);

const response1 = await client.index({
  index: "my-index-000001",
  refresh: "wait_for",
  document: {
    user_id: 12346,
  },
});
console.log(response1);
POST /my-index-000001/_doc?refresh=wait_for
{
  "user_id" : 12345
}

POST /my-index-000001/_doc?refresh=wait_for
{
  "user_id" : 12346
}

To change the user_id field to the keyword field type, use the create index API to create a new index with the correct mapping.

resp = client.indices.create(
    index="my-new-index-000001",
    mappings={
        "properties": {
            "user_id": {
                "type": "keyword"
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-new-index-000001',
  body: {
    mappings: {
      properties: {
        user_id: {
          type: 'keyword'
        }
      }
    }
  }
)
puts response
const response = await client.indices.create({
  index: "my-new-index-000001",
  mappings: {
    properties: {
      user_id: {
        type: "keyword",
      },
    },
  },
});
console.log(response);
PUT /my-new-index-000001
{
  "mappings" : {
    "properties": {
      "user_id": {
        "type": "keyword"
      }
    }
  }
}

Use the reindex API to copy documents from the old index to the new one.

resp = client.reindex(
    source={
        "index": "my-index-000001"
    },
    dest={
        "index": "my-new-index-000001"
    },
)
print(resp)
response = client.reindex(
  body: {
    source: {
      index: 'my-index-000001'
    },
    dest: {
      index: 'my-new-index-000001'
    }
  }
)
puts response
const response = await client.reindex({
  source: {
    index: "my-index-000001",
  },
  dest: {
    index: "my-new-index-000001",
  },
});
console.log(response);
POST /_reindex
{
  "source": {
    "index": "my-index-000001"
  },
  "dest": {
    "index": "my-new-index-000001"
  }
}

Rename a field

edit

Renaming a field would invalidate data already indexed under the old field name. Instead, add an alias field to create an alternate field name.

For example, use the create index API to create an index with the user_identifier field.

resp = client.indices.create(
    index="my-index-000001",
    mappings={
        "properties": {
            "user_identifier": {
                "type": "keyword"
            }
        }
    },
)
print(resp)
response = client.indices.create(
  index: 'my-index-000001',
  body: {
    mappings: {
      properties: {
        user_identifier: {
          type: 'keyword'
        }
      }
    }
  }
)
puts response
res, err := es.Indices.Create(
	"my-index-000001",
	es.Indices.Create.WithBody(strings.NewReader(`{
	  "mappings": {
	    "properties": {
	      "user_identifier": {
	        "type": "keyword"
	      }
	    }
	  }
	}`)),
)
fmt.Println(res, err)
const response = await client.indices.create({
  index: "my-index-000001",
  mappings: {
    properties: {
      user_identifier: {
        type: "keyword",
      },
    },
  },
});
console.log(response);
PUT /my-index-000001
{
  "mappings": {
    "properties": {
      "user_identifier": {
        "type": "keyword"
      }
    }
  }
}

Use the update mapping API to add the user_id field alias for the existing user_identifier field.

resp = client.indices.put_mapping(
    index="my-index-000001",
    properties={
        "user_id": {
            "type": "alias",
            "path": "user_identifier"
        }
    },
)
print(resp)
response = client.indices.put_mapping(
  index: 'my-index-000001',
  body: {
    properties: {
      user_id: {
        type: 'alias',
        path: 'user_identifier'
      }
    }
  }
)
puts response
res, err := es.Indices.PutMapping(
	[]string{"my-index-000001"},
	strings.NewReader(`{
	  "properties": {
	    "user_id": {
	      "type": "alias",
	      "path": "user_identifier"
	    }
	  }
	}`),
)
fmt.Println(res, err)
const response = await client.indices.putMapping({
  index: "my-index-000001",
  properties: {
    user_id: {
      type: "alias",
      path: "user_identifier",
    },
  },
});
console.log(response);
PUT /my-index-000001/_mapping
{
  "properties": {
    "user_id": {
      "type": "alias",
      "path": "user_identifier"
    }
  }
}