Introduction à Spring Data Elasticsearch

Introduction à Spring Data Elasticsearch

1. Vue d'ensemble

Dans cet articlewe’ll explore the basics of Spring Data Elasticsearch d'une manière pratique et centrée sur le code.

Nous allons montrer comment indexer, rechercher et interroger Elasticsearch dans une application Spring à l'aide de Spring Data - un module Spring pour l'interaction avec un moteur de recherche open-source populaire basé sur Lucene.

Tandis qu'Elasticsearch est sans schéma, il peut utiliser des mappages pour indiquer le type d'un champ. Lorsqu'un document est indexé, ses champs sont traités en fonction de leur type. Par exemple, un champ de texte sera segmenté et filtré conformément aux règles de mappage. Vous pouvez également créer vos propres filtres et tokenizers.

2. Données de printemps

Spring Data permet d'éviter le code passe-partout. Par exemple, si nous définissons une interface de référentiel qui étend l'interfaceElasticsearchRepository fournie par Spring Data Elasticsearch, les opérations CRUD de, pour la classe de document correspondante seront rendues disponibles par défaut.

De plus, simplement en déclarant des méthodes avec des noms dans un format prescrit, les implémentations de méthodes sont générées pour vous - il n'est pas nécessaire d'écrire une implémentation de l'interface de référentiel.

Vous pouvez en savoir plus sur Spring Datahere.

2.1. Dépendance Maven

Spring Data Elasticsearch fournit une API Java pour le moteur de recherche. Pour l'utiliser, nous devons ajouter une nouvelle dépendance auxpom.xml:


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

2.2. Définition des interfaces de référentiel

Nous devons ensuite étendre l’une des interfaces de référentiel fournies, en remplaçant les types génériques par nos types de document et de clé primaire.

Notez queElasticsearchRepository étendPagingAndSortingRepository, qui fournit un support intégré pour la pagination et le tri.

Dans notre exemple, nous allons utiliser la fonctionnalité de pagination dans notre méthode de recherche personnalisée:

public interface ArticleRepository extends ElasticsearchRepository {

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

Notez que nous avons ajouté deux méthodes personnalisées. Avec la méthodefindByAuthorsName, le proxy du référentiel créera une implémentation basée sur le nom de la méthode. L'algorithme de résolution déterminera qu'il a besoin d'accéder à la propriétéauthors, puis recherchera la propriéténame de chaque élément.

La deuxième méthode,findByAuthorsNameUsingCustomQuery, utilise une requête booléenne Elasticsearch, définie à l'aide de l'annotation@Query, qui nécessite une correspondance stricte entre le nom de l'auteur et l'argumentname fourni.

2.3. Configuration Java

Explorons maintenant la configuration Spring de notre couche de persistance ici:

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

Notez que nous utilisons une annotation standard de style d'activation Spring -@EnableElasticsearchRepositories - pour analyser le package fourni à la recherche de référentiels Spring Data.

Nous définissons également un simpleTransport Client:

  1. Nous activons la fonctionnalité de détection pour notre client en utilisant «client.transport.sniff»

  2. Nous fournissons également le répertoire d'installation Elasticsearch à l'aide de «path.home».

  3. Si le nom du cluster n'est pas “elasticsearch”, nous devons le fournir en utilisant “cluster.name”

Enfin, nous configurons également un beanElasticsearchOperations -elasticsearchTemplate - en tant que client pour travailler avec le serveur Elasticsearch.

3. Mappages

Définissons maintenant notre première entité - un document appeléArticle avec une chaîneid:

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

Notez que dans l'annotation@Document, nous indiquons que les instances de cette classe doivent être stockées dans Elasticsearch dans un index appelé «blog», et avec un type de document «article». Les documents avec de nombreuxtype différents peuvent être stockés dans les mêmesindex.

Notez également que le champauthors est marqué commeFieldType.Nested. Cela nous permet de définir la classeAuthor séparément, mais d'avoir les instances individuelles de l'auteur incorporées dans un documentArticle lorsqu'il est indexé dans Elasticsearch.

4. Indexation de documents

Spring Data Elasticsearch crée généralement des index en fonction des entités du projet.

Cependant, vous pouvez également créer un index par programme, via le modèle client:

elasticsearchTemplate.createIndex(Article.class);

Une fois l'index disponible, nous pouvons ajouter un document à l'index.

Jetons un coup d'œil à un exemple - indexation d'un article avec deux auteurs:

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

5. Requête

5.1. Requête basée sur le nom de la méthode

La classe de référentiel que nous avons définie précédemment avait une méthodefindByAuthorsName - que nous pouvons utiliser pour rechercher des articles par nom d'auteur:

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

En appelantfindByAuthorName avec un objetPageRequest, nous obtenons la première page de résultats (la numérotation des pages est basée sur zéro), cette page contenant au plus 10 articles.

5.2. Une requête personnalisée

Il existe deux manières de définir des requêtes personnalisées pour les référentiels Spring Data Elasticsearch. Une façon est d'utiliser l'annotation@Query, comme démontré dans la section 2.2.

Une autre option consiste à utiliser un générateur pour la création d'une requête personnalisée.

Par exemple, nous pourrions rechercher des articles contenant le mot «data» dans le titre en créant une requête avec lesNativeSearchQueryBuilder:

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

6. Mise à jour et suppression

Afin de mettre à jour ou de supprimer un document, nous devons d’abord récupérer ce document.

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

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

Maintenant, pour mettre à jour le titre de l'article, nous pouvons modifier le document et utiliser l'APIsave:

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

Comme vous l'avez peut-être deviné, pour supprimer un document, vous pouvez utiliser la méthodedelete:

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

7. Conclusion

Il s'agissait d'une discussion rapide et pratique sur l'utilisation de base de Spring Data Elasticsearch.

Pour en savoir plus sur les fonctionnalités impressionnantes d'Elasticsearch, vous pouvez trouver sesdocumentation sur le site officiel.

L'exemple utilisé dans cet article est disponible en tant quesample project in GitHub.