Ćwiczenie — wykonywanie zapytań za pomocą zestawu SDK Java usługi Azure Cosmos DB

Ukończone

Po utworzeniu dokumentów w aplikacji utwórzmy do nich zapytania z poziomu aplikacji. Zestaw SDK Java usługi Azure Cosmos DB używa zapytań SQL. Zestaw SDK .NET obsługuje dodatkowo zapytania LINQ, ale w zestawie SDK Java nie ma takiej opcji. W tej lekcji skoncentrujemy się na wykonywaniu zapytań SQL z poziomu aplikacji, a nie z poziomu portalu.

Do przetestowania tych zapytań użyjemy dokumentów użytkownika utworzonych na potrzeby Twojej aplikacji sklepu internetowego.

Uruchamianie zapytań SQL

  1. Ten przykład pokazuje, jak można wykonać zapytanie w środowisku SQL z poziomu kodu Java. Skopiuj kod i dodaj go na końcu pliku 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();
    }
    

    Zauważ, że w tym kodzie znowu korzystamy z modelu programowania deklaratywnego przepływu danych biblioteki Project Reactor. Tym razem używamy go do asynchronicznej obsługi stron odpowiedzi na zapytania. Pokazujemy podejście asynchroniczne, ponieważ w rzeczywistej sytuacji mogą być setki lub tysiące odpowiedzi na zapytanie. Agregacja odpowiedzi na zapytanie może być zadaniem intensywnie wykorzystującym procesor, a zwiększona wydajność wątków programowania asynchronicznego podniesie jego wydajność.

    Krótko mówiąc, zależy nam na wysokiej przepływności obsługi odpowiedzi na zapytania, czyli dużej liczbie stron na sekundę na wątek. Metoda queryitems zwraca wystąpienie klasy CosmosPagedFlux o nazwie pagedFluxResponse, a metoda pagedFluxResponse.byPage(preferredPageSize) tworzy wystąpienie Flux będące źródłem asynchronicznych zdarzeń strony. Potok operacji wewnątrz elementu .flatMap( ... ).blockLast(); działa asynchronicznie i pseudo-równolegle na stronie odpowiedzi na zapytanie skojarzonej z każdym zdarzeniem emitowanym przez wystąpienie Flux.

  2. Skopiuj poniższy kod i wklej go do metody basicOperations przed kodem usuwania dokumentu.

    executeSimpleQuery("SELECT * FROM User WHERE User.lastName = 'Pindakova'");
    
  3. Skompiluj i uruchom plik CosmosApp.java w środowisku IDE lub uruchom program w terminalu przy użyciu polecenia:

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

    W terminalu dane wyjściowe powinny wyglądać mniej więcej tak:

    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
    

Po utworzeniu dokumentów w aplikacji utwórzmy do nich zapytania z poziomu aplikacji. Projekt Spring Data w usłudze Azure Cosmos DB uwidacznia zarówno pochodne metody zapytania, jak i niestandardowe metody zapytania — a oba te rodzaje korzystają z funkcji zapytań języka SQL podstawowego zestawu Java SDK v4 w usłudze Azure Cosmos DB. W tej lekcji skoncentrujemy się na wykonywaniu zapytań projektu Spring Data w usłudze Azure Cosmos DB z poziomu aplikacji, a nie z poziomu portalu.

Do przetestowania tych zapytań użyjemy dokumentów klienta WebCustomer utworzonych na potrzeby Twojej aplikacji sklepu internetowego.

Tworzenie i wywoływanie metod zapytań pochodnych

Metody zapytań pochodnych to metody repozytorium Spring Data bez implementacji; w zamian nazwa metody informuje projekt Spring Data o konieczności przetłumaczenia wszystkich wywołań metody i ich argumentów na zapytanie w podstawowej bazie danych. Na przykład w przypadku wywołania elementu findById z pewnymi argumentami projekt Spring Data odczytuje nazwę metody jako „znajdowanie według identyfikatora” i tworzy zapytanie bazy danych, które zwraca dokument określony przez argumenty.

