Exercice : Interroger à l’aide du kit de développement logiciel (SDK) Java Azure Cosmos DB

Effectué

Maintenant que vous avez créé des documents dans votre application, nous allons les interroger à partir de votre application. Le kit de développement logiciel (SDK) Java Azure Cosmos DB utilise des requêtes SQL. Le kit de développement logiciel (SDK) .NET prend en charge les requêtes LINQ, mais le kit de développement logiciel (SDK) Java n’a aucun analogue. Cette unité se concentre sur l’exécution des requêtes SQL à partir de votre application, et non à partir du portail.

Nous allons utiliser les documents utilisateur que vous avez créés pour votre application de détaillant en ligne afin de tester ces requêtes.

Exécuter des requêtes SQL

  1. L’exemple suivant montre comment une requête peut être exécutée dans SQL à partir de votre code Java. Copiez le code et ajoutez-le à la fin du fichier CosmosApp.java.

    /**
     * Execute a custom query on the Azure Cosmos DB container.
     * @param query Query String.
     */
    private static void executeSimpleQuery(final String query) {
    
        final int preferredPageSize = 10;
        CosmosQueryRequestOptions queryOptions = new CosmosQueryRequestOptions();
    
        CosmosPagedFlux<User> pagedFluxResponse = container.queryItems(
                query, queryOptions, User.class);
    
        logger.info("Running SQL query...");
    
        pagedFluxResponse.byPage(preferredPageSize).flatMap(fluxResponse -> {
            logger.info("Got a page of query result with " + fluxResponse.getResults().size()
                    + " items(s) and request charge of " + fluxResponse.getRequestCharge());
    
            logger.info("Item Ids " + fluxResponse
                    .getResults()
                    .stream()
                    .map(User::getId)
                    .collect(Collectors.toList()));
    
            return Flux.empty();
        }).blockLast();
    }
    

    Dans ce code, vous remarquerez que nous utilisons à nouveau le modèle de programmation de dataflow déclaratif Project Reactor. Cette fois, nous l’utilisons pour gérer les pages de réponse de requête de manière asynchrone. Nous présentons une approche asynchrone, car dans un cas d’usage réel, il peut y avoir des centaines voire des milliers de réponses à une requête. L’agrégation des réponses de requête peut être une tâche gourmande en ressources processeur qui tire parti de l’efficacité accrue des threads de la programmation asynchrone.

    En bref, nous souhaitons obtenir un débit élevé de traitement de réponses aux requêtes ou un taux élevé de pages par seconde pour chaque thread. queryitems retourne l’instance pagedFluxResponseCosmosPagedFlux et pagedFluxResponse.byPage(preferredPageSize) crée une instance Flux qui est une source d’événements de page asynchrones. Le pipeline des opérations situé à l’intérieur de .flatMap( ... ).blockLast(); opère de façon asynchrone et pseudo-parallèle sur la page des réponses de requêtes associée à chaque événement émis par l’instance Flux.

  2. Copiez et collez le code suivant dans votre méthode basicOperations, avant le code de suppression du document.

    executeSimpleQuery("SELECT * FROM User WHERE User.lastName = 'Pindakova'");
    
  3. Générez et exécutez CosmosApp.java dans l’IDE ou exécutez le programme sur le terminal à l’aide de :

    mvn clean package
    mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"
    

    Sans le terminal, la sortie se présente ainsi :

    INFO: Database and container validation complete
    INFO: User 1 already exists in the database
    INFO: User 2 already exists in the database
    INFO: Read User 1
    INFO: Replaced last name for Suh
    INFO: Running SQL query...
    INFO: Got a page of query result with 1 items(s) and request charge of 2.83
    INFO: Item Ids [2]
    INFO: Deleted User 1
    

Maintenant que vous avez créé des documents dans votre application, nous allons les interroger à partir de votre application. Spring Data Azure Cosmos DB expose à la fois les méthodes de requête dérivées et les méthodes de requête personnalisées, et ces deux fonctions s’appuient sur la fonctionnalité de requête en langage SQL du kit de développement logiciel (SDK) Azure Cosmos DB Java v4 sous-jacent. Cette unité se concentre sur l’exécution des requêtes Spring Data Azure Cosmos DB à partir de votre application, et non à partir du portail.

Nous allons utiliser les documents WebCustomer que vous avez créés pour votre application de détaillant en ligne afin de tester ces requêtes.

Créer et appeler des méthodes de requête dérivées

Les méthodes de requête dérivées sont des méthodes de référentiel Spring Data sans implémentation. Au lieu de cela, le nom de la méthode demande à Spring Data de traduire chaque appel de méthode et ses arguments en une requête sur la base de données sous-jacente. Par exemple, lorsque vous appelez findById avec certains arguments, Spring Data lit le nom de la méthode comme « rechercher par ID » et assemble une requête de base de données qui retourne le document spécifié par les arguments.

