Övning – Fråga med Java SDK för Azure Cosmos DB

Slutförd

Nu när du har skapat dokument i ditt program kan du skicka frågor mot dem från programmet. Java SDK för Azure Cosmos DB använder SQL-frågor. .NET SDK har ytterligare stöd för LINQ-frågor, men Java SDK är inte analogt. Den här lektionen handlar om att köra SQL-frågor från ditt program i stället för från portalen.

Du kan testa de här frågorna med hjälp av användardokumenten som du har skapat för ditt onlineförsäljningsprogram.

Köra SQL-frågor

  1. I följande exempel visas hur en fråga kan utföras i SQL från din Java-kod. Kopiera koden och lägg till den i slutet av CosmosApp.java-filen.

    /**
     * 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();
    }
    

    I den här koden ser du till att vi återanvänder Project Reactors programmeringsmodell för deklarativt dataflöde. Den här gången använder vi den för att hantera frågesvarssidor asynkront. Vi demonstrerar en asynkron metod eftersom det i ett verkligt användningsfall kan finnas hundratals eller tusentals svar på en fråga. Att aggregera svar på frågor kan vara en processorintensiv uppgift som har nytta av den ökade trådeffektiviteten vid asynkron programmering.

    I korthet vill vi ha ett högt dataflöde för hantering av frågesvar, eller ett högt antal sidor/sekund per tråd. queryitems returnerar CosmosPagedFlux-instansen pagedFluxResponse och pagedFluxResponse.byPage(preferredPageSize) skapar en Flux-instans som är en källa för asynkrona sidhändelser. Pipelinen för åtgärder i .flatMap( ... ).blockLast(); fungerar asynkront och pseudoparallellt på den frågesvarssida som är associerad med varje händelse som genereras av Flux-instansen.

  2. Kopiera och klistra in följande kod i metoden basicOperations, före koden för dokumentborttagning.

    executeSimpleQuery("SELECT * FROM User WHERE User.lastName = 'Pindakova'");
    
  3. Kompilera och kör CosmosApp.java i IDE eller kör programmet i terminalen med hjälp av:

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

    I terminalen bör utdata se ut ungefär så här:

    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
    

Nu när du har skapat dokument i ditt program kan du skicka frågor mot dem från programmet. Azure Cosmos DB för Spring Data tillgängliggör både härledda frågemetoder och anpassade frågemetoder – och båda dessa bygger på SQL-språkets frågefunktion i den underliggande Java SDK v4 för Azure Cosmos DB. Den här lektionen handlar om att köra Azure Cosmos DB-frågor för Spring Data från ditt program i stället för från portalen.

Vi kommer att använda WebCustomer-dokumenten som du skapade för ditt onlineförsäljningsprogram för att testa frågorna.

Skapa och anropa härledda frågemetoder

Härledda frågemetoder är Spring Data-lagringsplatsmetoder utan implementering. I stället signalerar metodnamnet till Spring Data att översätta varje metodanrop och dess argument till en fråga om den underliggande databasen. När du till exempel anropar findById med vissa argument, läser Spring Data metodnamnet som ”hitta efter ID” och sammanställer en databasfråga som returnerar det dokument som specificeras av argumenten.

Azure Cosmos DB för Spring Data innehåller ett antal inbyggda härledda frågemetoder, bland annat findById. I det här avsnittet visas hur du implementerar nya härledda frågemetoder.

  1. Vi kommer att skapa en härledd frågemetod som frågar alla dokument med ett visst värde för fältet firstName. Gå till ReactiveWebCustomerRepository.java. Följande metoddeklaration visas:

    Flux<WebCustomer> findByFirstName(String firstName);
    

    Den här lagringsplatsmetoden förklarar till Spring Data att du vill ha en metod som frågar på firstName när den anropas. Kom ihåg att WebCustomer-klassen började med en @Container-kommentar som anger containerName som WebCustomers. Eftersom findByFirstName returnerar Flux<WebCustomer>, är Spring Data programmerad för att fråga WebCustomers när den här metoden anropas.

  2. Kopiera och klistra in följande kod i din run-metod föredeleteWebCustomerDocument anropet.

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

    I den här koden ser du till att vi återanvänder Project Reactors programmeringsmodell för deklarativt dataflöde. Den här gången använder vi den för att hantera frågesvarssidor asynkront. Vi demonstrerar en asynkron metod eftersom det i ett verkligt användningsfall kan finnas hundratals eller tusentals svar på en fråga. Att aggregera svar på frågor kan vara en processorintensiv uppgift som har nytta av den ökade trådeffektiviteten vid asynkron programmering.

    I korthet vill vi ha ett högt dataflöde för hantering av frågesvar, eller ett högt antal svar/sekund per tråd. findByFirstName returnerar Flux<WebCustomer>-instansen webCustomers. Pipelinen för åtgärder i .flatMap( ... ).blockLast(); fungerar asynkront och pseudoparallellt på de frågesvar som är associerade med varje händelse som genereras av Flux<WebCustomer>.

  3. Kompilera och kör CosmosSample.java i IDE eller kör programmet i terminalen med hjälp av:

    mvn clean package
    mvn spring-boot:run
    

    I terminalen bör utdata se ut ungefär så här:

    INFO: - WebCustomer is : maxaxam
    

Skapa och anropa anpassade frågemetoder

Anpassade frågemetoder är Spring Data-lagringsplatsmetoder med en @Query-kommentar som anger en frågesträng och frågesträngen innehåller platshållare för metodargumenten. Den här gången har metodnamnet ingen inverkan på vilken fråga som utförs. @Query-kommentaren signalerar Spring Data att skicka en SQL-språkfråga till den underliggande databasen, efter att ha fyllt i platshållarna för argumenten med värdena för metodargumenten.

  1. Vi kommer att skapa en anpassad frågemetod som frågar alla dokument som har ett visst värde för fältet lastName. Gå till ReactiveWebCustomerRepository.java. Följande metoddeklaration visas:

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

    Den här lagringsplatsmetoden förklarar till Spring Data att du vill ha en metod som frågar på lastName när den anropas. Värdet för argumentet lastName ersätts med platshållaren @lastName.

  2. Kopiera och klistra in följande kod i din run-metod, efter den härledda frågekoden.

    logger.info("Running custom query...");
    webCustomers = reactiveWebCustomerRepository.findByLastName("Axam");
    webCustomers.flatMap(webCustomer -> {
        logger.info("- WebCustomer is : {}", webCustomer.getUserId());
        return Mono.empty();
    }).blockLast();
    
  3. Kompilera och kör CosmosSample.java i IDE eller kör programmet i terminalen med hjälp av:

    mvn clean package
    mvn spring-boot:run
    

    I terminalen bör utdata se ut ungefär så här:

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

I den här lektionen har du lärt dig om härledda och anpassade frågor. Du har sedan lagt till båda frågetyperna i programmet för att hämta användarposter.