Dinushka
Dinushka

Reputation: 118

Elasticsearch Java api query JSON parser

So i'm having a elasticsearch database, which i used to store Contacts. i do the below query.

 public String getAllContacts() throws IOException {

    SearchResponse response = client.prepareSearch("contact").get();

    return response.toString();
}

so then i get a result like this Json result from query

then i want to put the Json data in to my Contact class objects

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Date;
@JsonIgnoreProperties(ignoreUnknown = true)
@XmlRootElement
public class Contact {

    private long id;
    private String name;
    private Date date;

    public Contact() {}
    public Contact(long id, String name, Date date) {
        this.id = id;
        this.name = name;
        this.date = date;
    }
    public long getId() {return id;}
    public void setId(long id) {this.id = id;}
    public String getName() { return name;}
    public void setName(String name) {this.name = name;}
    public Date getDate() { return date; }
    public void setDate(Date date) { this.date = date; }
}

later i But when i try to map the JSON to object using below code i get errors

    ObjectMapper mapper = new ObjectMapper();
    List<Contact> myObjects = mapper
.readValue(response.toString(), mapper
.getTypeFactory()
.constructCollectionType(List.class, Contact.class));

one of many errors

Can not deserialize instance of java.util.ArrayList out of START_OBJECT token

so the problem i think is all the other stuff which comes from the query if I get a clean JSON like this {"id":"2","name";"dinu"} it works (i did test it manually) but it comes with many other stuff such as the top part of the JSON file(header meta data) (check the above JSON result image).

so i think i have 2 options:-

Option 1 :- get a clean result from elasticsearch DB, so i need to modify the search query. i don't know if that is even possible with elasticsearch. if so can someone make suggestion on how to modify the query (in java API).

Option 2 :- filter out the JSON file and remove all unwanted stuff and then make it into Contact object. i tried GSON and jackson both failed with the unfiltered file. If there is any advance or custom way to filter out let me know.

Option 3 :- i'm totally wrong and there is a better easy way to do it.Please let me know.

UPDATE Watch THIS :- https://www.youtube.com/watch?v=YgKcVBbvy2U

so i tried the above way using GSON to Serialize

then exceptions are not coming but i get the responds after serialization as "Unexpected 'd'" also in raw formate it outputs this dinu.model.HitsObject@6c79684b everytime i send a GET respond the text after @ symbol changes'.

Upvotes: 3

Views: 5447

Answers (3)

raslan
raslan

Reputation: 94

You need to perform an iteration over search hits and de-serialize value.

SearchResponse response = client.prepareSearch("contact").get();
ObjectMapper mapper = new ObjectMapper();
List<Contact> lst = new ArrayList<Contact>();
for(SearchHit hit : response.getHits().getHits()) {
    Contact c = mapper.readValue(hit.getSourceAsString(), Contact.class);
    lst.add(c);
}

If you need to again serialize it as a json list you can simply get as JSON

String lstString = mapper.writeValueAsString(lst);

Above mentioned ObjectMapper is from jackson data-binding library. It’s pretty nice than Gson

import com.fasterxml.jackson.databind.ObjectMapper;

Upvotes: 6

Anup
Anup

Reputation: 1

Not sure whether this helps to get what you are looking for. I just added your string to a text file

Object obj = new JSONParser().parse(new FileReader("data.txt"));

    // typecasting obj to JSONObject
    JSONObject jo = (JSONObject) obj;

    // getting hits
    Map hits = ((Map)jo.get("hits"));
    JSONArray array = null;
    // iterating hits Map
    Iterator<Map.Entry> itr1 = hits.entrySet().iterator();
    while (itr1.hasNext()) {
        Map.Entry pair = itr1.next();
        System.out.println(pair.getKey() + " : " + pair.getValue());
       if(pair.getKey().equals("hits")){
           array = (JSONArray) pair.getValue();

       }
    }

    System.out.println(array);

[{"_index":"contact","_type":"id","_id":2,"_score":1},{"_index":"contact","_type":"id","_id":4,"_score":1}]

you can probably write a method which can set values to the corresponding objects by iterating the JSON Array

Upvotes: 0

Anup
Anup

Reputation: 1

From the response JSON, the hits: tag should be the list which contains the attributes index,type,id,score,source..etc. Please try to retrieve the hits list object which contains the objects which has the contact

Upvotes: 0

Related Questions