Клиент 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 обрабатывает преобразование типа для вас.