Exercício – Consultar usando o SDK do Java do Azure Cosmos DB

Concluído

Agora que você criou documentos no aplicativo, vamos consultá-los no aplicativo. O SDK do Java do Azure Cosmos DB usa consultas SQL. No SDK do .NET, há suporte adicional para consultas LINQ, mas o SDK do Java não tem nada análogo. Esta unidade concentra-se na execução de consultas SQL no aplicativo, em vez de no portal.

Usaremos os documentos do usuário que você criou para seu aplicativo de loja online para testar essas consultas.

Executar consultas SQL

  1. O exemplo a seguir descreve como uma consulta pode ser executada no SQL por meio do código Java. Copie o código e adicione-o ao final do arquivo 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();
    }
    

    Nesse código, observe que estamos novamente usando o modelo de programação de fluxo de dados declarativo do Project Reactor. Desta vez, estamos usando-o para lidar com páginas de resposta de consulta de forma assíncrona. Demonstramos uma abordagem assíncrona porque, em um caso de uso real, pode haver centenas ou milhares de respostas a uma consulta. A agregação de respostas de consulta pode ser uma tarefa com uso intensivo de CPU que se beneficia da maior eficiência de threads da programação assíncrona.

    Em resumo, desejamos uma alta taxa de transferência no tratamento de respostas de consulta ou um volume alto de páginas/segundo por thread. queryitems retorna a instância de CosmosPagedFluxpagedFluxResponse, e pagedFluxResponse.byPage(preferredPageSize) cria uma instância Flux que é uma fonte de eventos de página assíncronos. O pipeline de operações dentro de .flatMap( ... ).blockLast(); funciona de modo assíncrono e pseudoparalelo na página de resposta de consulta associada a cada evento emitido pela instância Flux.

  2. Copie e cole o código a seguir no método basicOperations, antes do código de exclusão do documento.

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

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

    No terminal, a saída deverá ser semelhante a esta:

    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 você criou documentos no aplicativo, vamos consultá-los no aplicativo. O Spring Data para Azure Cosmos DB expõe os métodos de consulta derivada, bem como os métodos de consulta personalizada, e ambos se baseiam no recurso de consulta de linguagem SQL do SDK do Java do Azure Cosmos DB v4 subjacente. Esta unidade se concentra em executar consultas do Spring Data para Azure Cosmos DB em seu aplicativo, em vez de fazer isso no portal.

Usaremos os documentos do WebCustomer que você criou para seu aplicativo de loja online a fim de testar essas consultas.

Criar e chamar métodos de consulta derivada

Os métodos de consulta derivada são métodos de repositório do Spring Data sem implementação; em vez disso, o nome do método sinaliza para o Spring Data converter cada chamada de método e seus argumentos em uma consulta no banco de dados subjacente. Por exemplo, quando você chama findById com alguns argumentos, o Spring Data lê o nome do método como "localizar por ID" e monta uma consulta de banco de dados que retorna o documento especificado pelos argumentos.

O Spring Data para Azure Cosmos DB inclui vários métodos de consulta derivada internos, como findById. Nesta seção, mostraremos como implementar novos métodos de consulta derivada.

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

    Flux<WebCustomer> findByFirstName(String firstName);
    

    Esse método de repositório declara ao Spring Data que você deseja um método que consulte firstName quando é chamado. Lembre-se de que a classe WebCustomer começou com uma anotação @Container especificando containerName como WebCustomers. Uma vez que findByFirstName retorna Flux<WebCustomer>, o Spring Data consulta WebCustomers quando esse método é chamado.

  2. Copie e cole o código a seguir 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();
    

    Nesse código, observe que estamos novamente usando o modelo de programação de fluxo de dados declarativo do Project Reactor. Desta vez, estamos usando-o para lidar com páginas de resposta de consulta de forma assíncrona. Demonstramos uma abordagem assíncrona porque, em um caso de uso real, pode haver centenas ou milhares de respostas a uma consulta. A agregação de respostas de consulta pode ser uma tarefa com uso intensivo de CPU que se beneficia da maior eficiência de threads da programação assíncrona.

    Em resumo, desejamos uma alta taxa de transferência no tratamento de respostas de consulta ou um volume alto de respostas/segundo por thread. findByFirstName retorna o nome da instância de Flux<WebCustomer>, webCustomers. O pipeline de operações dentro de .flatMap( ... ).blockLast(); funciona de modo assíncrono e pseudoparalelo nas respostas de consulta associadas a cada evento emitido pelo Flux<WebCustomer>.

  3. Compile e execute o CosmosSample.java no IDE ou execute o programa no terminal usando:

    mvn clean package
    mvn spring-boot:run
    

    No terminal, a saída deverá ser semelhante a esta:

    INFO: - WebCustomer is : maxaxam
    

Criar e chamar métodos de consulta personalizada

Os métodos de consulta personalizada são métodos de repositório do Spring Data com uma anotação @Query que especifica uma cadeia de caracteres de consulta, e essa cadeia contém espaços reservados para os argumentos do método. Desta vez, o nome do método não tem impacto sobre qual consulta é executada. A anotação @Query sinaliza para o Spring Data emitir uma consulta de linguagem SQL para o banco de dados subjacente, depois de preencher os espaços reservados de argumento com os valores dos argumentos do método.

  1. Criaremos um método de consulta personalizada que consulta todos os documentos com 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);
    

    Esse método de repositório declara ao Spring Data que você deseja um método que consulte lastName quando é chamado. O valor do argumento lastName será substituído pelo espaço reservado @lastName.

  2. Copie e cole o código a seguir no método run, após o código de consulta derivada.

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

    mvn clean package
    mvn spring-boot:run
    

    No terminal, a saída deverá ser semelhante a esta:

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

Nesta unidade, você aprendeu sobre consultas derivadas e personalizadas. Em seguida, você adicionou esses dois tipos de consulta ao seu aplicativo para recuperar registros de usuário.