【问题标题】:Jest getSourceAsObject always returns NULL开玩笑 getSourceAsObject 总是返回 NULL
【发布时间】:2015-04-20 18:59:42
【问题描述】:

我正在尝试来自Jest 的几个示例,以用作 ElasticSearch 集成的 POC。

现在,我正在尝试一个基本的 GET。我创建了一个名为 Document 的 POJO。其中有一些基本的 setter 和 getter 是一些字段。我填充它,然后使用 GSON 生成 JSON 文本。

从这个生成的 JSON 中,我进入 ElasticSearch Sense 并执行以下操作:

PUT /reports/documents/3
{
    // JSON code
}

这生成就好了。然后我尝试使用 Get 从 Java 中提取值,如下所示:

JestClientFactory factory = new JestClientFactory();

factory.setHttpClientConfig(new HttpClientConfig
                            .Builder("http://localhost:9200")
                            .multiThreaded(true)
                            .build());

client = factory.getObject();

Get get = new Get.Builder("reports", "3").type("documents").build();

try {
    JestResult result = client.execute(get);
    String json = result.getJsonString();
    System.out.println(json);

    Document doc = null; 
    doc = result.getSourceAsObject(Document.class);
    System.out.println("is doc null? " + doc == null);
}catch (Exception e) {
    System.err.println("Error getting document");
    e.printStackTrace();
}

字符串json 返回我所期望的(显示_index、_type、_id,当然还有_source)。但是,doc 始终显示为 NULL。我不确定为什么会这样。

为了看看这是否只是一个Get问题,我继续尝试搜索。我做了以下代码sn-p:

try {
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.query(QueryBuilders.matchQuery("reportNumber", "101221895CRT-004"));

    Search search = new Search.Builder(searchSourceBuilder.toString())
                                        // multiple index or types can be added.
                                        .addIndex("reports")
                                        .addType("documents")
                                        .build();

    SearchResult result = client.execute(search);

    //List<Document> results = result.getSourceAsObjectList(Document.class);

    List<SearchResult.Hit<Document, Void>> hits = result.getHits(Document.class);

    for (SearchResult.Hit hit : hits) {
        Document source = (Document) hit.source;
        Void ex = (Void) hit.explanation;

        System.out.println();
    }

    System.out.println("Result size: " + hits.size());
}catch (Exception e) {
    System.err.println("Error searching");
    e.printStackTrace();
}

查看result 时,会显示对象的JSON。但是,List&lt;Document&gt; results 显示为 NULL。使用hits时,命中的大小是正确的,但是“source”和“ex”都是NULL。

关于我做错了什么有什么想法吗?

更新
在阅读了 Cihat 的评论后,我继续添加了日志记录。事实证明,在尝试转换日期时出现错误(因此它总是返回为 NULL)。

我收到以下错误消息:

Unhandled exception occurred while converting source to the object .com.someCompanyName.data.Document
com.google.gson.JsonSyntaxException: java.text.ParseException: Unparseable date: "Nov 6, 2014 8:29:00 AM"

我尝试了所有不同的格式:

  • 2014 年 11 月 6 日上午 8:29:00(没有时间,一年只有 14)
  • 2014 年 11 月 6 日上午 8:29:00(没有时间,也没有使年份只有 14)
  • 2014-11-06 8:29:00 AM(时间和年份变化相同)
  • 2014-NOV-06 8:29:00 AM(时间和年份变化相同)
  • 2014 年 6 月 11 日上午 8:29:00(同样的事情)

所有这些都失败了。我确定我尝试了其他一些格式,所以不确定日期应该是什么格式。我什至尝试了来自DateFormat JavaDocs 的确切日期,但它仍然失败。每次我进行搜索时,它都会说要在 GsonBuilder 中定义 Dateformat,但在 Jest 中我无权访问它。

【问题讨论】:

  • 你的 JSON 结构是什么样的? DocumentSTDocument 的定义在哪里?你看过日志吗(也许在 jest 包上启用调试级别日志记录)?
  • 我写了一个快速测试用例,它使用 Jest 来索引一个文档,然后使用getSourceAsObject 来访问它。那工作正常。这可能是 GSON 和您的 Document 类的问题。
  • @CihatKeser - 感谢您对日志记录的建议。我添加了它并相应地更新了问题。
  • 你可能想看看这个test case
  • Jest(以及 希望 ES)使用的默认日期时间格式是 ISO 8601 组合日期+时间格式(即:yyyy-MM-dd'T'HH:mm:ssZ);如果您需要任何其他格式,那么您应该将其设置在 gson 实例上,正如 C.Trimble 指出的那样。还有它的价值:在即将到来的版本中,这些反序列化异常不会像这里那样被吞没并丢失在日志中:)

标签: java json elasticsearch elasticsearch-jest


【解决方案1】:

这个测试用例演示了使用 Jest 对文档进行索引,然后获取相同的文档。不是一个完整的答案,但希望看到一些已知有效的东西是有用的。

import io.searchbox.client.JestClient;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.JestResult;
import io.searchbox.client.config.HttpClientConfig;
import io.searchbox.core.Get;
import io.searchbox.core.Index;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.*;
import org.junit.Test;

public class JestRoundtripIT {

  public static final String INDEX = "reports";
  public static final String TYPE = "documents";
  public static final String ID = "3";

  @Test
  public void documentRoundTrip() throws Exception {
    JestClientFactory factory = new JestClientFactory();

    factory.setHttpClientConfig(new HttpClientConfig
                                .Builder("http://localhost:9200")
                                .multiThreaded(true)
                                .build());

    JestClient client = factory.getObject();

    Document original = new Document()
      .withAuthor("Shay Banon")
      .withContent("You know, for search...");

    JestResult indexResult = client.execute(
      new Index.Builder(original)
        .index(INDEX)
        .type(TYPE)
        .id(ID)
        .build());
    assertThat(indexResult.isSucceeded(), equalTo(true));

    JestResult getResult = client.execute(
      new Get.Builder(INDEX, ID)
      .type(TYPE)
      .build());
    assertThat(getResult.isSucceeded(), equalTo(true));

    Document fromEs = getResult.getSourceAsObject(Document.class);

    assertThat(fromEs, notNullValue());
    assertThat(fromEs.getAuthor(), equalTo(original.getAuthor()));
    assertThat(fromEs.getContent(), equalTo(original.getContent()));
  }

  public static class Document {
    protected String author;
    protected String content;
    public Document withAuthor( String author ) {
      this.author = author;
      return this;
    }

    public Document withContent( String content ) {
      this.content = content;
      return this;
    }

    public String getAuthor() {
      return author;
    }

    public void setAuthor( String author ) {
      this.author = author;
    }

    public String getContent() {
      return content;
    }

    public void setContent( String content ) {
      this.content = content;
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 2020-10-24
    • 2017-09-11
    • 1970-01-01
    • 2018-11-30
    • 1970-01-01
    • 2021-09-11
    相关资源
    最近更新 更多