2
votes

If multiple types in an Elasticsearch index have fields with the same name, those fields must have the same mapping that tries to create a "foobar" property as both string and long"...

For example if you try to PUT the following index mapping:

{
  "mappings": {
    "type_one": {
      "properties": {
        "foobar": { 
          "type": "string"
        }
      }
    },
    "type_two": {
      "properties": {
        "foobar": { 
          "type": "long"
        }
      }
    }
  }
}

...the following error will be returned

{
  "error": {
    "root_cause": [
      {
        "type": "mapper_parsing_exception",
        "reason": "Failed to parse mapping [type_one]: mapper [foobar] cannot be changed from type [long] to [string]"
      }
    ],
    "type": "mapper_parsing_exception",
    "reason": "Failed to parse mapping [type_one]: mapper [foobar] cannot be changed from type [long] to [string]",
    "caused_by": {
      "type": "illegal_argument_exception",
      "reason": "mapper [foobar] cannot be changed from type [long] to [string]"
    }
  },
  "status": 400
}

The following is from the elasticsearch site:

Conflicts between fields in different types

Fields in the same index with the same name in two different types must have the same mapping, as they are backed by the same field internally. Trying to update a mapping parameter for a field which exists in more than one type will throw an exception, unless you specify the update_all_types parameter, in which case it will update that parameter across all fields with the same name in the same index.

If fields with the same name must have the same mapping for all types in the index then why are field mappings specified per type? Why not specify the fields for the entire index, and then identify which fields are assigned to each type.

For example something like this:

{
   "fields":{
      "PropA":{
         "type":"string"
      },
      "PropB":{
         "type":"long"
      },
      "PropC":{
         "type":"boolean"
      }
   },
   "types":{
      "foo":[
         "PropA",
         "PropB"
      ],
      "foo":[
         "PropA",
         "PropC"
      ],
      "foo":[
         "PropA",
         "PropC",
         "PropC"
      ]
   }
}

Wouldn't a mapping format like this be more succinct, and a better representation of what is actually allowed?

The reason I ask is because I'm working on creating an index template JSON file with about 80 different fields used across 15 types. Many of the fields are used across multiple if not all the types. So anytime I need to update a field I have to make sure I update it for every type where it's used.

1

1 Answers

0
votes

Looks like I'm not the only one that found this confusing.

Remove support for types? #15613

Sounds like removing support for multiple types per index and specifying fields at the index level is on the roadmap for future versions.