Клиент Elasticearch Client высокого уровня - java Карта с введенными (подпольными) полями - датами, цифрами и т.д.
(уточнение скопировано из комментария)
У меня есть java.util.Map
, у которого разные пары значений, а некоторые из них - даты, некоторые числа, некоторые - строки, а некоторые - также java.util.Map
которые также могут содержать все типы вышеупомянутых типов. Я могу поместить его в индекс, я вижу, что сопоставление elasticsearch создается автоматически с правильными типами полей, теперь я хочу получить эту Map
и увидеть даты, числа, строки и вложенную Map
вместо того, что у меня есть сейчас - просто строки и Карты
Дальнейшая история:
Я помещаю java.util.Map
в Elasticsearch, используя следующий код:
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);
}
}
Я не могу создавать сопоставления явно в соответствии с моей задачей.
Для одного из моих индексов он создал такое сопоставление, что довольно хорошо:
{
"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
}
}
}
}
}
}
}
}
}
}
}
}
Теперь я возвращаю свою структуру со следующим кодом,
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);
}
}
Даты возвращаются в виде строк, таких как "1957-04-29T00: 00: 00.000Z"
Нет объекта Java для сопоставления этого документа, поскольку у меня есть только Карты карт/Списки/значения.
Как заставить клиента оставления Java соблюдать сопоставление Elasticsearch, созданного для индекса? response.getFields()
возвращает пустую карту.
В случае, если это невозможно (например, "source is json/strings by design" и т.д. И т.д.), Я готов получить отображение в наиболее удобной форме и пропустить результат самостоятельно. Будет оценен код для извлечения карт elasticsearch.
Большое спасибо!
Ответы
Ответ 1
Если вы все еще хотите получить сопоставление типов и выполнить преобразование вручную, в API-интерфейсе индексов есть команда Get Mapping, которую вы можете вызвать с клиентом REST низкого уровня Java.
String getMapping(RestHighLevelClient client, String index, String type) throws IOException {
String endpoint = index + "/_mapping/" + type;
Response response = client.getLowLevelClient().performRequest("GET", endpoint);
return EntityUtils.toString(response.getEntity());
}
Но на самом деле я бы рекомендовал вместо этого использовать что-то вроде Jackson для привязки данных. Привяжите Map
вы получаете от Elasticsearch, к объекту Java, который моделирует документ, и пусть Jackson обрабатывает преобразование типа для вас.