Spring Data Azure Cosmos DB inclut un certain nombre de méthodes de requête dérivées intégrées, y compris findById. Dans cette section, nous vous montrerons comment implémenter de nouvelles méthodes de requête dérivées.

  1. Nous allons créer une méthode de requête dérivée qui interroge tous les documents ayant une certaine valeur pour le champ firstName. Accédez à ReactiveWebCustomerRepository.java. Vous verrez la déclaration de méthode suivante :

    Flux<WebCustomer> findByFirstName(String firstName);
    

    Cette méthode de référentiel indique à Spring Data que vous souhaitez une méthode qui interroge firstName quand elle est appelée. Souvenez-vous que la classe WebCustomer a commencé par une annotation @Container spécifiant containerName comme WebCustomers. Comme findByFirstName retourne Flux<WebCustomer>, Spring Data peut interroger WebCustomers lorsque cette méthode est appelée.

  2. Copiez et collez le code suivant dans votre méthode run, avant l’appel deleteWebCustomerDocument.

    logger.info("Running derived query...");
    Flux<WebCustomer> webCustomers = reactiveWebCustomerRepository.findByFirstName("Max");
    webCustomers.flatMap(webCustomer -> {
        logger.info("- WebCustomer is : {}", webCustomer.getUserId());
        return Mono.empty();
    }).blockLast();
    

    Dans ce code, vous remarquerez que nous utilisons à nouveau le modèle de programmation de dataflow déclaratif Project Reactor. Cette fois, nous l’utilisons pour gérer les pages de réponse de requête de manière asynchrone. Nous présentons une approche asynchrone, car dans un cas d’usage réel, il peut y avoir des centaines voire des milliers de réponses à une requête. L’agrégation des réponses de requête peut être une tâche gourmande en ressources processeur qui tire parti de l’efficacité accrue des threads de la programmation asynchrone.

    En bref, nous souhaitons obtenir un débit élevé de traitement de réponses aux requêtes ou un taux élevé de réponses par seconde pour chaque thread. findByFirstName renvoie l’instance Flux<WebCustomer>webCustomers. Le pipeline des opérations situé dans .flatMap( ... ).blockLast(); opère de façon asynchrone et pseudo-parallèle sur les réponses de requêtes associées à chaque événement émis par le Flux<WebCustomer>.

  3. Générez et exécutez CosmosSample.java dans l’IDE ou exécutez le programme sur le terminal à l’aide de :

    mvn clean package
    mvn spring-boot:run
    

    Sans le terminal, la sortie se présente ainsi :

    INFO: - WebCustomer is : maxaxam
    

Créer et appeler des méthodes de requête personnalisées

Les méthodes de requête personnalisées sont des méthodes de référentiel Spring Data avec une annotation @Query spécifiant une chaîne de requête, et la chaîne de requête contient des espaces réservés pour les arguments de la méthode. Cette fois-ci, le nom de la méthode n’a aucun impact sur la requête exécutée. L’annotation @Query demande à Spring Data d’émettre une requête en langage SQL à la base de données sous-jacente, après le remplissage des espaces réservés des arguments avec les valeurs des arguments de la méthode.

  1. Nous allons créer une méthode de requête personnalisée qui interroge tous les documents ayant une certaine valeur pour le champ lastName. Accédez à ReactiveWebCustomerRepository.java. Vous verrez la déclaration de méthode suivante :

    @Query(value = "SELECT * FROM User WHERE User.lastName = @lastName")
    Flux<WebCustomer> findByLastName(@Param("lastName") String lastName);
    

    Cette méthode de référentiel indique à Spring Data que vous souhaitez une méthode qui interroge lastName quand elle est appelée. La valeur de l’argument lastName sera remplacée par l’espace réservé @lastName.

  2. Copiez et collez le code suivant dans votre méthode run, après le code de la requête dérivée.

    logger.info("Running custom query...");
    webCustomers = reactiveWebCustomerRepository.findByLastName("Axam");
    webCustomers.flatMap(webCustomer -> {
        logger.info("- WebCustomer is : {}", webCustomer.getUserId());
        return Mono.empty();
    }).blockLast();
    
  3. Générez et exécutez CosmosSample.java dans l’IDE ou exécutez le programme sur le terminal à l’aide de :

    mvn clean package
    mvn spring-boot:run
    

    Sans le terminal, la sortie se présente ainsi :

    INFO: Running derived query...
    INFO: - WebCustomer is : maxaxam
    INFO: Running custom query...
    INFO: - WebCustomer is : maxaxam    
    

Dans cette unité, vous avez découvert les requêtes dérivées et les requêtes personnalisées. Vous avez ensuite ajouté les types de requêtes à votre application pour récupérer les enregistrements utilisateur.