Esercizio - Eseguire query usando Java SDK per Azure Cosmos DB

Completato

Dopo aver creato documenti nell'applicazione, è possibile eseguire query per recuperarli dall'applicazione. Java SDK per Azure Cosmos DB usa le query SQL. .NET SDK offre supporto aggiuntivo per le query LINQ, ma Java SDK non ha alcun analogo. Questa unità è incentrata sull'esecuzione di query SQL dall'applicazione, anziché dal portale.

Per testare queste query verranno usati i documenti utente creati per l'applicazione del rivenditore online.

Eseguire query SQL

  1. L'esempio seguente mostra come è possibile eseguire una query in SQL dal codice Java. Copiare il codice e aggiungerlo alla fine del file 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();
    }
    

    In questo codice si noti che viene usato ancora una volta il modello di programmazione del flusso di dati dichiarativo di Project Reactor. Questa volta viene usato per gestire le pagine di risposta alle query in modo asincrono. Viene illustrato un approccio asincrono perché, in un caso d'uso reale, potrebbero essere presenti centinaia o migliaia di risposte a una query. L'aggregazione delle risposte alle query può essere un'attività che richiede un utilizzo intensivo della CPU, che trae vantaggio dall'aumentata efficienza dei thread della programmazione asincrona.

    In breve, si vuole una velocità effettiva elevata per la gestione delle risposte alle query o un numero elevato di pagine al secondo per thread. queryitems restituisce l'istanza CosmosPagedFlux di pagedFluxResponse, mentre pagedFluxResponse.byPage(preferredPageSize) crea un'istanza di Flux che è un'origine di eventi di pagina asincroni. La pipeline di operazioni all'interno di .flatMap( ... ).blockLast(); funziona in modo asincrono e in pseudo-parallelo nella pagina di risposte alle query associata a ogni evento emesso dall'istanza Flux.

  2. Copiare e incollare il codice seguente nel metodo basicOperations prima del codice di eliminazione del documento.

    executeSimpleQuery("SELECT * FROM User WHERE User.lastName = 'Pindakova'");
    
  3. Compilare ed eseguire CosmosApp.java nell'IDE oppure eseguire il programma nel terminale usando:

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

    Nel terminale l'output sarà simile al seguente:

    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
    

Dopo aver creato documenti nell'applicazione, è possibile eseguire query per recuperarli dall'applicazione. Spring Data per Azure Cosmos DB espone sia i metodi di query derivati che i metodi di query personalizzati. Entrambi i tipi di metodi sono basati sulla funzionalità di query del linguaggio SQL di Azure Cosmos DB Java SDK v4. Questa unità è incentrata sull'esecuzione di query di Spring Data per Azure Cosmos DB dall'applicazione, anziché dal portale.

Per testare queste query verranno usati i documenti WebCustomer creati per l'applicazione del rivenditore online.

Creare e chiamare metodi di query derivati

I metodi di query derivati sono metodi di repository di Spring Data senza implementazione; al contrario, il nome del metodo segnala a Spring Data di tradurre ogni chiamata al metodo e i relativi argomenti in una query nel database sottostante. Ad esempio, quando viene effettuata una chiamata a findById con alcuni argomenti, Spring Data legge il nome del metodo come "ricerca per ID" e assembla una query di database che restituisce il documento specificato dagli argomenti.

Spring Data per Azure Cosmos DB include una serie di metodi di query derivati predefiniti, tra cui findById. In questa sezione verrà illustrato come implementare nuovi metodi di query derivati.

  1. Si creerà un metodo di query derivato che esegue una query su tutti i documenti che hanno un determinato valore per il campo firstName. Passare a ReactiveWebCustomerRepository.java. Verrà visualizzata la dichiarazione di metodo seguente:

    Flux<WebCustomer> findByFirstName(String firstName);
    

    Questo metodo di repository dichiara a Spring Data che si vuole un metodo che esegua una query su firstName quando viene chiamato. Tenere presente che la classe WebCustomer inizia con un'annotazione @Container che specifica containerName come WebCustomers. Poiché findByFirstName restituisce Flux<WebCustomer>, viene indicato a Spring Data di eseguire una query su WebCustomers quando viene chiamato questo metodo.

  2. Copiare e incollare il codice seguente nel metodo run prima della chiamata 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();
    

    In questo codice si noti che viene usato ancora una volta il modello di programmazione del flusso di dati dichiarativo di Project Reactor. Questa volta viene usato per gestire le pagine di risposta alle query in modo asincrono. Viene illustrato un approccio asincrono perché, in un caso d'uso reale, potrebbero essere presenti centinaia o migliaia di risposte a una query. L'aggregazione delle risposte alle query può essere un'attività che richiede un utilizzo intensivo della CPU, che trae vantaggio dall'aumentata efficienza dei thread della programmazione asincrona.

    In breve, si vuole una velocità effettiva elevata per la gestione delle risposte alle query o un numero elevato di risposte al secondo per thread. findByFirstName restituisce l'istanza di Flux<WebCustomer> webCustomers. La pipeline di operazioni all'interno di .flatMap( ... ).blockLast(); funziona in modo asincrono e in pseudo-parallelo nelle risposte alle query associate a ogni evento emesso da Flux<WebCustomer>.

  3. Compilare ed eseguire CosmosSample.java nell'IDE oppure eseguire il programma nel terminale usando:

    mvn clean package
    mvn spring-boot:run
    

    Nel terminale l'output sarà simile al seguente:

    INFO: - WebCustomer is : maxaxam
    

Creare e chiamare metodi di query personalizzati

I metodi di query personalizzati sono metodi di repository di Spring Data con un'annotazione @Query che specifica una stringa di query che contiene segnaposto per gli argomenti del metodo. In questo caso il nome del metodo non ha alcun effetto sulla query eseguita. L'annotazione @Query indica a Spring Data di inviare una query in linguaggio SQL nel database sottostante, dopo aver compilato i segnaposto degli argomenti con i valori degli argomenti del metodo.

  1. Si creerà un metodo di query personalizzato che esegue una query su tutti i documenti che hanno un determinato valore per il campo lastName. Passare a ReactiveWebCustomerRepository.java. Verrà visualizzata la dichiarazione di metodo seguente:

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

    Questo metodo di repository dichiara a Spring Data che si vuole un metodo che esegua una query su lastName quando viene chiamato. Il valore dell'argomento lastName verrà sostituito per il segnaposto @lastName.

  2. Copiare e incollare il codice seguente nel metodo run, dopo il codice della query derivata.

    logger.info("Running custom query...");
    webCustomers = reactiveWebCustomerRepository.findByLastName("Axam");
    webCustomers.flatMap(webCustomer -> {
        logger.info("- WebCustomer is : {}", webCustomer.getUserId());
        return Mono.empty();
    }).blockLast();
    
  3. Compilare ed eseguire CosmosSample.java nell'IDE oppure eseguire il programma nel terminale usando:

    mvn clean package
    mvn spring-boot:run
    

    Nel terminale l'output sarà simile al seguente:

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

In questa unità sono state apprese informazioni sulle query derivate e personalizzate. Quindi sono stati aggiunti entrambi i tipi di query all'applicazione per recuperare i record utente.