Projekt Spring Data w usłudze Azure Cosmos DB zawierają szereg wbudowanych metod zapytań pochodnych, w tym findById. W tej sekcji pokazano, jak zaimplementować nowe metody zapytań pochodnych.

  1. Utworzymy metodę zapytań pochodnych, która wysyła zapytania do wszystkich dokumentów z określoną wartością pola firstName. Przejdź do ReactiveWebCustomerRepository.java. Zostanie wyświetlona następująca deklaracja metody:

    Flux<WebCustomer> findByFirstName(String firstName);
    

    Ta metoda repozytorium deklaruje w projekcie Spring Data, że potrzebujesz metody, która po wywołaniu wykonuje zapytanie dotyczące elementu firstName. Przypomnij sobie, że klasa WebCustomer rozpoczęła się adnotacją @Container określającą nazwę containerName jako WebCustomers. Ponieważ element findByFirstName zwraca wartość Flux<WebCustomer>, projekt Spring Data wie, że ma wykonać zapytanie o element WebCustomers po wywołaniu tej metody.

  2. Skopiuj poniższy kod i wklej go do metody run przed wywołaniem elementu 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();
    

    Zauważ, że w tym kodzie znowu korzystamy z modelu programowania deklaratywnego przepływu danych biblioteki Project Reactor. Tym razem używamy go do asynchronicznej obsługi stron odpowiedzi na zapytania. Pokazujemy podejście asynchroniczne, ponieważ w rzeczywistej sytuacji mogą być setki lub tysiące odpowiedzi na zapytanie. Agregacja odpowiedzi na zapytanie może być zadaniem intensywnie wykorzystującym procesor, a zwiększona wydajność wątków programowania asynchronicznego podniesie jego wydajność.

    Krótko mówiąc, zależy nam na wysokiej przepływności obsługi odpowiedzi na zapytania, czyli dużej liczbie odpowiedzi na sekundę na wątek. Instrukcja findByFirstName zwraca wystąpienie Flux<WebCustomer> dla elementu webCustomers. Potok operacji wewnątrz elementu .flatMap( ... ).blockLast(); działa asynchronicznie i pseudo-równolegle w odpowiedziach na zapytanie skojarzonych z każdym zdarzeniem emitowanym przez obiekt Flux<WebCustomer>.

  3. Skompiluj i uruchom plik CosmosSample.java w środowisku IDE lub uruchom program w terminalu przy użyciu polecenia:

    mvn clean package
    mvn spring-boot:run
    

    W terminalu dane wyjściowe powinny wyglądać mniej więcej tak:

    INFO: - WebCustomer is : maxaxam
    

Tworzenie i wywoływanie metod zapytań niestandardowych

Metody zapytań niestandardowych to metody Spring Data z adnotacją @Query określającą ciąg zapytania — a ciąg zapytania zawiera symbole zastępcze dla argumentów metody. Tym razem nazwa metody nie ma wpływu na to, jakie zapytanie jest wykonywane. Adnotacja @Query informuje projekt Spring Data o konieczności utworzenia zapytania języka SQL w podstawowej bazie danych po wypełnieniu symboli zastępczych argumentu wartościami argumentów metody.

  1. Utworzymy metodę zapytań niestandardowych, która wysyła zapytania do wszystkich dokumentów z określoną wartością pola lastName. Przejdź do ReactiveWebCustomerRepository.java. Zostanie wyświetlona następująca deklaracja metody:

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

    Ta metoda repozytorium deklaruje w projekcie Spring Data, że potrzebujesz metody, która po wywołaniu wykonuje zapytanie dotyczące elementu lastName. Wartość argumentu lastName zostanie zastąpiona symbolem zastępczym @lastName.

  2. Skopiuj poniższy kod i wklej go do metody run po kodzie zapytania pochodnego.

    logger.info("Running custom query...");
    webCustomers = reactiveWebCustomerRepository.findByLastName("Axam");
    webCustomers.flatMap(webCustomer -> {
        logger.info("- WebCustomer is : {}", webCustomer.getUserId());
        return Mono.empty();
    }).blockLast();
    
  3. Skompiluj i uruchom plik CosmosSample.java w środowisku IDE lub uruchom program w terminalu przy użyciu polecenia:

    mvn clean package
    mvn spring-boot:run
    

    W terminalu dane wyjściowe powinny wyglądać mniej więcej tak:

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

W tej lekcji przedstawiono informacje o zapytaniach pochodnych i niestandardowych. Dodaliśmy też do aplikacji obydwa typy zapytań w celu pobrania rekordów użytkowników.