Link Search Menu Expand Document Documentation Menu

Mappings

Mappings tell OpenSearch how to store and index your documents and their fields. You can specify the data type for each field (for example, year as date) to make storage and querying more efficient.

While dynamic mappings automatically add new data and fields, using explicit mappings is recommended. Explicit mappings let you define the exact structure and data types upfront. This helps to maintain data consistency and optimize performance, especially for large datasets or high-volume indexing operations.

For example, with explicit mappings, you can ensure that year is treated as text and age as an integer instead of both being interpreted as integers by dynamic mapping.

Dynamic mapping

When you index a document, OpenSearch adds fields automatically with dynamic mapping. You can also explicitly add fields to an index mapping.

Dynamic mapping rules

When OpenSearch encounters a new field during indexing, it uses the following rules to determine the field type:

JSON data type OpenSearch field type Description
null No field is added A null field can’t be indexed or searched. When a field is set to null, OpenSearch behaves as if the field has no value.
true or false boolean field OpenSearch accepts true and false as Boolean values. An empty string is equal to false.
Double (for example, 1.5) float field A single-precision, 32-bit IEEE 754 floating-point number, restricted to finite values. JSON floating-point numbers are mapped to this type.
Long (for example, 1) long field A signed 64-bit number. JSON integer numbers are mapped to this type.
Object ({}) object field Objects are standard JSON objects, which can have fields and mappings of their own. For example, a movies object can have additional properties such as title, year, and director.
Array ([]) Depends on the first non-null value in the array OpenSearch does not have a specific array data type. Arrays are represented as a set of values of the same data type (for example, integers or strings) associated with a field. When indexing, you can pass multiple values for a field, and OpenSearch will treat it as an array. Empty arrays are valid and recognized as array fields with zero elements—not as fields with no values.
String ("") text field with keyword subfield, or date field, or numeric field A string sequence of characters. By default, strings are mapped as text fields with a keyword subfield. However, if the string matches a date format (and date detection is enabled), it becomes a date field. If numeric detection is enabled and the string represents a number, it becomes the appropriate numeric field type.

These are the only field types that are automatically detected. All other field types must be mapped explicitly.

Dynamic templates

Dynamic templates are used to define custom mappings for dynamically added fields based on the data type, field name, or field path. They allow you to define a flexible schema for your data that can automatically adapt to changes in the structure or format of the input data.

You can use the following syntax to define a dynamic mapping template:

PUT index
{
  "mappings": {
    "dynamic_templates": [
        {
          "fields": {
            "mapping": {
              "type": "short"
            },
            "match_mapping_type": "string",
            "path_match": "status*"
          }
        }
    ]
  }
}

This mapping configuration dynamically maps any field with a name starting with status (for example, status_code) to the short data type if the initial value provided during indexing is a string.

Dynamic mapping parameters

The dynamic_templates support the following parameters for matching conditions and mapping rules. The default value is null.

Parameter Description
match_mapping_type Specifies the JSON data type (for example, string, long, double, object, binary, Boolean, date) that triggers the mapping.
match A regular expression used to match field names and apply the mapping.
unmatch A regular expression used to exclude field names from the mapping.
match_pattern Determines the pattern matching behavior, either regex or simple. Default is simple.
path_match Allows you to match nested field paths using a regular expression.
path_unmatch Excludes nested field paths from the mapping using a regular expression.
mapping The mapping configuration to apply.

Dynamic mapping settings

OpenSearch provides several settings to control how dynamic mapping behaves when processing new fields.

Date detection

By default, OpenSearch automatically detects date-formatted strings and creates date fields. When date_detection is enabled (default), new string fields are checked against date patterns specified in dynamic_date_formats. If a match is found, a new date field is created with the corresponding format.

The default value for dynamic_date_formats is:

["strict_date_optional_time", "yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z"]

When you run the following example request, the create_date field is automatically mapped as a date field with the format yyyy/MM/dd HH:mm:ss Z||yyyy/MM/dd Z:

PUT sample-index/_doc/1
{
  "create_date": "2025/05/26"
}

You can disable automatic date detection by setting date_detection to false:

PUT sample-index
{
  "mappings": {
    "date_detection": false
  }
}

With date detection disabled, date-formatted strings will be mapped as text fields instead.

You can customize the date patterns used for detection by specifying your own dynamic_date_formats:

PUT sample-index
{
  "mappings": {
    "dynamic_date_formats": ["MM/dd/yyyy", "dd-MM-yyyy"]
  }
}

Numeric detection

While JSON supports native numeric data types, some applications may send numbers as strings. OpenSearch can automatically detect numeric strings and map them as numeric fields when numeric_detection is enabled.

Numeric detection is disabled by default. The recommended approach is to use explicit mappings for numeric fields.

To enable numeric detection, send the following request:

PUT sample-index
{
  "mappings": {
    "numeric_detection": true
  }
}

Then index a document containing numeric fields into the index:

PUT sample-index/_doc/1
{
  "price": "19.99",
  "quantity": "5"
}

With numeric detection enabled:

  • The price field will be mapped as a float field
  • The quantity field will be mapped as a long field

Explicit mapping

If you know exactly which field data types you need to use, then you can specify them in your request body when creating your index, as shown in the following example request:

