Elasticsearch Java API查询JSON解析器

3

我有一个 Elasticsearch 数据库,用于存储联系人。我执行以下查询:

 public String getAllContacts() throws IOException {

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

    return response.toString();
}

那么我得到了这样的结果:查询得到的Json结果

然后我想将Json数据放入我的联系人类对象中。

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; }
}

后来我尝试使用以下代码将JSON映射到对象,但是出现了错误。
    ObjectMapper mapper = new ObjectMapper();
    List<Contact> myObjects = mapper
.readValue(response.toString(), mapper
.getTypeFactory()
.constructCollectionType(List.class, Contact.class));

许多错误之一

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

所以我认为问题在于查询中获取的其他内容。如果我得到一个干净的JSON,像这样{"id":"2","name";"dinu"},它可以工作(我手动测试过),但它会带来许多其他东西,例如JSON文件的顶部部分(头部元数据)(请检查上面的JSON结果图像)。
所以我认为我有两个选择:- 选项1:从elasticsearch DB获取干净的结果,因此需要修改搜索查询。我不知道这是否在elasticsearch中可能。如果可以,请有人建议如何修改查询(在java API中)。 选项2:过滤JSON文件并删除所有不需要的内容,然后将其转换为Contact对象。我尝试过GSON和jackson,但都无法处理未经过滤的文件。如果有任何高级或自定义的过滤方法,请告诉我。 选项3:我完全错了,有更好、更容易的方法。请告诉我。

更新 观看此视频:- https://www.youtube.com/watch?v=YgKcVBbvy2U

我尝试了使用GSON进行序列化的上述方法。

然后异常不会出现,但是在序列化后,我得到的响应是“Unexpected 'd'”,而在原始格式中,每次发送GET响应后,它都会输出这个dinu.model.HitsObject @6c79684b,@符号后面的文本会更改。

3个回答

6
您需要对搜索结果进行迭代并反序列化数值。
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);
}

如果您需要将其再次序列化为JSON列表,您可以简单地获取为JSON。
String lstString = mapper.writeValueAsString(lst);

上述提到的ObjectMapper来自jackson数据绑定库。相比Gson,它更加出色。

import com.fasterxml.jackson.databind.ObjectMapper;

0

不确定这是否有助于您找到所需的内容。我只是将您的字符串添加到文本文件中。

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}]

您可能会编写一个方法,通过遍历JSON数组来为相应的对象设置值。


0
从响应的JSON中,hits:标签应该是包含属性index、type、id、score、source等的列表。请尝试检索包含联系人对象的hits列表对象。

我想要做的是移除命中列表对象,仅以JSON格式获取联系人数据。 - Dinushka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接