Ejercicio: Realización de consultas mediante el SDK de Java de Azure Cosmos DB

Completado

Ahora que ha creado documentos en la aplicación, vamos a consultarlos desde la aplicación. El SDK de Java de Azure Cosmos DB usa consultas SQL. En el SDK de .NET existe compatibilidad adicional con las consultas LINQ, pero el SDK de Java no tiene ningún elemento análogo. Esta unidad se centra en ejecutar consultas SQL desde la aplicación en vez de usar el portal.

Vamos a usar los documentos de usuario creados para la aplicación minorista en línea para probar estas consultas.

Ejecución de consultas SQL

  1. En el ejemplo siguiente se muestra cómo se podría realizar una consulta en SQL desde el código de Java. Copie el código y agréguelo al final del archivo 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();
    }
    

    En este código, observe que usamos una vez más el modelo de programación de flujo de datos declarativo de Project Reactor. Esta vez, se usa para administrar las páginas de respuesta de la consulta de forma asincrónica. Se muestra un enfoque asincrónico porque, en un caso de uso real, puede haber cientos o miles de respuestas a una consulta. La agregación de respuestas de consulta puede ser una tarea que consume muchos recursos de la CPU y que se beneficia de la mayor eficiencia de subprocesos de la programación asincrónica.

    En resumen, queremos un alto rendimiento para controlar las respuesta de las consultas, o un número alto de páginas/segundo por subproceso. queryitems devuelve la instancia pagedFluxResponse de CosmosPagedFlux y pagedFluxResponse.byPage(preferredPageSize) crea una instancia Flux que es un origen de eventos de página asincrónicos. La canalización de operaciones dentro de .flatMap( ... ).blockLast(); funciona de forma asincrónica y pseudoparalela en la página de respuesta de las consultas asociada a cada evento emitido por la instancia Flux.

  2. Copie el código siguiente en el método basicOperations y péguelo delante del código de eliminación del documento.

    executeSimpleQuery("SELECT * FROM User WHERE User.lastName = 'Pindakova'");
    
  3. Compile y ejecute CosmosApp.java en el IDE o ejecute el programa en el terminal usando:

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

    En el terminal, la salida debe tener un aspecto similar al siguiente:

    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
    

Ahora que ha creado documentos en la aplicación, vamos a consultarlos desde la aplicación. Spring Data para Azure Cosmos DB expone los métodos de consulta derivados, así como los métodos de consulta personalizados, y ambos se basan en la funcionalidad de consulta del lenguaje SQL del SDK de Java v4 de Azure Cosmos DB subyacente. Esta unidad se centra en ejecutar consultas de Spring Data para Azure Cosmos DB desde la aplicación en vez de usar el portal.

Vamos a usar los documentos WebCustomer creados para la aplicación minorista en línea para probar estas consultas.

Creación de métodos de consulta derivados y llamada a dichos métodos

Los métodos de consulta derivados son métodos de repositorio de Spring Data sin implementación; en su lugar, el nombre del método indica a Spring Data que traduzca cada llamada al método y sus argumentos en una consulta en la base de datos subyacente. Por ejemplo, cuando se llama a findById con algunos argumentos, Spring Data lee el nombre del método como "find by ID" y ensambla una consulta de base de datos que devuelve el documento especificado por los argumentos.

Spring Data para Azure Cosmos DB incluye una serie de métodos de consulta derivados integrados, como findById. En esta sección, se mostrará cómo implementar nuevos métodos de consulta derivados.

  1. Vamos a crear un método de consulta derivado que consulta todos los documentos que tienen un valor determinado para el campo firstName. Vaya a ReactiveWebCustomerRepository.java. Verá la siguiente declaración de método:

    Flux<WebCustomer> findByFirstName(String firstName);
    

    Este método del repositorio declara a Spring Data que desea que un método realice consultas en firstName cuando se llama a dicho método. Recuerde que la clase WebCustomer comenzó con una anotación @Container que especifica containerName como WebCustomers. Como findByFirstName devuelve Flux<WebCustomer>, Spring Data sabe consultar WebCustomers cuando se llama a este método.

  2. Copie el código siguiente y péguelo en el método run, antes de llamar a 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();
    

    En este código, observe que usamos una vez más el modelo de programación de flujo de datos declarativo de Project Reactor. Esta vez, se usa para administrar las páginas de respuesta de la consulta de forma asincrónica. Se muestra un enfoque asincrónico porque, en un caso de uso real, puede haber cientos o miles de respuestas a una consulta. La agregación de respuestas de consulta puede ser una tarea que consume muchos recursos de la CPU y que se beneficia de la mayor eficiencia de subprocesos de la programación asincrónica.

    En resumen, queremos un alto rendimiento para controlar las respuesta de las consultas, o un número alto de respuestas/segundo por subproceso. findByFirstName devuelve la instancia webCustomers de Flux<WebCustomer>. La canalización de operaciones dentro de .flatMap( ... ).blockLast(); funciona de forma asincrónica y pseudoparalela en las respuestas de las consultas asociadas a cada evento emitido por el objeto Flux<WebCustomer>.

  3. Compile y ejecute CosmosSample.java en el IDE o ejecute el programa en el terminal usando:

    mvn clean package
    mvn spring-boot:run
    

    En el terminal, la salida debe tener un aspecto similar al siguiente:

    INFO: - WebCustomer is : maxaxam
    

Creación de métodos de consulta personalizados y llamada a dichos métodos

Los métodos de consulta personalizados son métodos de repositorio de Spring Data con una anotación @Query que especifica una cadena de consulta, y esta última contiene marcadores de posición para los argumentos del método. Esta vez, el nombre del método no tiene ningún impacto en la consulta que se realiza. La anotación @Query indica a Spring Data que emita una consulta de lenguaje SQL a la base de datos subyacente, después de rellenar los marcadores de posición de los argumentos con los valores de los argumentos del método.

  1. Vamos a crear un método de consulta personalizado que consulta todos los documentos que tienen un valor determinado para el campo lastName. Vaya a ReactiveWebCustomerRepository.java. Verá la siguiente declaración de método:

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

    Este método del repositorio declara a Spring Data que desea que un método realice consultas en lastName cuando se llama a dicho método. El valor del argumento lastName se sustituirá por el marcador de posición @lastName.

  2. Copie el código siguiente y péguelo en el método run, después del código de la 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 y ejecute CosmosSample.java en el IDE o ejecute el programa en el terminal usando:

    mvn clean package
    mvn spring-boot:run
    

    En el terminal, la salida debe tener un aspecto similar al siguiente:

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

En esta unidad, ha obtenido información sobre las consultas derivadas y personalizadas. Después, ha agregado ambos tipos de consulta a la aplicación para recuperar los registros de usuario.