Exercício – Consulta com o SDK Java do Azure Cosmos DB

Concluído

Agora que criou documentos na aplicação, vamos consultá-los. O SDK Java do Azure Cosmos DB utiliza consultas SQL. O SDK. NET contém suporte adicional para consultas LINQ, mas o SDK Java não tem nenhuma analogia. Esta unidade foca-se na execução de consultas SQL a partir da aplicação e não a partir do portal.

Vamos utilizar os documentos de utilizador que criou para a aplicação de revendedor online para testar estas consultas.

Executar consultas SQL

  1. A seguinte amostra mostra como realizar uma consulta no SQL a partir do código Java. Copie o código e adicione-o à parte final do ficheiro 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();
    }
    

    Neste código, repare que estamos a utilizar novamente o modelo de programação de fluxo de dados declarativo do Project Reactor. Desta vez, estamos a utilizá-lo para lidar com as páginas de resposta das consultas de forma assíncrona. Demonstramos uma abordagem assíncrona, uma vez que, num caso de utilização real, podem existir centenas ou milhares de respostas a uma consulta. A agregação de respostas de consultas pode constituir uma tarefa intensiva da CPU que beneficia da eficiência superior de threads da programação assíncrona.

    Resumindo, queremos um débito elevado ao lidar com respostas de consultas ou taxas elevadas de páginas/segundo por thread. queryitems devolve a instância pagedFluxResponse de CosmosPagedFlux e pagedFluxResponse.byPage(preferredPageSize) cria uma instância Flux que é uma origem de eventos de página assíncronos. O pipeline de operações em .flatMap( ... ).blockLast(); opera de forma assíncrona e pseudo-paralela na página de resposta de consultas associada a cada evento emitido pela instância Flux.

  2. Copie o cole o seguinte código no método basicOperations, antes do código de eliminação do documento.

    executeSimpleQuery("SELECT * FROM User WHERE User.lastName = 'Pindakova'");
    
  3. Crie e execute CosmosApp.java no IDE ou execute o programa no terminal com:

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

    No terminal, o resultado deverá ter um aspeto semelhante ao seguinte:

    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
    

Agora que criou documentos na aplicação, vamos consultá-los. O Azure Cosmos DB do Spring Data expõe os métodos de consulta derivados, bem como os métodos de consulta personalizados, e ambos se baseiam na capacidade de consulta de linguagem SQL do SDK Java do Azure Cosmos DB v4 subjacente. Esta unidade foca-se na execução de consultas do Azure Cosmos DB do Spring Data a partir da aplicação e não a partir do portal.

Vamos utilizar os documentos de WebCustomer que criou para a aplicação de revendedor online para testar estas consultas.

Criar e chamar métodos de consulta derivados

Os métodos de consulta derivados são métodos de repositório do Spring Data sem implementação; em vez disso, o nome do método sinaliza o Spring Data para traduzir cada chamada de método e os argumentos numa consulta na base de dados subjacente. Por exemplo, quando chama findById com alguns argumentos, o Spring Data lê o nome do método como “localizar por ID” e monta uma consulta de base de dados que devolve o documento especificado pelos argumentos.

O Azure Cosmos DB do Spring Data inclui um número de métodos de consulta derivados integrados, incluindo findById. Nesta secção, mostraremos como implementar novos métodos de consulta derivados.

  1. Criaremos um método de consulta derivado que consulta todos os documentos com um determinado valor para o campo firstName. Navegue até ReactiveWebCustomerRepository.java. Você verá a seguinte declaração de método:

    Flux<WebCustomer> findByFirstName(String firstName);
    

    Este método de repositório declara ao Spring Data que quer um método que consulta firstName quando é chamado. Lembre-se de que a classe WebCustomer começou com uma anotação @Container ao especificar containerName como WebCustomers. Como findByFirstName devolve Flux<WebCustomer>, o Spring Data sabe como consultar WebCustomers quando este método é chamado.

  2. Copie e cole o seguinte código no método run, antes da chamada 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();
    

    Neste código, repare que estamos a utilizar novamente o modelo de programação de fluxo de dados declarativo do Project Reactor. Desta vez, estamos a utilizá-lo para lidar com as páginas de resposta das consultas de forma assíncrona. Demonstramos uma abordagem assíncrona, uma vez que, num caso de utilização real, podem existir centenas ou milhares de respostas a uma consulta. A agregação de respostas de consultas pode constituir uma tarefa intensiva da CPU que beneficia da eficiência superior de threads da programação assíncrona.

    Resumindo, queremos um débito elevado ao lidar com respostas de consultas ou taxas elevadas de respostas/segundo por thread. findByFirstName devolve a instância webCustomers de Flux<WebCustomer>. O pipeline de operações em .flatMap( ... ).blockLast(); opera de forma assíncrona e pseudo-paralela nas resposta de consultas associadas a cada evento emitido por Flux<WebCustomer>.

  3. Crie e execute CosmosSample.java no IDE ou execute o programa no terminal com:

    mvn clean package
    mvn spring-boot:run
    

    No terminal, o resultado deverá ter um aspeto semelhante ao seguinte:

    INFO: - WebCustomer is : maxaxam
    

Criar e chamar métodos de consulta personalizados

Os métodos de consulta personalizados são métodos de repositório do Spring Data com uma anotação @Query a especificar uma cadeia de consulta – e a cadeia de consulta contém marcadores de posição para os argumentos dos métodos. Desta vez, o nome do método não tem qualquer impacto sobre a consulta que é executada. A anotação @Query indica ao Spring Data para emitir uma consulta de linguagem SQL para a base de dados subjacente, depois de preencher os marcadores de posição dos argumentos com os valores dos argumentos dos métodos.

  1. Criaremos um método de consulta personalizado que consulta todos os documentos com um determinado valor para o campo lastName. Navegue até ReactiveWebCustomerRepository.java. Você verá a seguinte declaração de método:

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

    Este método de repositório declara ao Spring Data que quer um método que consulta lastName quando é chamado. O valor do argumento lastName será substituído pelo marcador de posição @lastName.

  2. Copie e cole o seguinte código no método run, após o código da consulta derivado.

    logger.info("Running custom query...");
    webCustomers = reactiveWebCustomerRepository.findByLastName("Axam");
    webCustomers.flatMap(webCustomer -> {
        logger.info("- WebCustomer is : {}", webCustomer.getUserId());
        return Mono.empty();
    }).blockLast();
    
  3. Crie e execute CosmosSample.java no IDE ou execute o programa no terminal com:

    mvn clean package
    mvn spring-boot:run
    

    No terminal, o resultado deverá ter um aspeto semelhante ao seguinte:

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

Nesta unidade, ficou a saber mais sobre as consultas derivadas e personalizadas. Em seguida, adicionou ambos os tipos de consulta à aplicação para obter registos de utilizador.