wxkevin wxkevin - 5 months ago 181
JSON Question

Using Jest or Java API is there a way to tell Elasticsearch to create documents from json as a String?

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.

Answer

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.

Comments