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.
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.
You might want to try converting your string to a JSON object first, that's probably why you're getting that error. Elasticsearch tries to parse it as an object but finds a string there instead. Maybe do something like:
JSONObject jsonObj = new JSONObject(names);
and then using that object.