Custom datatype in mappin

I first post my question/feature request on https://github.com/elastic/elasticsearch/issues/14341
but did not get a satisfactory answer.

I haven't found a way to create a custom datatype to reuse in mapping definition.

I would like to have a way to define custom_datatype in the mapping like that :

{
  "settings" : {
     "number_of_shards" : 1,
     "custom_datatypes": [{
         "string_with_raw": {
           "mapping": {
             "index": "analyzed",
             "omit_norms": true,
             "type": "string",
             "fields": {
               "raw": {
                 "ignore_above": 256,
                 "index": "not_analyzed",
                 "type": "string"
               }
             }
           }
         }
      }],
  },
  "mappings" : {
    "my_type": {
      "properties": {
        "field1": {
            "type": "string_with_raw"             
        },
        "field2": {
            "type": "string_with_raw"             
         },
         "field3": {
            "type": "string"             
         }
      }
    }
  }
}

For now I have to duplicate for every field :

"mappings": {
      "my_type": {      
        "properties": {
          "message": {
               "index": "analyzed",
               "omit_norms": true,
               "type": "string",
               "fields": {
                  "raw": {
                     "ignore_above": 256,
                     "index": "not_analyzed",
                     "type": "string"
                  }
               }     
          },
          "field2": {
              "index": "analyzed",
              "omit_norms": true,
              "type": "string",
              "fields": {
                "raw": {
                  "ignore_above": 256,
                  "index": "not_analyzed",
                  "type": "string"
                }
              }             
          },
          "field3": {
              "type": "string"             
          }
        }
     }
}

}

It could also be used in dynamic mappings:

{
 "settings" : {
    "number_of_shards" : 1,
    "custom_datatypes": [{
        "string_with_raw": {
          "mapping": {
            "index": "analyzed",
            "omit_norms": true,
            "type": "string",
            "fields": {
              "raw": {
                "ignore_above": 256,
                "index": "not_analyzed",
                "type": "string"
              }
            }
          }
        }
     }],
},
"mappings" : {
  "my_type": {
     "dynamic_templates": [{
        "message_field": {
          "mapping": {
            "omit_norms": false,
           "type": "string_with_raw"
          },
          "match_mapping_type": "string",
          "match": "*_with_raw"
        }
    }],
    "properties": {
      "field1": {
            "type": "string_with_raw"             
        },
       "field2": {
            "type": "string_with_raw"             
        },
        "field3": {
            "type": "string"             
        }            
    }
  }
}

}

For the dynamic_templates part, the value set in the mapping should override equivalent field defined in the custom datatype.

Is there a way to achieve that at the moment ?

There is currently no way to create custom data types through the JSON settings as you've outlined. However, you can create custom data types by implementing an Elasticsearch Plugin and registering the type that way. This plugin shows an example of how to create a custom datatype: