Given this POJO:
public class People {
String sex;
long age;
String names;
}
The "names" property will be a json string for which I need to create nested documents for. Here is an example of an instance I need to save to Elasticsearch using Jest Client:
People people = new People();
people.setSex("Male");
people.setAge(21);
people.setNames("[{\"fname\": \"Bob\",\"lname\": \"Smith\"},[{\"fname\": \"Mike\",\"lname\": \"Johnson\"}");
Index index = new Index.Builder(people).index("indexName").type("aType").build();
jestClient.execute(index);
The result document in ES looks like:
"_source" : {
"sex" : "Male",
"age" : 21,
"names" : "[{\"fname\": \"Bob\",\"lname\": \"Smith\"},{\"fname\": \"Mike\",\"lname\": \"Johnson\"}]"
}
So it took the String names and inserted it as a literal String, which makes sense but I actually need to create documents from each name object. In other words I want it to look like this:
"_source" : {
"sex" : "Male",
"age" : 21,
"names" : [{
"fname": "Bob",
"lname": "Smith"
}, {
"fname": "Mike",
"lname": "Johnson"
}]
}
I tried adding a mapping to tell ES to treat it as "nested" but then I get a Mapper Parsing Exception saying "tried to parse field [names] as object, but found a concrete value".
I know I should be able to do this if I create an actual Name POJO object and have a list of them, but unfortunately due to requirements I am unable to do this. I have to use the string of JSON provided in the format specified above.
SOLUTION:
Thanks to Vishal Rao for pointing me in the right direction.
The solution was to change the "names" type to a JsonArray (Google GSON). Then used the Google GSON parser as such:
People people = new People();
people.setSex("Male");
people.setAge(21);
String json = "[{\"fname\": \"Bob\",\"lname\": \"Smith\"},[{\"fname\": \"Mike\",\"lname\": \"Johnson\"}"
JsonParser jsonParser = new JsonParser();
JsonElement jsonElement = jsonParser.parse(json);
JsonArray jsonArray = jsonElement.getAsJsonArray();
people.setNames(jsonArray);
Index index = new Index.Builder(people).index("indexName").type("aType").build();
jestClient.execute(index);
In addition I also have a mapping that sets the names property to a nested type.