Ćwiczenie — wykonywanie zapytań za pomocą zestawu SDK Java usługi Azure Cosmos DB
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
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 klasyCosmosPagedFlux
o nazwiepagedFluxResponse
, a metodapagedFluxResponse.byPage(preferredPageSize)
tworzy wystąpienieFlux
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ąpienieFlux
.Skopiuj poniższy kod i wklej go do metody
basicOperations
przed kodem usuwania dokumentu.executeSimpleQuery("SELECT * FROM User WHERE User.lastName = 'Pindakova'");
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.
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 klasaWebCustomer
rozpoczęła się adnotacją@Container
określającą nazwęcontainerName
jakoWebCustomers
. Ponieważ elementfindByFirstName
zwraca wartośćFlux<WebCustomer>
, projekt Spring Data wie, że ma wykonać zapytanie o elementWebCustomers
po wywołaniu tej metody.Skopiuj poniższy kod i wklej go do metody
run
przed wywołaniem elementudeleteWebCustomerDocument
.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ąpienieFlux<WebCustomer>
dla elementuwebCustomers
. 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 obiektFlux<WebCustomer>
.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.
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ść argumentulastName
zostanie zastąpiona symbolem zastępczym@lastName
.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();
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.