Gyakorlat – Lekérdezés az Azure Cosmos DB Java SDK használatával

Befejeződött

Miután létrehozott néhány dokumentumot az alkalmazásában, le is kérdezheti azokat onnan. Az Azure Cosmos DB Java SDK SQL-lekérdezéseket használ. A .NET SDK további LINQ-lekérdezéstámogatással rendelkezik, a Java SDK azonban nem rendelkezik analóg verzióval. Ez a lecke az SQL-lekérdezéseknek nem a portálon, hanem az alkalmazásból történő futtatására koncentrál.

A lekérdezéseket az online kereskedelmi alkalmazásához készített felhasználói dokumentumok használatával fogjuk tesztelni.

SQL-lekérdezések futtatása

  1. A következő példa bemutatja, hogyan hajtható végre egy lekérdezés SQL-ben a Java-kódból. Másolja ki a kódot, és szúrja be a CosmosApp.java fájl végére.

    /**
     * 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();
    }
    

    Ebben a kódban ismét a Project Reactor deklaratív adatfolyam-programozási modelljét használjuk. Ezúttal ezzel aszinkron módon kezeljük a lekérdezés válaszoldalait. Azért aszinkron megközelítést alkalmazunk, mert egy valós használati esetben több száz vagy akár több ezer válasz is érkezhet egy lekérdezésre. A lekérdezésekre kapott válaszok összesítése CPU-igényes feladat lehet, amelynek előnyt jelent az aszinkron programozás nagyobb szálhatékonysága.

    Röviden, azt szeretnénk, hogy a lekérdezések válaszainak kezelése nagy sebességgel, tehát másodpercenként és szálanként sok oldallal történjen. A queryitems a CosmosPagedFluxpagedFluxResponse-példányt adja vissza, a pagedFluxResponse.byPage(preferredPageSize) pedig létrehoz egy Flux példányt, amely az aszinkron oldalesemények forrása. A .flatMap( ... ).blockLast(); szakaszban lévő műveleti folyamat aszinkron és pszeudo-párhuzamos módon működik a Flux példány által kiadott egyes eseményekhez tartozó lekérdezési válaszoldalakon.

  2. Másolja át az alábbi kódot a basicOperations metódusba, a dokumentumot törlő kód elé.

    executeSimpleQuery("SELECT * FROM User WHERE User.lastName = 'Pindakova'");
    
  3. Fordítsa le és futtassa a CosmosApp.java alkalmazást a fejlesztőkörnyezetben, vagy hajtsa végre a programot a terminálban a következő módon:

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

    A terminálon az alábbihoz hasonló kimenetnek kell megjelennie:

    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
    

Miután létrehozott néhány dokumentumot az alkalmazásában, le is kérdezheti azokat onnan. A Spring Data Azure Cosmos DB a származtatott és az egyéni lekérdezési metódusokat is elérhetővé teszi – ezek mindegyike a hátterükben álló Azure Cosmos DB Java SDK v4 SQL-nyelvi lekérdezési képességeire épül. Ez a lecke az Spring Data Azure Cosmos DB-lekérdezéseknek nem a portálon, hanem az alkalmazásból történő futtatására koncentrál.

A lekérdezéseket az online kereskedelmi alkalmazásához készített WebCustomer dokumentumok használatával fogjuk tesztelni.

Származtatott lekérdezési metódusok létrehozása és hívása

A származtatott lekérdezési metódusok a Spring Data-kódtár implementáció nélküli metódusai. Ehelyett a metódus neve jelzi a Spring Data számára, hogy fordítsa le az egyes metódusokat és azok argumentumait a mögöttes adatbázis lekérdezéseivé. Például a findById argumentumokkal történő hívásakor a Spring Data a „find by ID” formában olvassa a metódus nevét, és olyan adatbázis-lekérdezést állít össze, amely az argumentumokkal megadott dokumentumot adja vissza.

A Spring Data Azure Cosmos DB számos beépített származtatott lekérdezési metódust tartalmaz, ezek egyike a findById. Ebben a szakaszban az új származtatott lekérdezési metódusok implementálását mutatjuk be.

  1. Létrehozunk egy származtatott lekérdezési metódust, amely a firstName mező egy bizonyos értékével rendelkező összes dokumentumot lekérdezi. Lépjen a ReactiveWebCustomerRepository.java. A következő metódusdeklaráció jelenik meg:

    Flux<WebCustomer> findByFirstName(String firstName);
    

    Ez az adattármetódus deklarálja a Spring Data számára, hogy olyan metódust szeretne, amely a hívásakor a firstName alapján végez lekérdezést. Mint tudja, a WebCustomer osztály egy @Container bejegyzéssel kezdődik, amely a containerNameWebCustomers értéket adja meg. Mivel a findByFirstName a Flux<WebCustomer> értéket adja vissza, a Spring Data tudja, hogy ennek a metódusnak a hívásakor a WebCustomers adatbázist kell lekérdeznie.

  2. Másolja át az alábbi kódot a run metódusba, a hívása 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();
    

    Ebben a kódban ismét a Project Reactor deklaratív adatfolyam-programozási modelljét használjuk. Ezúttal ezzel aszinkron módon kezeljük a lekérdezés válaszoldalait. Azért aszinkron megközelítést alkalmazunk, mert egy valós használati esetben több száz vagy akár több ezer válasz is érkezhet egy lekérdezésre. A lekérdezésekre kapott válaszok összesítése CPU-igényes feladat lehet, amelynek előnyt jelent az aszinkron programozás nagyobb szálhatékonysága.

    Röviden, azt szeretnénk, hogy a lekérdezések válaszainak kezelése nagy sebességgel, tehát másodpercenként és szálanként sok válasszal történjen. A findByFirstName a Flux<WebCustomer>webCustomers-példányt adja vissza. A .flatMap( ... ).blockLast(); szakaszban lévő műveleti folyamat aszinkron és pszeudo-párhuzamos módon működik a Flux<WebCustomer> által kiadott egyes eseményekhez tartozó lekérdezési válaszokban.

  3. Fordítsa le és futtassa a CosmosSample.java alkalmazást a fejlesztőkörnyezetben, vagy hajtsa végre a programot a terminálban a következő módon:

    mvn clean package
    mvn spring-boot:run
    

    A terminálon az alábbihoz hasonló kimenetnek kell megjelennie:

    INFO: - WebCustomer is : maxaxam
    

Egyéni lekérdezési metódusok létrehozása és hívása

Az egyéni lekérdezési metódusok Spring Data-adattármetódusok egy lekérdezési sztringet megadó @Query bejegyzéssel – a lekérdezési sztring pedig helyőrzőket tartalmaz a metódus argumentumai számára. A metódus neve ezúttal nem befolyásolja, hogy milyen lekérdezés lesz végrehajtva. A @Query bejegyzés azt jelzi a Spring Data számára, hogy egy SQL-nyelvű lekérdezést adjon ki a mögöttes adatbázisba, miután az argumentumok helyőrzőit feltölti a metódus argumentumainak értékeivel.

  1. Létrehozunk egy egyéni lekérdezési metódust, amely a lastName mező egy bizonyos értékével rendelkező összes dokumentumot lekérdezi. Lépjen a ReactiveWebCustomerRepository.java. A következő metódusdeklaráció jelenik meg:

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

    Ez az adattármetódus deklarálja a Spring Data számára, hogy olyan metódust szeretne, amely a hívásakor a lastName alapján végez lekérdezést. A lastName argumentum értéke a @lastName helyőrzőbe lesz behelyettesítve.

  2. Másolja át az alábbi kódot a run metódusba, a származtatott lekérdezés kódja mögé.

    logger.info("Running custom query...");
    webCustomers = reactiveWebCustomerRepository.findByLastName("Axam");
    webCustomers.flatMap(webCustomer -> {
        logger.info("- WebCustomer is : {}", webCustomer.getUserId());
        return Mono.empty();
    }).blockLast();
    
  3. Fordítsa le és futtassa a CosmosSample.java alkalmazást a fejlesztőkörnyezetben, vagy hajtsa végre a programot a terminálban a következő módon:

    mvn clean package
    mvn spring-boot:run
    

    A terminálon az alábbihoz hasonló kimenetnek kell megjelennie:

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

Ebben a leckében a származtatott és az egyéni lekérdezésekkel ismerkedett meg. Ezután mindkét lekérdezéstípust hozzáadta az alkalmazáshoz, amellyel felhasználói rekordokat kért le.