Einführung in Spring Data Elasticsearch

Einführung in Spring Data Elasticsearch

1. Überblick

In diesem Artikelwe’ll explore the basics of Spring Data Elasticsearch auf codefokussierte, praktische Weise.

Wir zeigen, wie Sie Elasticsearch in einer Spring-Anwendung mithilfe von Spring Data indizieren, suchen und abfragen können - einem Spring-Modul für die Interaktion mit einer beliebten Open-Source-Suchmaschine auf Lucene-Basis.

Elasticsearch ist zwar schemenlos, kann jedoch Zuordnungen verwenden, um den Typ eines Felds zu ermitteln. Wenn ein Dokument indiziert wird, werden seine Felder entsprechend ihrer Art verarbeitet. Beispielsweise wird ein Textfeld entsprechend den Zuordnungsregeln mit einem Token versehen und gefiltert. Sie können auch eigene Filter und Tokenizer erstellen.

2. Federdaten

Spring Data vermeidet Code auf dem Kesselschild. Wenn wir beispielsweise eine Repository-Schnittstelle definieren, die die von Spring Data Elasticsearch,bereitgestellteElasticsearchRepository-Schnittstelle erweitert, werden die CRUD-Operationen für die entsprechende Dokumentklasse standardmäßig verfügbar gemacht.

Darüber hinaus werden Methodenimplementierungen für Sie generiert, indem Sie einfach Methoden mit Namen in einem vorgegebenen Format deklarieren - es ist nicht erforderlich, eine Implementierung der Repository-Schnittstelle zu schreiben.

Sie können mehr über Spring Datahere lesen.

2.1. Maven-Abhängigkeit

Spring Data Elasticsearch bietet eine Java-API für die Suchmaschine. Um es zu verwenden, müssen wir denpom.xml eine neue Abhängigkeit hinzufügen:


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

2.2. Repository-Schnittstellen definieren

Als Nächstes müssen wir eine der bereitgestellten Repository-Schnittstellen erweitern und die generischen Typen durch unsere tatsächlichen Dokument- und Primärschlüsseltypen ersetzen.

Beachten Sie, dassElasticsearchRepositoryPagingAndSortingRepository erweitert, was eine integrierte Unterstützung für die Paginierung und Sortierung bietet.

In unserem Beispiel verwenden wir die Paging-Funktion in unserer benutzerdefinierten Suchmethode:

public interface ArticleRepository extends ElasticsearchRepository {

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

Beachten Sie, dass wir zwei benutzerdefinierte Methoden hinzugefügt haben. Mit der MethodefindByAuthorsName erstellt der Repository-Proxy eine Implementierung basierend auf dem Methodennamen. Der Auflösungsalgorithmus bestimmt, dass er auf die Eigenschaftauthorszugreifen und dann die Eigenschaftnamejedes Elements durchsuchen muss.

Die zweite Methode,findByAuthorsNameUsingCustomQuery, verwendet eine boolesche Elasticsearch-Abfrage, die mithilfe der Annotation@Querydefiniert wird und eine strikte Übereinstimmung zwischen dem Namen des Autors und dem angegebenen Argumentnameerfordert.

2.3. Java-Konfiguration

Lassen Sie uns nun die Frühlingskonfiguration unserer Persistenzschicht hier untersuchen:

@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());
    }
}

Beachten Sie, dass wir eine Standardanmerkung im Spring-Aktivierungsstil -@EnableElasticsearchRepositories - verwenden, um das bereitgestellte Paket nach Spring Data-Repositorys zu durchsuchen.

Wir definieren auch ein einfachesTransport Client:

  1. Wir aktivieren die Sniffing-Funktion für unseren Kunden mit "client.transport.sniff".

  2. Wir stellen auch das Elasticsearch-Installationsverzeichnis über "path.home" zur Verfügung.

  3. Wenn der Clustername nicht "elasticsearch" ist, müssen wir ihn mit "cluster.name" bereitstellen.

Schließlich richten wir auch eineElasticsearchOperations-Bean -elasticsearchTemplate - als unseren Client ein, um gegen den Elasticsearch-Server zu arbeiten.

3. Zuordnungen

Definieren wir nun unsere erste Entität - ein Dokument namensArticle mit einem Stringid:

@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
}

Beachten Sie, dass wir in der Annotation@Document angeben, dass Instanzen dieser Klasse in Elasticsearch in einem Index namens „blog“ und mit dem Dokumenttyp „article“ gespeichert werden sollen. Dokumente mit vielen verschiedenentypes können in denselbenindex gespeichert werden.

Beachten Sie auch, dass das Feldauthors alsFieldType.Nested markiert ist. Auf diese Weise können wir die KlasseAuthoreparat definieren, die einzelnen Instanzen des Autors jedoch in ein DokumentArticleeinbetten, wenn es in Elasticsearch indiziert wird.

4. Indizieren von Dokumenten

Spring Data Elasticsearch erstellt im Allgemeinen automatisch Indizes basierend auf den Entitäten im Projekt.

Sie können einen Index jedoch auch programmgesteuert über die Client-Vorlage erstellen:

elasticsearchTemplate.createIndex(Article.class);

Nachdem der Index verfügbar ist, können wir dem Index ein Dokument hinzufügen.

Schauen wir uns ein kurzes Beispiel an: Indizieren eines Artikels mit zwei Autoren:

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

5. Abfragen

5.1. Auf Methodennamen basierende Abfrage

Die zuvor definierte Repository-Klasse hatte einefindByAuthorsName-Methode, mit der wir Artikel nach Autorennamen suchen können:

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

Durch Aufrufen vonfindByAuthorName mit einemPageRequest-Objekt erhalten wir die erste Ergebnisseite (die Seitennummerierung basiert auf Null), wobei diese Seite höchstens 10 Artikel enthält.

5.2. Eine benutzerdefinierte Abfrage

Es gibt verschiedene Möglichkeiten, benutzerdefinierte Abfragen für Spring Data Elasticsearch-Repositorys zu definieren. Eine Möglichkeit besteht darin, die Annotation@Queryzu verwenden, wie in Abschnitt 2.2 gezeigt.

Eine andere Möglichkeit besteht darin, einen Builder für die Erstellung benutzerdefinierter Abfragen zu verwenden.

Zum Beispiel könnten wir nach Artikeln suchen, die das Wort "data" im Titel haben, indem wir eine Abfrage mitNativeSearchQueryBuilder erstellen:

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

6. Aktualisieren und Löschen

Um ein Dokument zu aktualisieren oder zu löschen, müssen wir zuerst dieses Dokument abrufen.

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

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

Um nun den Titel des Artikels zu aktualisieren, können wir das Dokument ändern und diesave-API verwenden:

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

Wie Sie vielleicht erraten haben, können Sie zum Löschen eines Dokuments die Methodedeleteverwenden:

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

7. Fazit

Dies war eine schnelle und praktische Diskussion über die grundlegende Verwendung von Spring Data Elasticsearch.

Um mehr über die beeindruckenden Funktionen von Elasticsearch zu erfahren, finden Sie diedocumentationauf der offiziellen Website.

Das in diesem Artikel verwendete Beispiel ist alssample project in GitHub verfügbar.