elastic/elasticsearch-java

DynamicTemplates serializes MatchMappingType as a list

bnconti opened this issue · 2 comments

Java API client version

8.15.3

Java version

8

Elasticsearch Version

8.4.3

Problem description

Hey guys, I have some code that's using the indices().putMapping() API, and I think that I have found an issue when building the PutMappingRequest object.

I'm using the withJson() method, with this input:

{
  "dynamic_templates": [
    {
      "aggregate_template": {
        "match_mapping_type": "string",
        "match": "*___aggregate",
        "mapping": {
          "type": "text"
        }
      }
    }
  ]
}

Notice how the match_mapping_type is a String primitive, not a list. Now, when the Builder constructs the PutMappingRequest object, the request that it generates has this form:

PutMappingRequest: PUT /index/_mapping {"dynamic_templates":[{"attach_template":{"match":["attach___*"],"match_mapping_type":["string"],"mapping":{"type":"text"}}}]}

Notice how the match_mapping_type field was converted to a list. When using that in the request body to update the mapping, the ES responds with a 400 status:

{
  "root_cause": [
    {
      "type": "mapper_parsing_exception",
      "reason": "Failed to parse mapping: No field type matched on [[string]], possible values are [object, string, long, double, boolean, date, binary]"
    }
  ],
  "type": "mapper_parsing_exception",
  "reason": "Failed to parse mapping: No field type matched on [[string]], possible values are [object, string, long, double, boolean, date, binary]",
  "caused_by": {
    "type": "illegal_argument_exception",
    "reason": "No field type matched on [[string]], possible values are [object, string, long, double, boolean, date, binary]"
  }
}

But if I use the match_mapping_type as a String (as it was originally in my JSON), it works. In short, the client is building this body:

{
  "dynamic_templates": [
    {
      "attach_template": {
        "match": [
          "attach___*"
        ],
        "match_mapping_type": [
          "string"
        ],
        "mapping": {
          "type": "text"
        }
      }
    }
  ]
}

When it seems that it should be:

{
  "dynamic_templates": [
    {
      "attach_template": {
        "match": [
          "attach___*"
        ],
        "match_mapping_type": "string",
        "mapping": {
          "type": "text"
        }
      }
    }
  ]
}

Hm, maybe this isn't really an issue? The documentation says:

You can specify either a single data type or a list of data types for either the match_mapping_type or unmatch_mapping_type parameters

Maybe I'm missing something?

Hello! The documentation is correct, it just refers to the most recent version of the Elasticsearch server. The DynamicTemplate class was updated in version 8.13.0, adding new fields and support for arrays, and new versions of the java client were also updated to match the changes. You should update the server version :)