練習 - 使用 Azure Cosmos DB Java SDK 進行查詢
既然您已在應用程式中建立文件,讓我們從您的應用程式中查詢這些文件。 Azure Cosmos DB Java SDK 會使用 SQL 查詢。 .NET SDK 具有適用於 LINQ 查詢的額外支援,但 Java SDK 並沒有任何對應項目。 本單元將專注於從應用程式執行 SQL 查詢,而非使用入口網站。
我們將使用您為線上零售商應用程式建立的使用者文件來測試這些查詢。
執行 SQL 查詢
下列範例顯示如何從 Java 程式碼以 SQL 來執行查詢。 複製程式碼,並將其新增至 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(); }
請注意,在此程式碼中,我們會再次使用 Project Reactor 的宣告式資料流程程式設計模型。 這一次,我們會加以使用來以非同步方式處理查詢回應頁面。 我們會示範非同步方法,因為在現實使用案例中,查詢可能會有數以百計甚至千計的回應。 彙總查詢回應可能會是需要密集使用 CPU 的工作,而這類工作能夠受益於非同步程式設計更佳的執行緒效率。
簡而言之,我們想要處理查詢回應的高輸送量,也就是較高的每個執行緒每秒頁數。
queryitems
會傳回CosmosPagedFlux
執行個體pagedFluxResponse
,而pagedFluxResponse.byPage(preferredPageSize)
則會建立作為非同步頁面事件來源的Flux
執行個體。.flatMap( ... ).blockLast();
內的作業管線會以非同步方式運作,並在與由Flux
執行個體所發出的每個事件相關聯的查詢回應頁面上,以虛擬平行的方式運作。複製下列程式碼,並將其貼到文件刪除程式碼「之前」的
basicOperations
方法中。executeSimpleQuery("SELECT * FROM User WHERE User.lastName = 'Pindakova'");
在 IDE 中建置並執行 CosmosApp.java,或是使用下列指令碼在終端機中執行該程式:
mvn clean package mvn exec:java -Dexec.mainClass="com.azure.cosmos.examples.mslearnbasicapp.CosmosApp"
在終端機中,輸出看起來應該像這樣:
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
既然您已在應用程式中建立文件,讓我們從您的應用程式中查詢這些文件。 Spring Data Azure Cosmos DB 會公開這兩個衍生查詢方法,以及自訂的查詢方法;兩者都是以底層 Azure Cosmos DB Java SDK v4 的 SQL 語言查詢功能為基礎建置。 此單元將著重在從應用程式執行 Spring Data Azure Cosmos DB 查詢,而非使用入口網站。
我們將使用您為線上零售商應用程式建立的 WebCustomer
文件來測試這些查詢。
建立及呼叫衍生查詢方法
「衍生查詢方法」是沒有實作的 Spring Data 存放庫方法;相反地,該方法名稱會通知 Spring Data 將每個方法呼叫及其引數轉譯成底層資料庫上的查詢。 例如,當您搭配某些引數呼叫 findById
時,Spring Data 會將方法名稱讀取為 "find by ID" (依識別碼搜尋),並組合出會傳回引數所指定文件的資料庫查詢。
Spring Data Azure Cosmos DB 包含數個內建的「衍生查詢方法」,其中包括 findById
。 在此節中,我們將說明如何實作新的衍生查詢方法。
我們將會建立衍生查詢方法,其會查詢針對
firstName
欄位具有特定值的所有文件。 瀏覽至 ReactiveWebCustomerRepository.java。 您會看到下列方法宣告:Flux<WebCustomer> findByFirstName(String firstName);
此存放庫方法會向 Spring Data 宣告您想要在呼叫時會查詢
firstName
的方法。 您應該還記得,WebCustomer
類別的開頭是以將containerName
指定為WebCustomers
的@Container
註釋。 由於findByFirstName
會傳回Flux<WebCustomer>
,Spring Data 知道要在呼叫此方法時查詢WebCustomers
。複製下列程式碼,並將其貼到您
run
方法中位於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();
請注意,在此程式碼中,我們會再次使用 Project Reactor 的宣告式資料流程程式設計模型。 這一次,我們會加以使用來以非同步方式處理查詢回應頁面。 我們會示範非同步方法,因為在現實使用案例中,查詢可能會有數以百計甚至千計的回應。 彙總查詢回應可能會是需要密集使用 CPU 的工作,而這類工作能夠受益於非同步程式設計更佳的執行緒效率。
簡而言之,我們想要處理查詢回應的高輸送量,也就是較高的每個執行緒每秒回應數。
findByFirstName
會傳回Flux<WebCustomer>
執行個體webCustomers
。.flatMap( ... ).blockLast();
內的作業管線會在與每個由Flux<WebCustomer>
所發出事件建立關聯的查詢回應上,以非同步方式且虛擬平行的方式運作。在 IDE 中建置並執行 CosmosSample.java,或是使用下列指令碼在終端中執行該程式:
mvn clean package mvn spring-boot:run
在終端機中,輸出看起來應該像這樣:
INFO: - WebCustomer is : maxaxam
建立及呼叫自訂查詢方法
「自訂查詢方法」是 Spring Data 存放庫方法,其具有指定查詢字串的 @Query
註釋,而查詢字串則包含方法引數的預留位置。 這一回,方法名稱對於所執行的查詢並沒有任何影響。 @Query
註釋會通知 Spring Data 在以方法引數的值填入引數預留位置「之後」,向底層資料庫發出 SQL 語言查詢。
我們將會建立自訂查詢方法,其會查詢針對
lastName
欄位具有特定值的所有文件。 瀏覽至 ReactiveWebCustomerRepository.java。 您會看到下列方法宣告:@Query(value = "SELECT * FROM User WHERE User.lastName = @lastName") Flux<WebCustomer> findByLastName(@Param("lastName") String lastName);
此存放庫方法會向 Spring Data 宣告您想要在呼叫時會查詢
lastName
的方法。lastName
引數值將會取代@lastName
預留位置。複製下列程式碼,並將其貼到您
run
方法中位於衍生查詢程式碼之後的位置。logger.info("Running custom query..."); webCustomers = reactiveWebCustomerRepository.findByLastName("Axam"); webCustomers.flatMap(webCustomer -> { logger.info("- WebCustomer is : {}", webCustomer.getUserId()); return Mono.empty(); }).blockLast();
在 IDE 中建置並執行 CosmosSample.java,或是使用下列指令碼在終端中執行該程式:
mvn clean package mvn spring-boot:run
在終端機中,輸出看起來應該像這樣:
INFO: Running derived query... INFO: - WebCustomer is : maxaxam INFO: Running custom query... INFO: - WebCustomer is : maxaxam
在此單元中,您已了解衍生及自訂查詢。 接著,您已將這兩種查詢類型新增至您的應用程式以擷取使用者記錄。