Статьи

Простой способ индексирования Java-бинов в Elasticsearch

Когда дело доходит до хранилищ данных, Java-программисты привыкли работать с Java-бинами, которые волшебным образом сохраняются. Такие примеры, как Hibernate и спецификация JPA для хранилищ реляционных данных или Morphia и Spring Data MongoDB, являются популярными примерами.

У разработчиков, работающих с Elasticsearch, иногда возникает одно и то же желание — передать Java-бин и автоматически проиндексировать его. Доступна реализация Spring Data для Elasticsearch, но она может оказаться для вас непроизводительной или не поддерживаться вашей версией Elasticsearch. И есть Jest, который использует HTTP API, который поддерживает непосредственное хранение Java Beans.

Если вы хотите сделать то же самое с помощью стандартного Java-клиента для Elasticsearch, прямой поддержки этому нет, но его можно легко реализовать вручную.

Предположим, вы хотите сохранить следующую простую структуру объектов, которая представляет книгу.

1
2
3
4
5
6
7
Publisher publisher = new Publisher();
publisher.setCountry("UK");
publisher.setName("Packt");
Book book = new Book();
book.setTitle("Learning Spring Boot");
book.setAuthors(Arrays.asList("Greg L. Turnquist"));
book.setPublisher(publisher);

Часто случается, что мы так много думаем об одном способе решения проблемы, что не можем увидеть более легкий путь. Нам не нужны специальные рамки для Elasticsearch. Elastcsearch с удовольствием сохранит большинство структур JSON для вас. К счастью, создание документов JSON из объектов Java — это решенная проблема с использованием таких библиотек, как Джексон или GSON .

Мы можем просто добавить зависимость, в данном случае к jackson-databind , в проект, если его там еще нет, и создать экземпляр ObjectMapper.

1
ObjectMapper mapper = new ObjectMapper();

Если вы используете Spring Boot, вы, как правило, сможете просто @Autowire ObjectMapper. Затем ObjectMapper можно использовать для создания JSON-представления объекта.

1
String value = mapper.writeValueAsString(book);

Это приведет к строке, похожей на эту.

1
{"title":"Learning Spring Boot","authors":["Greg L. Turnquist"],"publisher":{"name":"Packt","country":"UK"}}

Затем вы можете проиндексировать результат, используя клиентский интерфейс Elasticsearch.

1
2
3
IndexResponse response = client
        .prepareIndex(indexName, "book")
        .setSource(value).execute().actionGet();

При получении документа вы можете снова создать объекты Java, используя метод readValue.

1
2
3
4
5
6
7
GetResponse getResponse = client
        .prepareGet(indexName, "book", response.getId())
        .execute().actionGet();
String source = getResponse.getSourceAsString();
Book persistedBook = mapper
        .readValue(source, Book.class);
assertEquals("Packt", persistedBook.getPublisher().getName());

Или даже лучше: может быть, вам даже не нужно снова создавать объект Java? Когда вы только отображаете результат в шаблоне, может быть, достаточно просто передать карту полученного документа?

1
2
Map<String, Object> sourceAsMap =
    getResponse.getSourceAsMap();

Иногда мы ищем сложные решения, когда они нам даже не нужны. Поскольку Elasticsearch использует JSON везде, очень легко использовать общие библиотеки для сериализации, будь то на Java или на других языках.

Ссылка: Простой способ индексирования Java Beans в Elasticsearch от нашего партнера JCG Флориана Хопфа в блоге Dev Time .