Cvičení – dotazování pomocí sady Azure Cosmos DB Java SDK

Dokončeno

Když jste vytvořili ve své aplikaci dokumenty, můžeme se na ně teď z aplikace zkusit dotázat. Sada Azure Cosmos DB Java SDK využívá dotazy SQL. V sadě .NET SDK je dodatečná podpora dotazů LINQ, sada Java SDK ale nic podobného neobsahuje. Tato lekce se zaměřuje na spouštění dotazů SQL z aplikace místo z portálu.

K testování těchto dotazů použijeme dokumenty uživatele, které jste vytvořili pro aplikaci online prodejce.

Spuštění dotazů SQL

  1. Následující ukázka znázorňuje, jak lze v kódu v Javě provést dotaz SQL. Zkopírujte tento kód a přidejte ho na konec souboru 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();
    }
    

    Při zkoumání tohoto kódu si všimnete, že znovu využíváme programovací model deklarativního toku dat projektu Reactor. Tentokrát s jeho využitím asynchronně zpracováváme stránky s odpověďmi na dotazy. Asynchronní přístup ukazujeme, protože při reálném použití mohou na dotaz existovat stovky nebo tisíce odpovědí. Agregace odpovědí na dotaz může být úloha s velkými nároky na procesor, která těží z lepší efektivity vláken při asynchronním programování.

    Chceme zkrátka dosáhnout vysoké propustnosti při zpracování odpovědí na dotazy neboli vysokého počtu stránek za sekundu na vlákno. queryitems vrátí instanci CosmosPagedFlux pagedFluxResponse a pagedFluxResponse.byPage(preferredPageSize) vytvoří instanci Flux, což je zdroj asynchronních událostí stránky. Kanál operací uvnitř .flatMap( ... ).blockLast(); zpracovává stránku s odpovědmi na dotaz, která je přidružena ke každé události vydávané instancí Flux, asynchronně a pseudoparalelně.

  2. Následující kód zkopírujte a vložte do metody basicOperations před kód pro odstranění dokumentu.

    executeSimpleQuery("SELECT * FROM User WHERE User.lastName = 'Pindakova'");
    
  3. Sestavte a spusťte program CosmosApp.java v integrovaném vývojovém prostředí, nebo ho spusťte v terminálu příkazem:

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

    V terminálu by měl výstup vypadat zhruba následovně:

    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
    

Když jste vytvořili ve své aplikaci dokumenty, můžeme se na ně teď z aplikace zkusit dotázat. Spring Data Azure Cosmos DB zpřístupňuje jak metody odvozených dotazů, tak metody vlastních dotazů, přičemž oba typy využívají schopnost dotazování v jazyce SQL podkladové sady Azure Cosmos DB Java SDK verze 4. Tato lekce se zaměřuje na spouštění dotazů Spring Data Azure Cosmos DB z aplikace místo z portálu.

K testování těchto dotazů použijeme dokumenty WebCustomer, které jste vytvořili pro aplikaci online prodejce.

Vytváření a volání metod odvozených dotazů

Metody odvozených dotazů jsou metody úložiště Spring Data bez implementace; název metody místo toho modelu Spring Data signalizuje, aby přeložil jednotlivá volání metod a jejich argumenty na dotaz vůči podkladové databázi. Když například zavoláte findById s určitými argumenty, přečte Spring Data název této metody jako „najít podle ID“ a sestaví databázový dotaz, který vrátí dokument určený těmito argumenty.

Spring Data Azure Cosmos DB obsahuje množství předdefinovaných metod odvozených dotazů včetně findById. V této části si ukážeme, jak implementovat nové metody odvozených dotazů.

  1. Vytvoříme metodu odvozeného dotazu, která se dotazuje na všechny dokumenty, které mají určitou hodnotu v poli firstName. Přejděte na ReactiveWebCustomerRepository.java. Zobrazí se následující deklarace metody:

    Flux<WebCustomer> findByFirstName(String firstName);
    

    Tato metoda úložiště modelu Spring Data deklaruje, že chcete metodu, která se při volání dotazuje na firstName. Vzpomeňte si, že třída WebCustomer začínala anotací @Container, která containerName specifikuje jako WebCustomers. Protože findByFirstName vrací Flux<WebCustomer>, model Spring Data ví, že má při volání této metody dotazovat WebCustomers.

  2. Následující kód zkopírujte a vložte do metody run před volání 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();
    

    Při zkoumání tohoto kódu si všimnete, že znovu využíváme programovací model deklarativního toku dat projektu Reactor. Tentokrát s jeho využitím asynchronně zpracováváme stránky s odpověďmi na dotazy. Asynchronní přístup ukazujeme, protože při reálném použití mohou na dotaz existovat stovky nebo tisíce odpovědí. Agregace odpovědí na dotaz může být úloha s velkými nároky na procesor, která těží z lepší efektivity vláken při asynchronním programování.

    Chceme zkrátka dosáhnout vysoké propustnosti při zpracování odpovědí na dotazy neboli vysokého počtu odpovědí za sekundu na vlákno. findByFirstName vrací instanci Flux<WebCustomer> pro webCustomers. Kanál operací uvnitř .flatMap( ... ).blockLast(); zpracovává odpovědi na dotazy přidružené k jednotlivým událostem, které vydává Flux<WebCustomer>, asynchronně a pseudoparalelně.

  3. Sestavte a spusťte CosmosSample.java v integrovaném vývojovém prostředí, nebo program spusťte v terminálu těmito příkazy:

    mvn clean package
    mvn spring-boot:run
    

    V terminálu by měl výstup vypadat zhruba následovně:

    INFO: - WebCustomer is : maxaxam
    

Vytváření a volání metod vlastních dotazů

Metody vlastních dotazů jsou metody úložiště Spring Data s anotací @Query určující řetězec dotazu, přičemž řetězec dotazu obsahuje zástupné symboly pro argumenty metody. Název metody tentokrát nemá žádný vliv na to, jaký dotaz se provede. Anotace @Query modelu Spring Data signalizuje, aby po vyplnění zástupných argumentů hodnotami argumentů metody vydal dotaz v jazyce SQL vůči podkladové databázi.

  1. Vytvoříme metodu vlastního dotazu, která se dotazuje na všechny dokumenty, které mají určitou hodnotu v poli lastName. Přejděte na ReactiveWebCustomerRepository.java. Zobrazí se následující deklarace metody:

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

    Tato metoda úložiště modelu Spring Data deklaruje, že chcete metodu, která se při volání dotazuje na lastName. Zástupný symbol @lastName bude nahrazen hodnotou argumentu lastName.

  2. Následující kód zkopírujte a vložte do metody run za kód odvozeného dotazu.

    logger.info("Running custom query...");
    webCustomers = reactiveWebCustomerRepository.findByLastName("Axam");
    webCustomers.flatMap(webCustomer -> {
        logger.info("- WebCustomer is : {}", webCustomer.getUserId());
        return Mono.empty();
    }).blockLast();
    
  3. Sestavte a spusťte CosmosSample.java v integrovaném vývojovém prostředí, nebo program spusťte v terminálu těmito příkazy:

    mvn clean package
    mvn spring-boot:run
    

    V terminálu by měl výstup vypadat zhruba následovně:

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

V této lekci jste se dozvěděli o odvozených a vlastních dotazech. Potom jste do aplikace přidali oba typy dotazů, abyste získali záznamy uživatelů.