PUT sample-index1
{
  "mappings": {
    "properties": {
      "year":    { "type" : "text" },
      "age":     { "type" : "integer" },
      "director":{ "type" : "text" }
    }
  }
}

You cannot change the mapping of an existing field, you can only modify the field’s mapping parameters.

To add mappings to an existing index or data stream, you can send a request to the _mapping endpoint using the PUT or POST HTTP method, as shown in the following example request:

POST sample-index1/_mapping
{
  "properties": {
    "year":    { "type" : "text" },
    "age":     { "type" : "integer" },
    "director":{ "type" : "text" }
  }
}

For more information about the Mapping API, see Update mapping.

Retrieving mappings

To get all mappings for one or more indexes, use the following request:

GET <index>/_mapping

In the previous request, <index> may be an index name or a comma-separated list of index names.

To get all mappings for all indexes, use the following request:

GET _mapping

To get a mapping for a specific field, provide the index name and the field name:

GET _mapping/field/<fields>
GET /<index>/_mapping/field/<fields>

Both <index> and <fields> can be specified as either one value or a comma-separated list. For example, the following request retrieves the mapping for the year and age fields in sample-index1:

GET sample-index1/_mapping/field/year,age

The response contains the specified fields:

{
  "sample-index1" : {
    "mappings" : {
      "year" : {
        "full_name" : "year",
        "mapping" : {
          "year" : {
            "type" : "text"
          }
        }
      },
      "age" : {
        "full_name" : "age",
        "mapping" : {
          "age" : {
            "type" : "integer"
          }
        }
      }
    }
  }
}

For more information, see Get Index API.

Examples

The following examples demonstrate practical applications of OpenSearch mappings in different scenarios.

Ignoring malformed IP addresses

The following example shows you how to create a mapping specifying that OpenSearch should ignore any documents containing malformed IP addresses that do not conform to the ip data type. You can accomplish this by setting the ignore_malformed parameter to true.

To create an index with an ip mapping, use a PUT request:

PUT /test-index
{
  "mappings" : {
    "properties" :  {
      "ip_address" : {
        "type" : "ip",
        "ignore_malformed": true
      }
    }
  }
}

Then add a document with a malformed IP address:

PUT /test-index/_doc/1
{
  "ip_address" : "malformed ip address"
}

When you query the index, the ip_address field will be ignored. You can query the index using the following request:

GET /test-index/_search

The response shows that the document was indexed successfully, but the malformed IP address field is listed in the _ignored array:

{
  "took": 14,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "test-index",
        "_id": "1",
        "_score": 1,
        "_ignored": [
          "ip_address"
        ],
        "_source": {
          "ip_address": "malformed ip address"
        }
      }
    ]
  }
}

Mapping string fields to text and keyword types

To create an index named movies1 with a dynamic template that maps all string fields to both the text and keyword types, you can use the following request:

PUT movies1
{
  "mappings": {
    "dynamic_templates": [
      {
        "strings": {
          "match_mapping_type": "string",
          "mapping": {
            "type": "text",
            "fields": {
              "keyword": {
                "type":  "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    ]
  }
}

This dynamic template ensures that any string fields in your documents will be indexed as both a full-text text type and a keyword type.

Mapping parameters

Mapping parameters are used to configure the behavior of index fields. For detailed information about all available mapping parameters, see Mapping parameters.

Metadata fields

OpenSearch automatically manages several metadata fields for each document, such as _source, _id, and _index. For information about all available metadata fields and their configuration options, see Metadata fields.

Mapping limit settings

OpenSearch provides several settings to prevent mapping explosion and control mapping growth. These settings help maintain cluster performance and prevent memory issues caused by creating an excessive number of fields.

These settings can be configured when creating an index or updated for existing indexes:

PUT /my-index/_settings
{
  "index.mapping.total_fields.limit": 2000
}

The following table lists all available mapping limit settings. All settings are dynamic. For more information, see Dynamic settings.

Setting Default Valid values Description
index.mapping.total_fields.limit 1000 [0, ∞) Sets the maximum number of fields allowed in an index, including regular fields, object mappings, and field aliases. Increasing this limit requires careful consideration of cluster resources. When raising this setting, consider also adjusting the indices.query.bool.max_clause_count setting to accommodate larger queries.
index.mapping.depth.limit 20 [1, 100] Controls the maximum nesting depth for field mappings. Depth is calculated by counting the levels of nested objects, starting from the root level (depth 1 for root-level fields, depth 2 for fields within one level of object nesting, and so on).
index.mapping.nested_fields.limit 50 [0, ∞) Limits the number of distinct nested field types in an index. Since nested fields require special handling and additional memory, this setting helps prevent excessive resource consumption.
index.mapping.nested_objects.limit 10000 [0, ∞) Restricts the total number of nested JSON objects that a single document can contain across all nested field types. This prevents individual documents from consuming excessive memory during indexing.
index.mapping.field_name_length.limit 50000 [1, 50000] Sets the maximum allowed length for field names. This setting can help maintain reasonable mapping sizes by preventing extremely long field names.
index.mapper.dynamic true true,false Determines whether new fields should be dynamically added to a mapping. Setting this to false can prevent uncontrolled field growth.