# Force default "type" of new fields to be "string"?

**URL:** <https://discuss.elastic.co/t/force-default-type-of-new-fields-to-be-string/11618>\
**Category:** Elasticsearch\
**Created:** [April 17, 2013, 6:47pm UTC](https://discuss.elastic.co/t/force-default-type-of-new-fields-to-be-string/11618 "2013-04-17T18:47:51Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jamshid](https://avatars.discourse-cdn.com/v4/letter/j/ecd19e/32.png) [@Jamshid](https://discuss.elastic.co/u/Jamshid)\
**Post date:** [April 17, 2013, 6:47pm UTC](https://discuss.elastic.co/t/force-default-type-of-new-fields-to-be-string/11618/1 "2013-04-17T18:47:51Z")

</div>

Hi, I'm currently setting the type of the "known" fields in my index via  
elasticsearch-0.19.3/config/templates/foo.json:

{  
"foo\_template" : {  
"template" : "\*",  
"settings" : {  
"index.number\_of\_shards" : 3,  
"index.number\_of\_replicas" : 1  
},  
"mappings" : {  
"_default_" : {  
"\_source" : { "enabled" : true,  
"compress" : true },  
"\_all" : { "enabled" : false },  
"\_timestamp" : { "enabled" : true,  
"store" : true },  
"analyzer" : "keyword",  
"properties" : {  
"name" : { "type" : "string", "analyzer" : "keyword" },  
"size" : { "type" : "long" }  
}  
}  
}  
}  
}

Problem is that I also index user-supplied fields, but don't know the names  
of the field beforehand. E.g.:

$ curl -XPOST '[http://localhost:9200/test/123](http://localhost:9200/test/123)' -d '{ "name" : "test", _"x-foo-meta"  
: "2013-01-01"_, "size" : 1 }'

But I don't want "x-foo-meta" type to ever be date, only string. If the  
first insert happens to contain a value that looks like a date then the  
mapping for the field is permanently set to date:

$ curl -XGET '[http://localhost:9200/test/\_mapping](http://localhost:9200/test/_mapping)'  
{"test":{"123":{"analyzer":"keyword","\_all":{"enabled":false},"\_timestamp":{"store":"yes","enabled":true},"\_source":{"compress":true},"properties":{"name":{"type":"string","analyzer":"keyword"},"size":{"type":"long"},  
_"x-foo-meta":{"type":"date"_  
,"format":"dateOptionalTime"}}},"_default_":{"analyzer":"keyword","\_all":{"enabled":false},"\_timestamp":{"store":"yes","enabled":true},"\_source":{"compress":true},"properties":{"name":{"type":"string","analyzer":"keyword"},"size":{"type":"long"}}}}}

If I try to insert a non-date value I get an error:

$ curl -XPOST '[http://localhost:9200/test/123](http://localhost:9200/test/123)' -d '{ "name" : "test", _"x-foo-meta"  
: "x2013-01-01"_, "size" : 1 }'  
{"error":"MapperParsingException[Failed to parse [x-foo-meta]]; nested:  
MapperParsingException[failed to parse date field [x2013-01-01], tried both  
date format [dateOptionalTime], and timestamp number]; nested:  
IllegalArgumentException[Invalid format: "x2013-01-01"]; ","status":400}

So, how can I force the type of all unspecified fields to be "string"?  
Wildcards don't work in "properties", and setting "type" : "string" in the  
foo.json caused an error on insert, I assume because the "size" field I'm  
inserting is not a string:

{"error":"MapperParsingException[mapping [_default_]]; nested:  
MapperParsingException[Trying to parse an object but has a different type  
[string] for [_default_]]; ","status":400}

Thanks,  
Jamshid

--  
You received this message because you are subscribed to the Google Groups "elasticsearch" group.  
To unsubscribe from this group and stop receiving emails from it, send an email to [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<div class="post-metadata">

**Author:** ![Ivan](https://avatars.discourse-cdn.com/v4/letter/i/df788c/32.png) [@Ivan](https://discuss.elastic.co/u/Ivan)\
**Post date:** [April 17, 2013, 6:57pm UTC](https://discuss.elastic.co/t/force-default-type-of-new-fields-to-be-string/11618/2 "2013-04-17T18:57:14Z")

</div>

Dynamic templates is what you are looking for:

> **[Elasticsearch Platform — Find real-time answers at scale](https://www.elastic.co)**
>
> Power insights and outcomes with the Elasticsearch Platform and AI. See into your data and find answers that matter with enterprise solutions designed to help you build, observe, and protect. Try Elasticsearch free today.

Looking for dynamic\_templates toward the bottom. That section really should  
be a standalone page IMHO.

--  
Ivan

On Wed, Apr 17, 2013 at 11:47 AM, Jamshid [jamshid69@gmail.com](mailto:jamshid69@gmail.com) wrote:

> Hi, I'm currently setting the type of the "known" fields in my index via  
> elasticsearch-0.19.3/config/templates/foo.json:
> 
> {  
> "foo\_template" : {  
> "template" : "\*",  
> "settings" : {  
> "index.number\_of\_shards" : 3,  
> "index.number\_of\_replicas" : 1  
> },  
> "mappings" : {  
> "_default_" : {  
> "\_source" : { "enabled" : true,  
> "compress" : true },  
> "\_all" : { "enabled" : false },  
> "\_timestamp" : { "enabled" : true,  
> "store" : true },  
> "analyzer" : "keyword",  
> "properties" : {  
> "name" : { "type" : "string", "analyzer" : "keyword"  
> },  
> "size" : { "type" : "long" }  
> }  
> }  
> }  
> }  
> }
> 
> Problem is that I also index user-supplied fields, but don't know the  
> names of the field beforehand. E.g.:
> 
> $ curl -XPOST '[http://localhost:9200/test/123](http://localhost:9200/test/123)' -d '{ "name" : "test", _"x-foo-meta"  
> : "2013-01-01"_, "size" : 1 }'
> 
> But I don't want "x-foo-meta" type to ever be date, only string. If the  
> first insert happens to contain a value that looks like a date then the  
> mapping for the field is permanently set to date:
> 
> $ curl -XGET '[http://localhost:9200/test/\_mapping](http://localhost:9200/test/_mapping)'
> 
> {"test":{"123":{"analyzer":"keyword","\_all":{"enabled":false},"\_timestamp":{"store":"yes","enabled":true},"\_source":{"compress":true},"properties":{"name":{"type":"string","analyzer":"keyword"},"size":{"type":"long"},  
> _"x-foo-meta":{"type":"date"_  
> ,"format":"dateOptionalTime"}}},"_default_":{"analyzer":"keyword","\_all":{"enabled":false},"\_timestamp":{"store":"yes","enabled":true},"\_source":{"compress":true},"properties":{"name":{"type":"string","analyzer":"keyword"},"size":{"type":"long"}}}}}
> 
> If I try to insert a non-date value I get an error:
> 
> $ curl -XPOST '[http://localhost:9200/test/123](http://localhost:9200/test/123)' -d '{ "name" : "test", _"x-foo-meta"  
> : "x2013-01-01"_, "size" : 1 }'  
> {"error":"MapperParsingException[Failed to parse [x-foo-meta]]; nested:  
> MapperParsingException[failed to parse date field [x2013-01-01], tried both  
> date format [dateOptionalTime], and timestamp number]; nested:  
> IllegalArgumentException[Invalid format: "x2013-01-01"]; ","status":400}
> 
> So, how can I force the type of all unspecified fields to be "string"?  
> Wildcards don't work in "properties", and setting "type" : "string" in the  
> foo.json caused an error on insert, I assume because the "size" field I'm  
> inserting is not a string:
> 
> {"error":"MapperParsingException[mapping [_default_]]; nested:  
> MapperParsingException[Trying to parse an object but has a different type  
> [string] for [_default_]]; ","status":400}
> 
> Thanks,  
> Jamshid
> 
> --  
> You received this message because you are subscribed to the Google Groups  
> "elasticsearch" group.  
> To unsubscribe from this group and stop receiving emails from it, send an  
> email to [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
> For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

--  
You received this message because you are subscribed to the Google Groups "elasticsearch" group.  
To unsubscribe from this group and stop receiving emails from it, send an email to [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<div class="post-metadata">

**Author:** ![Jamshid](https://avatars.discourse-cdn.com/v4/letter/j/ecd19e/32.png) [@Jamshid](https://discuss.elastic.co/u/Jamshid)\
**Post date:** [April 17, 2013, 9:51pm UTC](https://discuss.elastic.co/t/force-default-type-of-new-fields-to-be-string/11618/3 "2013-04-17T21:51:04Z")

</div>

Thanks, Ivan, yes that is exactly what I need. Had trouble figuring out  
where to merge "dynamic\_templates" into my existing  
elasticsearch-0.19.3/config/templates/foo.json, but finally got it:

{  
"foo\_template" : {  
"template" : "_",  
"settings" : {  
"index.number\_of\_shards" : 3,  
"index.number\_of\_replicas" : 1  
},  
"mappings" : {  
"default" : {  
"\_source" : { "enabled" : true,  
"compress" : true },  
"\_all" : { "enabled" : false },  
"\_timestamp" : { "enabled" : true,  
"store" : true },  
"analyzer" : "keyword",  
"dynamic\_templates" : [ {  
"thisnamedoesnotmatter": {  
"match" : "x_",  
"mapping" : {  
"type": "string",  
"analyzer": "keyword"  
}  
}  
} ],  
"properties" : {  
"name" : { "type" : "string", "analyzer" : "keyword" },  
"size" : { "type" : "long" }  
}  
}  
}  
}  
}

Now size remains a "long" but other fields are forced to "string",  
regardless of the type of of the first value submitted.

curl -XDELETE '[http://localhost:9200/test](http://localhost:9200/test)'  
curl -XPOST '[http://localhst:9200/test/123](http://localhst:9200/test/123)' -d '{ "name" : "test",  
"x-foo-meta" : "2013-01-01", "size" : "1" }'  
curl -XGET '[http://localhost:9200/test/\_mapping](http://localhost:9200/test/_mapping)'

--Jamshid

On Wednesday, April 17, 2013 1:57:14 PM UTC-5, Ivan Brusic wrote:

> Dynamic templates is what you are looking for:  
> [Elasticsearch Platform — Find real-time answers at scale | Elastic](http://www.elasticsearch.org/guide/reference/mapping/root-object-type/)
> 
> Looking for dynamic\_templates toward the bottom. That section really  
> should be a standalone page IMHO.
> 
> --  
> Ivan
> 
> On Wed, Apr 17, 2013 at 11:47 AM, Jamshid \<[jams...@gmail.com](mailto:jams...@gmail.com) \<javascript:\>
> 
> > wrote:
> 
> > Hi, I'm currently setting the type of the "known" fields in my index via  
> > elasticsearch-0.19.3/config/templates/foo.json:
> > 
> > {  
> > "foo\_template" : {  
> > "template" : "\*",  
> > "settings" : {  
> > "index.number\_of\_shards" : 3,  
> > "index.number\_of\_replicas" : 1  
> > },  
> > "mappings" : {  
> > "_default_" : {  
> > "\_source" : { "enabled" : true,  
> > "compress" : true },  
> > "\_all" : { "enabled" : false },  
> > "\_timestamp" : { "enabled" : true,  
> > "store" : true },  
> > "analyzer" : "keyword",  
> > "properties" : {  
> > "name" : { "type" : "string", "analyzer" : "keyword"  
> > },  
> > "size" : { "type" : "long" }  
> > }  
> > }  
> > }  
> > }  
> > }
> > 
> > Problem is that I also index user-supplied fields, but don't know the  
> > names of the field beforehand. E.g.:
> > 
> > $ curl -XPOST '[http://localhost:9200/test/123](http://localhost:9200/test/123)' -d '{ "name" : "test", _"x-foo-meta"  
> > : "2013-01-01"_, "size" : 1 }'
> > 
> > But I don't want "x-foo-meta" type to ever be date, only string. If the  
> > first insert happens to contain a value that looks like a date then the  
> > mapping for the field is permanently set to date:
> > 
> > $ curl -XGET '[http://localhost:9200/test/\_mapping](http://localhost:9200/test/_mapping)'
> > 
> > {"test":{"123":{"analyzer":"keyword","\_all":{"enabled":false},"\_timestamp":{"store":"yes","enabled":true},"\_source":{"compress":true},"properties":{"name":{"type":"string","analyzer":"keyword"},"size":{"type":"long"},  
> > _"x-foo-meta":{"type":"date"_  
> > ,"format":"dateOptionalTime"}}},"_default_":{"analyzer":"keyword","\_all":{"enabled":false},"\_timestamp":{"store":"yes","enabled":true},"\_source":{"compress":true},"properties":{"name":{"type":"string","analyzer":"keyword"},"size":{"type":"long"}}}}}
> > 
> > If I try to insert a non-date value I get an error:
> > 
> > $ curl -XPOST '[http://localhost:9200/test/123](http://localhost:9200/test/123)' -d '{ "name" : "test", _"x-foo-meta"  
> > : "x2013-01-01"_, "size" : 1 }'  
> > {"error":"MapperParsingException[Failed to parse [x-foo-meta]]; nested:  
> > MapperParsingException[failed to parse date field [x2013-01-01], tried both  
> > date format [dateOptionalTime], and timestamp number]; nested:  
> > IllegalArgumentException[Invalid format: "x2013-01-01"]; ","status":400}
> > 
> > So, how can I force the type of all unspecified fields to be "string"?  
> > Wildcards don't work in "properties", and setting "type" : "string" in the  
> > foo.json caused an error on insert, I assume because the "size" field I'm  
> > inserting is not a string:
> > 
> > {"error":"MapperParsingException[mapping [_default_]]; nested:  
> > MapperParsingException[Trying to parse an object but has a different type  
> > [string] for [_default_]]; ","status":400}
> > 
> > Thanks,  
> > Jamshid
> > 
> > --  
> > You received this message because you are subscribed to the Google Groups  
> > "elasticsearch" group.  
> > To unsubscribe from this group and stop receiving emails from it, send an  
> > email to [elasticsearc...@googlegroups.com](mailto:elasticsearc...@googlegroups.com) \<javascript:\>.  
> > For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

--  
You received this message because you are subscribed to the Google Groups "elasticsearch" group.  
To unsubscribe from this group and stop receiving emails from it, send an email to [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 6, 2017, 2:40am UTC](https://discuss.elastic.co/t/force-default-type-of-new-fields-to-be-string/11618/4 "2017-07-06T02:40:43Z")

</div>


