I am trying to use the Elasticsearch Java API to dynamically create mappings. This is important because I don't want to have to change compiled code to change the mapping.
Almost all of the examples out there are using XContentBuilder
to do this, but I want to use a JSON string from a file.
Code:
client.admin().indices().preparePutMapping(indexName)
.setType("test")
.setSource(indexMapping)
.execute().actionGet();
File String:
{
"test": {
"dynamic": "strict",
"_id": {
"path": "id"
},
"properties": {
"address": {
"index_analyzer": "ip4-pattern-analyzer",
"store": true,
"type": "string",
"fields": {
"raw": {
"index": "not_analyzed",
"type": "string"
}
}
}
}
}
}
Error thrown from Elasticsearch PutMappingRequest.class
:
failed to generate simplified mapping definition
The same JSON defined using XContentbuilder
works perfectly.
String type = "test";
XContentBuilder jb = XContentFactory.jsonBuilder().
startObject().
startObject(type).
field("dynamic", "strict").
startObject("_id").
field("path", "id").
endObject().
startObject("_all").
field("enabled", "true").
endObject().
startObject("properties").
startObject("address").
field("type", "string").
field("store", "yes").
field("index_analyzer", "ip4-pattern-analyzer").
startObject("fields").
startObject("raw").
field("type","string").
field("index","not_analyzed").
endObject().
endObject().
endObject().
endObject().
endObject().
endObject();
I couldn't ever get it to work using anything other than an XContentBuilder. I decided to convert the json to a map using Jackson, then map the object using the XContentFactory.jsonBuilder(). I then pass the XContentBuilder directly to the putMapping call.
public static XContentBuilder builderFromJson(String json) throws JsonParseException, JsonMappingException, IOException{
Map<String, Object> map = new ObjectMapper().readValue(json, new TypeReference<Map<String, Object>>(){});
return XContentFactory.jsonBuilder().map(map);
}