Saturday, May 26, 2018

Elasticsearch High Level Rest Client - java Map with typed (sub) fields - dates, numbers etc

Leave a Comment

(clarification copied from a comment)

I have a java.util.Map that has different key value pairs, and some of the values are dates, some numbers, some are strings, and some are also java.util.Maps that can also contain all kinds of above mentioned types. I am able to put it into the index, I see that the elasticsearch mapping is created automatically with correct field types, now I want to retrieve that Map and see dates, numbers, strings and nested Maps instead of what I currently have - just strings and Maps

Further story:

I'm putting a java.util.Map in Elasticsearch using the following code:

public void putMap(String key, Map<String, ?> value) {     try {         IndexRequest ir = Requests.indexRequest(_index)                 .id(key)                 .type("doc")                 .source(value);          Factory.DB.index(ir); // the high level rest client here      } catch (IOException ex) {         throw new RuntimeException(ex);     } } 

I am not able to create mappings explicitly as per my task.

For one of my indices it has created the mapping like this, which is quite fine:

{ "rex": { "mappings": {   "doc": {     "properties": {       "variables": {         "properties": {           "customer": {             "properties": {               "accounts": {                 "properties": {                   "dateOpen": {                     "type": "date"                   },                   "id": {                     "type": "text",                     "fields": {                       "keyword": {                         "type": "keyword",                         "ignore_above": 256                       }                     }                   }                 }               },               "dateOfBirth": {                 "type": "date"               },               "firstName": {                 "type": "text",                 "fields": {                   "keyword": {                     "type": "keyword",                     "ignore_above": 256                   }                 }               },               "id": {                 "type": "text",                 "fields": {                   "keyword": {                     "type": "keyword",                     "ignore_above": 256                   }                 }               },                "lastName": {                 "type": "text",                 "fields": {                   "keyword": {                     "type": "keyword",                     "ignore_above": 256                   }                 }               },               "middleName": {                 "type": "text",                 "fields": {                   "keyword": {                     "type": "keyword",                     "ignore_above": 256                   }                 }               }             }           }         }       }     }   } } } } 

Now I am retrieving my structure back with the following code,

public Map<String, ?> getMap(String key) {     try {          GetRequest gr = new GetRequest(_index, "doc", key);          try {             GetResponse response = Factory.DB.get(gr);              if (!response.isExists()) {                 return null;             }              Map<String, ?> ret = response.getSourceAsMap();              return ret;         } catch (ElasticsearchStatusException ee) {             if (ee.status().getStatus() == RestStatus.NOT_FOUND.getStatus()) {                 return null;             } else {                 throw new RuntimeException(ee);             }         }      } catch (IOException ex) {         throw new RuntimeException(ex);     } } 

The dates are returned as strings like "1957-04-29T00:00:00.000Z"

There's no Java object to map this document to as I have only Maps of Maps/Lists/values.

How do I make the Java Rest Client respect the mapping the Elasticsearch created for the index? response.getFields() returns empty map.

In case it is impossible (like 'source is json/strings by design' etc etc), I am ready to retrieve the mapping in the most convenient form possible and walk through the result by myself. The code to retrieve elasticsearch mapping will be appreciated.

Big thank you!

0 Answers

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment