Search code examples
javajsonelasticsearchtimestampelasticsearch-jest

JestResult.getSourceAsObjectList - for "@timestamp" or seemingly any field starting with "@"


How would JestResult.getSourceAsObjectList be used to map the field "@timestamp"? Actually, I cannot figure out how to map any field with a name starting with "@". It keeps getting set to "null".

For example if the Elasticsearch query returns

{
    "_id": "Vhv2OE1SNSeSg285UYQRQ",
    "@version": "1",
    "@timestamp": "2014-12-19T01:18:06.454Z"
    "type": "hdfs"
}

and there is a matching POJO Java class

import io.searchbox.annotations.JestId;

public class ElasticsearchLog {

    @JestId
    private String _id;
    private String version;
    private String timestamp;
    private String type;

    @Override
    public String toString() {
        return "ElasticsearchLog{" +
                "_id='" + _id + '\'' +
                ", version='" + version + '\'' +
                ", timestamp='" + timestamp + '\'' +
               ", type='" + type + '\''
            '    }';

}

Then doing

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.Search;
import java.util.List;

public class JESTClient {
    public static void main(String[] args) throws Exception {
        String clusterIP = "localhost";
        String port = "9200";

        //setup client
        JestClientFactory factory = new JestClientFactory();
        factory.setHttpClientConfig(new HttpClientConfig
                .Builder("http://" + clusterIP + ":" + port)
                .multiThreaded(true)
                .build());
        JestClient client = factory.getObject();

        Search search = new Search.Builder("{  \"query\": { \"match_all\": {} } }")
                .addIndex("_all")
                .build();
        JestResult result = client.execute(search);
        List<ElasticsearchLog> resultLogs = result.getSourceAsObjectList(ElasticsearchLog.class);
        for(ElasticsearchLog log: resultLogs){
            System.out.println(log);
        }

Prints out

ElasticsearchLog{_id='Vhv2OE1SNSeSg285UYQRQ', version='null', timestamp='null', type='hdfs'}

So the "@version" and "@timestamp" are not getting mapped properly.

JsonObject itself seems to be just fine with "@" symbols:

import com.google.gson.JsonObject;

public static void main(String[] args){
        JsonObject testy = new JsonObject();
        testy.addProperty("@timestamp", "zzz");
        System.out.println(testy.get("@timestamp"));
}

Outputs: "zzz"

What is the proper usage of JestResult. getSourceAsObjectList to map a json field with a name starting with "@"?

Note: This is for

<dependency>
    <groupId>io.searchbox</groupId>
    <artifactId>jest</artifactId>
    <version>0.1.4</version>
</dependency>

Solution

  • Searchly support to the rescue!

    Email response from [email protected]

    Ferhat Sobay replied:

    Problem in here is @version requires a Java field as '@version' which is not possible with Java lang. @SerializedName annotation comes to rescue, had to dig a little but works!

    So try below;

    public class ElasticsearchLog {
    
      @JestId
      private String _id;
      @SerializedName("@version")
      private String version;
      @SerializedName("@timestamp")
      private String timestamp;
      private String type;
    
      @Override
      public String toString() {
      return "ElasticsearchLog{" +
      "_id='" + _id + '\'' +
      ", version='" + version + '\'' +
      ", timestamp='" + timestamp + '\'' +
      ", type='" + type + '\''
      ' }';
    
    }
    

    Best, @Ferhat