Введение в Spring Data Elasticsearch

Введение в Spring Data Elasticsearch

1. обзор

В этой статьеwe’ll explore the basics of Spring Data Elasticsearch в практической манере, ориентированной на код.

Мы покажем, как индексировать, искать и запрашивать Elasticsearch в приложении Spring, используя Spring Data - модуль Spring для взаимодействия с популярной поисковой системой на основе Lucene с открытым исходным кодом.

В то время как Elasticsearch не имеет схемы, он может использовать сопоставления для определения типа поля. Когда документ проиндексирован, его поля обрабатываются в соответствии с их типами. Например, текстовое поле будет размечено и отфильтровано в соответствии с правилами отображения. Вы также можете создавать собственные фильтры и токенизаторы.

2. Spring Data

Spring Data помогает избежать шаблонного кода. Например, если мы определим интерфейс репозитория, который расширяет интерфейсElasticsearchRepository, предоставляемый Spring Data, Elasticsearch, операции CRUD, для соответствующего класса документов будут доступны по умолчанию.

Кроме того, просто объявляя методы с именами в предписанном формате, реализации методов создаются для вас - нет необходимости писать реализацию интерфейса репозитория.

Вы можете узнать больше о Spring Datahere.

2.1. Maven Dependency

Spring Data Elasticsearch предоставляет Java API для поисковой системы. Чтобы использовать его, нам нужно добавить новую зависимость кpom.xml:


    org.springframework.data
    spring-data-elasticsearch
    3.0.8.RELEASE

2.2. Определение интерфейсов репозитория

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

Обратите внимание, чтоElasticsearchRepository расширяетPagingAndSortingRepository, что обеспечивает встроенную поддержку нумерации страниц и сортировки.

В нашем примере мы будем использовать функцию подкачки в нашем пользовательском методе поиска:

public interface ArticleRepository extends ElasticsearchRepository {

    Page
findByAuthorsName(String name, Pageable pageable); @Query("{\"bool\": {\"must\": [{\"match\": {\"authors.name\": \"?0\"}}]}}") Page
findByAuthorsNameUsingCustomQuery(String name, Pageable pageable); }

Обратите внимание, что мы добавили два пользовательских метода. С помощью методаfindByAuthorsName прокси-сервер репозитория создаст реализацию на основе имени метода. Алгоритм разрешения определит, что ему нужен доступ к свойствуauthors, а затем выполнит поиск в свойствеname каждого элемента.

Второй метод,findByAuthorsNameUsingCustomQuery, использует логический запрос Elasticsearch, определенный с помощью аннотации@Query, которая требует строгого соответствия между именем автора и предоставленным аргументомname.

2.3. Конфигурация Java

Давайте теперь рассмотрим конфигурацию Spring нашего слоя постоянства здесь:

@Configuration
@EnableElasticsearchRepositories(basePackages = "com.example.spring.data.es.repository")
@ComponentScan(basePackages = { "com.example.spring.data.es.service" })
public class Config {

    @Value("${elasticsearch.home:/usr/local/Cellar/elasticsearch/5.6.0}")
    private String elasticsearchHome;

    @Value("${elasticsearch.cluster.name:elasticsearch}")
    private String clusterName;

    @Bean
    public Client client() {
        Settings elasticsearchSettings = Settings.builder()
          .put("client.transport.sniff", true)
          .put("path.home", elasticsearchHome)
          .put("cluster.name", clusterName).build();
        TransportClient client = new PreBuiltTransportClient(elasticsearchSettings);
        client.addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
        return client;
    }

    @Bean
    public ElasticsearchOperations elasticsearchTemplate() {
        return new ElasticsearchTemplate(client());
    }
}

Обратите внимание, что мы используем стандартную аннотацию в стиле Spring enable -@EnableElasticsearchRepositories - для сканирования предоставленного пакета репозиториев Spring Data.

Мы также определяем простойTransport Client:

  1. Мы включаем функцию сниффинга для нашего клиента, используя «client.transport.sniff»

  2. Мы также предоставляем каталог установки Elasticsearch, используя «path.home»

  3. Если имя кластера не «эластичный поиск», мы должны предоставить его, используя «имя кластера».

Наконец, мы также настраиваем bean-компонентElasticsearchOperations -elasticsearchTemplate - в качестве нашего клиента для работы с сервером Elasticsearch.

3. Отображения

Теперь давайте определим нашу первую сущность - документ с именемArticle со строкойid:

@Document(indexName = "blog", type = "article")
public class Article {

    @Id
    private String id;

    private String title;

    @Field(type = FieldType.Nested, includeInParent = true)
    private List authors;

    // standard getters and setters
}

Обратите внимание, что в аннотации@Document мы указываем, что экземпляры этого класса должны храниться в Elasticsearch в индексе с именем «blog» и с типом документа «article». Документы с множеством разныхtypes могут храниться в одном и том жеindex.

Также обратите внимание, что полеauthors помечено какFieldType.Nested. Это позволяет нам определять классAuthor отдельно, но иметь отдельные экземпляры автора, встроенные в документArticle, когда он индексируется в Elasticsearch.

4. Индексирование документов

Spring Data Elasticsearch обычно автоматически создает индексы на основе сущностей в проекте.

Однако вы также можете создать индекс программно через шаблон клиента:

elasticsearchTemplate.createIndex(Article.class);

После того, как индекс будет доступен, мы можем добавить документ в индекс.

Давайте быстро рассмотрим пример - индексацию статьи с двумя авторами:

Article article = new Article("Spring Data Elasticsearch");
article.setAuthors(asList(new Author("John Smith"), new Author("John Doe")));
articleService.save(article);

5. Запросы

5.1. Запрос на основе имени метода

Класс репозитория, который мы определили ранее, имел методfindByAuthorsName, который мы можем использовать для поиска статей по имени автора:

String nameToFind = "John Smith";
Page
articleByAuthorName = articleService.findByAuthorName(nameToFind, PageRequest.of(0, 10));

ВызываяfindByAuthorName с объектомPageRequest, мы получаем первую страницу результатов (нумерация страниц отсчитывается от нуля), причем эта страница содержит не более 10 статей.

5.2. Пользовательский запрос

Существует несколько способов определения пользовательских запросов для репозиториев Spring Data Elasticsearch. Один из способов - использовать аннотацию@Query, как показано в разделе 2.2.

Другой вариант - использовать конструктор для создания пользовательских запросов.

Например, мы могли бы искать статьи, в названии которых есть слово «data», создав запрос сNativeSearchQueryBuilder:

SearchQuery searchQuery = new NativeSearchQueryBuilder()
  .withFilter(regexpQuery("title", ".*data.*"))
  .build();
List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);

6. Обновление и удаление

Чтобы обновить или удалить документ, нам сначала нужно получить этот документ.

String articleTitle = "Spring Data Elasticsearch";
SearchQuery searchQuery = new NativeSearchQueryBuilder()
  .withQuery(matchQuery("title", articleTitle).minimumShouldMatch("75%"))
  .build();

List
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);

Теперь, чтобы обновить заголовок статьи - мы можем изменить документ и использовать APIsave:

article.setTitle("Getting started with Search Engines");
articleService.save(article);

Как вы уже догадались, для удаления документа можно использовать методdelete:

articleService.delete(articles.get(0));

7. Заключение

Это было быстрое и практическое обсуждение базового использования Spring Data Elasticsearch.

Чтобы узнать больше о впечатляющих функциях Elasticsearch, вы можете найти егоdocumentation на официальном сайте.

Пример, использованный в этой статье, доступен какsample project in GitHub.

Related