Übung: Abfragen mit dem Java SDK in Azure Cosmos DB
Sie haben nun Dokumente in Ihrer Anwendung erstellt und können diese aus Ihrer Anwendung abrufen. Das Azure Cosmos DB Java SDK verwendet SQL-Abfragen. Das .NET SDK bietet zusätzliche Unterstützung für LINQ-Abfragen, aber das Java SDK verfügt über keine analogen Möglichkeiten. Diese Lerneinheit konzentriert sich nicht auf die Ausführung von Abfragen im Portal, sondern auf die Ausführung von SQL-Abfragen in Ihrer Anwendung.
Hierbei werden die für Ihre Anwendung für Onlinehändler erstellten Benutzerdokumente verwendet, um diese Abfragen zu testen.
Ausführen von SQL-Abfragen
Im folgenden Beispiel wird gezeigt, wie eine Abfrage über Ihren Java-Code in SQL ausgeführt werden kann. Kopieren Sie den Code, und fügen Sie ihn am Ende der Datei CosmosApp.java ein.
/** * 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(); }
Beachten Sie in diesem Code, dass wir das deklarative Datenfluss-Programmiermodell von Project Reactor erneut verwenden. Dieses Mal verwenden wir es, um Abfrageantwortseiten asynchron zu verarbeiten. Wir zeigen einen asynchronen Ansatz, da es in realen Anwendungsfällen Hunderte oder Tausende von Antworten auf eine Abfrage geben kann. Das Aggregieren von Abfrageantworten kann ein CPU-intensiver Task sein, der von der verbesserten Threadeffizienz der asynchronen Programmierung profitiert.
Kurz gesagt: Hier ist ein hoher Durchsatz für das Verarbeiten von Abfrageantworten erforderlich bzw. ein hoher Seiten/Sekunde-Wert pro Thread.
queryitems
gibt dieCosmosPagedFlux
-InstanzpagedFluxResponse
zurück, undpagedFluxResponse.byPage(preferredPageSize)
erstellt eineFlux
-Instanz. Diese ist die Quelle asynchroner Seitenereignisse. Die Vorgangspipeline innerhalb von.flatMap( ... ).blockLast();
, die jeweils den von derFlux
-Instanz ausgegebenen Ereignissen zugeordnet ist, wird auf der Abfrageantwortseite asynchron und pseudoparallel ausgeführt.Kopieren Sie den folgenden Code, und fügen Sie ihn vor dem Code zur Löschung des Dokuments in Ihrer
basicOperations
-Methode ein.executeSimpleQuery("SELECT * FROM User WHERE User.lastName = 'Pindakova'");
Erstellen Sie CosmosApp.java in der IDE, und führen Sie das Programm aus, oder führen Sie das Programm im Terminal wie folgt aus:
mvn clean package mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"
Die Ausgabe im Terminal sollte ungefähr wie folgt aussehen:
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
Sie haben nun Dokumente in Ihrer Anwendung erstellt und können diese aus Ihrer Anwendung abrufen. Spring Data Azure Cosmos DB macht sowohl abgeleitete Abfragemethoden als auch benutzerdefinierte Abfragemethoden verfügbar. Beide Methoden basieren auf der SQL-Sprachabfragefunktion des zugrunde liegenden Azure Cosmos DB Java SDK v4. In dieser Lerneinheit geht es primär um die Ausführung von Spring Data Azure Cosmos DB-Abfragen aus der Anwendung, nicht aus dem Portal.
Zum Testen dieser Abfragen werden die WebCustomer
-Dokumente verwendet, die Sie für Ihre Anwendung für Onlinehändler erstellt haben.
Erstellen und Abrufen abgeleiteter Abfragemethoden
Abgeleitete Abfragemethoden sind Spring Data-Repositorymethoden ohne Implementierung. Stattdessen signalisiert der Methodenname Spring Data, dass jeder Methodenaufruf und die zugehörigen Argumente in eine Abfrage der zugrunde liegenden Datenbank übersetzt werden müssen. Ein Beispiel: Wenn Sie findById
mit Argumenten aufrufen, interpretiert Spring Data den Namen als „nach ID suchen“ und stellt eine Datenbankabfrage zusammen, die das von den Argumenten angegebene Dokument zurückgibt.
Spring Data Azure Cosmos DB enthält eine Reihe integrierter abgeleiteter Abfrage, wie beispielsweise findById
. In diesem Abschnitt soll gezeigt werden, wie Sie neue abgeleitete Abfragemethoden implementieren.
Wir erstellen eine abgeleitete Abfragemethode, die alle Dokumente mit einem bestimmten Wert im Feld
firstName
abfragt. Navigieren Sie zu ReactWebCustomerRepository.java. Die folgende Methodendeklaration wird angezeigt:Flux<WebCustomer> findByFirstName(String firstName);
Diese Repositorymethode informiert Spring Data darüber, dass Sie eine Methode erstellen möchten, die beim Aufruf
firstName
abfragt. Sie erinnern sich sicher: DieWebCustomer
-Klasse beginnt mit einer@Container
-Anmerkung, diecontainerName
alsWebCustomers
angibt.findByFirstName
gibtFlux<WebCustomer>
zurück. Daher weiß Spring Data, dassWebCustomers
abgefragt werden soll, wenn diese Methode aufgerufen wird.Kopieren Sie den folgenden Code, und fügen Sie ihn vor dem Aufruf von
deleteWebCustomerDocument
in Ihrerun
-Methode ein.logger.info("Running derived query..."); Flux<WebCustomer> webCustomers = reactiveWebCustomerRepository.findByFirstName("Max"); webCustomers.flatMap(webCustomer -> { logger.info("- WebCustomer is : {}", webCustomer.getUserId()); return Mono.empty(); }).blockLast();
Beachten Sie in diesem Code, dass wir das deklarative Datenfluss-Programmiermodell von Project Reactor erneut verwenden. Dieses Mal verwenden wir es, um Abfrageantwortseiten asynchron zu verarbeiten. Wir zeigen einen asynchronen Ansatz, da es in realen Anwendungsfällen Hunderte oder Tausende von Antworten auf eine Abfrage geben kann. Das Aggregieren von Abfrageantworten kann ein CPU-intensiver Task sein, der von der verbesserten Threadeffizienz der asynchronen Programmierung profitiert.
Kurz gesagt: Hier ist ein hoher Durchsatz für das Verarbeiten von Abfrageantworten erforderlich bzw. ein hoher Antworten/Sekunde-Wert pro Thread.
findByFirstName
gibt dieFlux<WebCustomer>
-InstanzwebCustomers
zurück. Die Vorgangspipeline innerhalb von.flatMap( ... ).blockLast();
funktioniert asynchron und quasi-parallel zu den Abfrageantworten, die den einzelnen vonFlux<WebCustomer>
ausgegebenen Ereignissen zugeordnet sind.Erstellen Sie CosmosSample.java in der IDE, und führen Sie das Programm aus, oder führen Sie das Programm wie folgt im Terminal aus:
mvn clean package mvn spring-boot:run
Die Ausgabe im Terminal sollte ungefähr wie folgt aussehen:
INFO: - WebCustomer is : maxaxam
Erstellen und Aufrufen benutzerdefinierter Abfragemethoden
Benutzerdefinierte Abfragemethoden sind Spring Data-Repositorymethoden mit einer @Query
-Anmerkung, die eine Abfragezeichenfolge angibt. Die Abfragezeichenfolge enthält Platzhalter für die Methodenargumente. Diesmal hat der Methodenname keine Auswirkungen darauf, welche Abfrage ausgeführt wird. Die @Query
-Anmerkung signalisiert Spring Data, dass eine SQL-Sprachabfrage an die zugrunde liegende Datenbank ausgegeben werden soll, nachdem die Argumentplatzhalter mit den Werten der Methodenargumente aufgefüllt wurden.
Wir erstellen eine benutzerdefinierte Abfragemethode, die alle Dokumente mit einem bestimmten Wert im Feld
lastName
abfragt. Navigieren Sie zu ReactWebCustomerRepository.java. Die folgende Methodendeklaration wird angezeigt:@Query(value = "SELECT * FROM User WHERE User.lastName = @lastName") Flux<WebCustomer> findByLastName(@Param("lastName") String lastName);
Diese Repositorymethode informiert Spring Data darüber, dass Sie eine Methode erstellen möchten, die beim Aufruf
lastName
abfragt. Das ArgumentlastName
wird durch den Platzhalter@lastName
ersetzt.Kopieren Sie den folgenden Code, und fügen Sie ihn nach dem abgeleiteten Abfragecode in Ihre
run
-Methode ein.logger.info("Running custom query..."); webCustomers = reactiveWebCustomerRepository.findByLastName("Axam"); webCustomers.flatMap(webCustomer -> { logger.info("- WebCustomer is : {}", webCustomer.getUserId()); return Mono.empty(); }).blockLast();
Erstellen Sie CosmosSample.java in der IDE, und führen Sie das Programm aus, oder führen Sie das Programm wie folgt im Terminal aus:
mvn clean package mvn spring-boot:run
Die Ausgabe im Terminal sollte ungefähr wie folgt aussehen:
INFO: Running derived query... INFO: - WebCustomer is : maxaxam INFO: Running custom query... INFO: - WebCustomer is : maxaxam
In dieser Einheit haben Sie abgeleitete und benutzerdefinierte Abfragen kennengelernt. Anschließend haben Sie Ihrer Anwendung beide Abfragetypen hinzugefügt, um Benutzerdatensätze abzurufen.