Delen via


Tips voor queryprestaties voor Azure Cosmos DB SDK's

VAN TOEPASSING OP: NoSQL

Azure Cosmos DB is een snelle, flexibele gedistribueerde database die naadloos kan worden geschaald met gegarandeerde latentie- en doorvoerniveaus. U hoeft geen belangrijke architectuurwijzigingen aan te brengen of complexe code te schrijven om uw database te schalen met Azure Cosmos DB. Omhoog en omlaag schalen is net zo eenvoudig als het maken van één API-aanroep. Zie containerdoorvoer inrichten of databasedoorvoer inrichten voor meer informatie.

Queryplan-aanroepen verminderen

Als u een query wilt uitvoeren, moet een queryplan worden gebouwd. Dit vertegenwoordigt in het algemeen een netwerkaanvraag voor de Azure Cosmos DB-gateway, die wordt toegevoegd aan de latentie van de querybewerking. Er zijn twee manieren om deze aanvraag te verwijderen en de latentie van de querybewerking te verminderen:

Query's met één partitie optimaliseren met optimistische directe uitvoering

Azure Cosmos DB NoSQL heeft een optimalisatie met de naam Optimistische directe uitvoering (ODE), waarmee de efficiëntie van bepaalde NoSQL-query's kan worden verbeterd. Query's waarvoor geen distributie is vereist, zijn met name query's die kunnen worden uitgevoerd op één fysieke partitie of met antwoorden waarvoor geen paginering is vereist. Query's waarvoor geen distributie is vereist, kunnen sommige processen, zoals het genereren van queryplannen aan de clientzijde en het herschrijven van query's, overslaan, waardoor de querylatentie en RU-kosten worden verminderd. Als u de partitiesleutel opgeeft in de aanvraag of query zelf (of slechts één fysieke partitie hebt), en de resultaten van uw query geen paginering vereisen, kan ODE uw query's verbeteren.

Notitie

Optimistische Direct Execution (ODE), dat verbeterde prestaties biedt voor query's waarvoor geen distributie is vereist, mag niet worden verward met de directe modus. Dit is een pad voor het verbinden van uw toepassing met back-endreplica's.

ODE is nu standaard beschikbaar en ingeschakeld in .NET SDK versie 3.38.0 en hoger. Wanneer u een query uitvoert en een partitiesleutel opgeeft in de aanvraag of query zelf, of uw database slechts één fysieke partitie heeft, kan uw queryuitvoering gebruikmaken van de voordelen van ODE. Als u ODE wilt uitschakelen, stelt u EnableOptimisticDirectExecution in op false in de QueryRequestOptions.

Query's met één partitie die group by-, ORDER BY-, DISTINCT- en aggregatiefuncties (zoals som, gemiddelde, min en max) gebruiken, kunnen aanzienlijk profiteren van het gebruik van ODE. In scenario's waarin de query gericht is op meerdere partities of nog steeds paginering vereist, kan de latentie van het queryantwoord en de RU-kosten hoger zijn dan zonder ODE te gebruiken. Daarom raden we u aan bij het gebruik van ODE het volgende te doen:

  • Geef de partitiesleutel op in de aanroep of query zelf.
  • Zorg ervoor dat de gegevensgrootte niet is gegroeid en dat de partitie is gesplitst.
  • Zorg ervoor dat uw queryresultaten geen paginering nodig hebben om het volledige voordeel van ODE te krijgen.

Hier volgen enkele voorbeelden van eenvoudige query's met één partitie die kunnen profiteren van ODE:

- SELECT * FROM r
- SELECT * FROM r WHERE r.pk == "value"
- SELECT * FROM r WHERE r.id > 5
- SELECT r.id FROM r JOIN id IN r.id
- SELECT TOP 5 r.id FROM r ORDER BY r.id
- SELECT * FROM r WHERE r.id > 5 OFFSET 5 LIMIT 3 

Er kunnen gevallen zijn waarbij query's met één partitie nog steeds distributie vereisen als het aantal gegevensitems in de loop van de tijd toeneemt en uw Azure Cosmos DB-database de partitie splitst. Voorbeelden van query's waar dit kan gebeuren zijn:

- SELECT Count(r.id) AS count_a FROM r
- SELECT DISTINCT r.id FROM r
- SELECT Max(r.a) as min_a FROM r
- SELECT Avg(r.a) as min_a FROM r
- SELECT Sum(r.a) as sum_a FROM r WHERE r.a > 0 

Sommige complexe query's kunnen altijd distributie vereisen, zelfs als er één partitie is gericht. Voorbeelden van dergelijke query's zijn:

- SELECT Sum(id) as sum_id FROM r JOIN id IN r.id
- SELECT DISTINCT r.id FROM r GROUP BY r.id
- SELECT DISTINCT r.id, Sum(r.id) as sum_a FROM r GROUP BY r.id
- SELECT Count(1) FROM (SELECT DISTINCT r.id FROM root r)
- SELECT Avg(1) AS avg FROM root r 

Het is belangrijk te weten dat ODE het queryplan mogelijk niet altijd ophaalt en daardoor niet in staat is om niet te worden toegestaan of uitgeschakeld voor niet-ondersteunde query's. Na het splitsen van partities komen dergelijke query's bijvoorbeeld niet meer in aanmerking voor ODE en worden deze daarom niet uitgevoerd omdat de evaluatie van queryplannen aan de clientzijde deze blokkeert. Om compatibiliteit/servicecontinuïteit te garanderen, is het essentieel om ervoor te zorgen dat alleen query's die volledig worden ondersteund in scenario's zonder ODE (dat wil gezegd, ze uitvoeren en het juiste resultaat produceren in de algemene case met meerdere partities) worden gebruikt met ODE.

Notitie

Het gebruik van ODE kan ertoe leiden dat er een nieuw type vervolgtoken wordt gegenereerd. Een dergelijk token wordt niet door de oudere SDK's door het ontwerp herkend en dit kan leiden tot een ongeldige vervolgtokenuitzondering. Als u een scenario hebt waarin tokens die zijn gegenereerd op basis van de nieuwere SDK's worden gebruikt door een oudere SDK, raden we u aan om een upgrade uit te voeren in twee stappen:

  • Voer een upgrade uit naar de nieuwe SDK en schakel ODE uit, beide als onderdeel van één implementatie. Wacht tot alle knooppunten zijn bijgewerkt.
    • Als u ODE wilt uitschakelen, stelt u EnableOptimisticDirectExecution in op false in de QueryRequestOptions.
  • Schakel ODE in als onderdeel van de tweede implementatie voor alle knooppunten.

Het genereren van lokale queryplannen gebruiken

De SQL SDK bevat een systeemeigen ServiceInterop.dll om query's lokaal te parseren en optimaliseren. ServiceInterop.dll wordt alleen ondersteund op het Windows x64-platform . De volgende typen toepassingen maken standaard gebruik van 32-bits hostverwerking. Als u hostverwerking wilt wijzigen in 64-bits verwerking, volgt u deze stappen op basis van het type toepassing:

  • Voor uitvoerbare toepassingen kunt u de hostverwerking wijzigen door het platformdoel in te stellen op x64 in het venster Projecteigenschappen op het tabblad Opbouwen .

  • Voor testprojecten op basis van VSTest kunt u hostverwerking wijzigen door De>standaardprocessorarchitectuur testinstellingen>als X64 te selecteren in het menu Visual Studio Test.

  • Voor lokaal geïmplementeerde ASP.NET-webtoepassingen kunt u hostverwerking wijzigen door de 64-bits versie van IIS Express te selecteren voor websites en projecten onder Extra>Opties>Projecten en Oplossingen>Web Projects.

  • Voor ASP.NET webtoepassingen die zijn geïmplementeerd in Azure, kunt u de verwerking van de host wijzigen door het 64-bits platform te selecteren in toepassingsinstellingen in Azure Portal.

Notitie

Nieuwe Visual Studio-projecten zijn standaard ingesteld op Elke CPU. U wordt aangeraden uw project in te stellen op x64 , zodat het niet overschakelt naar x86. Een project dat is ingesteld op Elke CPU , kan eenvoudig overschakelen naar x86 als er een x86-afhankelijkheid wordt toegevoegd.
ServiceInterop.dll moet zich in de map bevinden waaruit de SDK-DLL wordt uitgevoerd. Dit moet alleen een probleem zijn als u DLL's handmatig kopieert of aangepaste build-/implementatiesystemen hebt.

Query's met één partitie gebruiken

Voor query's die gericht zijn op een partitiesleutel door de eigenschap PartitionKey in QueryRequestOptions te stellen en geen aggregaties (inclusief Distinct, DCount, Group By) in te stellen. In dit voorbeeld wordt het partitiesleutelveld /state gefilterd op de waarde Washington.

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle' AND c.state = 'Washington'"
{
    // ...
}

U kunt desgewenst de partitiesleutel opgeven als onderdeel van het object aanvraagopties.

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Washington")}))
{
    // ...
}

Notitie

Voor query's tussen partities moet de SDK alle bestaande partities bezoeken om te controleren op resultaten. Hoe meer fysieke partities de container heeft, hoe langzamer ze mogelijk zijn.

Vermijd het opnieuw maken van de iterator onnodig

Wanneer alle queryresultaten door het huidige onderdeel worden gebruikt, hoeft u de iterator niet opnieuw te maken met de vervolgbewerking voor elke pagina. Maak de query altijd volledig leeg, tenzij de paginering wordt beheerd door een ander aanroepend onderdeel:

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Washington")}))
{
    while (feedIterator.HasMoreResults) 
    {
        foreach(MyItem document in await feedIterator.ReadNextAsync())
        {
            // Iterate through documents
        }
    }
}

De mate van parallelle uitvoering afstemmen

Voor query's kunt u de eigenschap QueryRequestOptions MaxConcurrency afstemmen om de beste configuraties voor uw toepassing te identificeren, met name als u query's tussen partities uitvoert (zonder filter op de waarde van de partitiesleutel). MaxConcurrency bepaalt het maximum aantal parallelle taken, dat wil gezegd, het maximum aantal partities dat parallel moet worden bezocht. Als u de waarde instelt op -1, kan de SDK de optimale gelijktijdigheid bepalen.

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { 
        PartitionKey = new PartitionKey("Washington"),
        MaxConcurrency = -1 }))
{
    // ...
}

Laten we aannemen dat

  • D = Standaard maximum aantal parallelle taken (= totaal aantal processors op de clientcomputer)
  • P = Door de gebruiker opgegeven maximum aantal parallelle taken
  • N = Aantal partities dat moet worden bezocht voor het beantwoorden van een query

Hieronder volgen gevolgen voor de werking van de parallelle query's voor verschillende waarden van P.

  • (P == 0) => Seriële modus
  • (P == 1) => Maximum van één taak
  • (P > 1) => Min (P, N) parallelle taken
  • (P < 1) => Min (N, D) parallelle taken

Het paginaformaat afstemmen

Wanneer u een SQL-query uitgeeft, worden de resultaten gesegmenteerd geretourneerd als de resultatenset te groot is.

Notitie

De MaxItemCount eigenschap mag niet alleen worden gebruikt voor paginering. Het belangrijkste gebruik is om de prestaties van query's te verbeteren door het maximum aantal items dat op één pagina wordt geretourneerd, te verminderen.

U kunt ook het paginaformaat instellen met behulp van de beschikbare Azure Cosmos DB SDK's. Met de eigenschap MaxItemCount kunt QueryRequestOptions u het maximum aantal items instellen dat moet worden geretourneerd in de opsommingsbewerking. Wanneer MaxItemCount deze is ingesteld op -1, vindt de SDK automatisch de optimale waarde, afhankelijk van de documentgrootte. Voorbeeld:

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { 
        PartitionKey = new PartitionKey("Washington"),
        MaxItemCount = 1000}))
{
    // ...
}

Wanneer een query wordt uitgevoerd, worden de resulterende gegevens verzonden binnen een TCP-pakket. Als u een te lage waarde MaxItemCountopgeeft, is het aantal benodigde ritten voor het verzenden van de gegevens in het TCP-pakket hoog, wat van invloed is op de prestaties. Dus als u niet zeker weet welke waarde u voor de MaxItemCount eigenschap wilt instellen, kunt u deze het beste instellen op -1 en de SDK de standaardwaarde laten kiezen.

De buffergrootte afstemmen

Parallelle query is ontworpen om resultaten vooraf op te halen terwijl de huidige batch met resultaten door de client wordt verwerkt. Met dit vooraf ophalen wordt de algehele latentie van een query verbeterd. De eigenschap MaxBufferedItemCount in QueryRequestOptions beperkt het aantal vooraf opgehaalde resultaten. Stel MaxBufferedItemCount in op het verwachte aantal geretourneerde resultaten (of een hoger getal) zodat de query het maximale voordeel van vooraf ophalen kan ontvangen. Als u deze waarde instelt op -1, bepaalt het systeem automatisch het aantal items dat moet worden gebufferd.

using (FeedIterator<MyItem> feedIterator = container.GetItemQueryIterator<MyItem>(
    "SELECT * FROM c WHERE c.city = 'Seattle'",
    requestOptions: new QueryRequestOptions() { 
        PartitionKey = new PartitionKey("Washington"),
        MaxBufferedItemCount = -1}))
{
    // ...
}

Vooraf ophalen werkt op dezelfde manier, ongeacht de mate van parallelle uitvoering, en er is één buffer voor de gegevens van alle partities.

Volgende stappen

Meer informatie over prestaties met behulp van de .NET SDK:

Queryplan-aanroepen verminderen

Als u een query wilt uitvoeren, moet een queryplan worden gebouwd. Dit vertegenwoordigt in het algemeen een netwerkaanvraag voor de Azure Cosmos DB-gateway, die wordt toegevoegd aan de latentie van de querybewerking.

Queryplancaching gebruiken

Het queryplan, voor een query die is gericht op één partitie, wordt op de client in de cache opgeslagen. Dit elimineert de noodzaak om de gateway aan te roepen om het queryplan op te halen na de eerste aanroep. De sleutel voor het queryplan in de cache is de SQL-queryreeks. U moet ervoor zorgen dat de query is geparametriseerd. Als dat niet het geval is, zal het opzoeken van de cache van het queryplan vaak een cachemisser zijn, omdat de querytekenreeks waarschijnlijk niet identiek is tussen aanroepen. Caching van queryplannen is standaard ingeschakeld voor Java SDK versie 4.20.0 en hoger en voor Spring Data Azure Cosmos DB SDK versie 3.13.0 en hoger.

Geparametriseerde query's met één partitie gebruiken

Voor geparametriseerde query's die zijn gericht op een partitiesleutel met setPartitionKey en CosmosQueryRequestOptions die geen aggregaties bevatten (waaronder Distinct, DCount, Group By), kan het queryplan worden vermeden:

CosmosQueryRequestOptions options = new CosmosQueryRequestOptions();
options.setPartitionKey(new PartitionKey("Washington"));

ArrayList<SqlParameter> paramList = new ArrayList<SqlParameter>();
paramList.add(new SqlParameter("@city", "Seattle"));
SqlQuerySpec querySpec = new SqlQuerySpec(
        "SELECT * FROM c WHERE c.city = @city",
        paramList);

//  Sync API
CosmosPagedIterable<MyItem> filteredItems = 
    container.queryItems(querySpec, options, MyItem.class);

//  Async API
CosmosPagedFlux<MyItem> filteredItems = 
    asyncContainer.queryItems(querySpec, options, MyItem.class);

Notitie

Voor query's tussen partities moet de SDK alle bestaande partities bezoeken om te controleren op resultaten. Hoe meer fysieke partities de container heeft, hoe traag ze kunnen zijn.

De mate van parallelle uitvoering afstemmen

Parallelle query's werken door gelijktijdig query's uit te voeren op meerdere partities. Gegevens van een afzonderlijke gepartitioneerde container worden echter serieel opgehaald met betrekking tot de query. Gebruik dus setMaxDegreeOfParallelism om CosmosQueryRequestOptions de waarde in te stellen op het aantal partities dat u hebt. Als u het aantal partities niet weet, kunt setMaxDegreeOfParallelism u een hoog getal instellen en kiest het systeem het minimum (aantal partities, door de gebruiker verstrekte invoer) als de maximale mate van parallelle uitvoering. Als u de waarde instelt op -1, kan de SDK de optimale gelijktijdigheid bepalen.

Het is belangrijk om te weten dat parallelle query's de beste voordelen opleveren als de gegevens gelijkmatig worden verdeeld over alle partities met betrekking tot de query. Als de gepartitioneerde container zodanig is gepartitioneerd dat alle of een meerderheid van de gegevens die door een query worden geretourneerd, is geconcentreerd in een paar partities (in het slechtste geval één partitie), worden de prestaties van de query gedegradeerd.

CosmosQueryRequestOptions options = new CosmosQueryRequestOptions();
options.setPartitionKey(new PartitionKey("Washington"));
options.setMaxDegreeOfParallelism(-1);

// Define the query

//  Sync API
CosmosPagedIterable<MyItem> filteredItems = 
    container.queryItems(querySpec, options, MyItem.class);

//  Async API
CosmosPagedFlux<MyItem> filteredItems = 
    asyncContainer.queryItems(querySpec, options, MyItem.class);

Laten we aannemen dat

  • D = Standaard maximum aantal parallelle taken (= totaal aantal processors op de clientcomputer)
  • P = Door de gebruiker opgegeven maximum aantal parallelle taken
  • N = Aantal partities dat moet worden bezocht voor het beantwoorden van een query

Hieronder volgen gevolgen voor de werking van de parallelle query's voor verschillende waarden van P.

  • (P == 0) => Seriële modus
  • (P == 1) => Maximum van één taak
  • (P > 1) => Min (P, N) parallelle taken
  • (P == -1) => Min (N, D) parallelle taken

Het paginaformaat afstemmen

Wanneer u een SQL-query uitgeeft, worden de resultaten gesegmenteerd geretourneerd als de resultatenset te groot is. Standaard worden resultaten geretourneerd in segmenten van 100 items of 4 MB, afhankelijk van welke limiet het eerst wordt bereikt. Door het paginaformaat te vergroten, wordt het aantal benodigde retouren verminderd en worden de prestaties voor query's die meer dan 100 items retourneren, verbeterd. Als u niet zeker weet welke waarde u wilt instellen, is 1000 doorgaans een goede keuze. Het geheugenverbruik neemt toe naarmate de paginagrootte toeneemt, dus als uw werkbelasting geheugengevoelig is, kunt u een lagere waarde overwegen.

U kunt de parameter gebruiken iterableByPage() voor de pageSize synchronisatie-API en byPage() voor asynchrone API om een paginaformaat te definiëren:

//  Sync API
Iterable<FeedResponse<MyItem>> filteredItemsAsPages =
    container.queryItems(querySpec, options, MyItem.class).iterableByPage(continuationToken,pageSize);

for (FeedResponse<MyItem> page : filteredItemsAsPages) {
    for (MyItem item : page.getResults()) {
        //...
    }
}

//  Async API
Flux<FeedResponse<MyItem>> filteredItemsAsPages =
    asyncContainer.queryItems(querySpec, options, MyItem.class).byPage(continuationToken,pageSize);

filteredItemsAsPages.map(page -> {
    for (MyItem item : page.getResults()) {
        //...
    }
}).subscribe();

De buffergrootte afstemmen

Parallelle query is ontworpen om resultaten vooraf op te halen terwijl de huidige batch met resultaten door de client wordt verwerkt. Het vooraf ophalen helpt bij het verbeteren van de algehele latentie van een query. setMaxBufferedItemCount beperkt CosmosQueryRequestOptions het aantal vooraf opgehaalde resultaten. Als u het vooraf ophalen wilt maximaliseren, stelt u het in maxBufferedItemCount op een hoger getal dan de pageSize (OPMERKING: dit kan ook leiden tot een hoog geheugenverbruik). Als u het ophalen van vooraf wilt minimaliseren, stelt u het maxBufferedItemCount gelijk aan de pageSize. Als u deze waarde instelt op 0, bepaalt het systeem automatisch het aantal items dat moet worden gebufferd.

CosmosQueryRequestOptions options = new CosmosQueryRequestOptions();
options.setPartitionKey(new PartitionKey("Washington"));
options.setMaxBufferedItemCount(-1);

// Define the query

//  Sync API
CosmosPagedIterable<MyItem> filteredItems = 
    container.queryItems(querySpec, options, MyItem.class);

//  Async API
CosmosPagedFlux<MyItem> filteredItems = 
    asyncContainer.queryItems(querySpec, options, MyItem.class);

Vooraf ophalen werkt op dezelfde manier, ongeacht de mate van parallelle uitvoering, en er is één buffer voor de gegevens van alle partities.

Volgende stappen

Voor meer informatie over prestaties met behulp van de Java SDK:

Queryplan-aanroepen verminderen

Als u een query wilt uitvoeren, moet een queryplan worden gebouwd. Dit vertegenwoordigt in het algemeen een netwerkaanvraag voor de Azure Cosmos DB-gateway, die wordt toegevoegd aan de latentie van de querybewerking. Er is een manier om deze aanvraag te verwijderen en de latentie van de querybewerking met één partitie te verminderen. Geef voor query's met één partitie de partitiesleutelwaarde voor het item op en geef deze door als partition_key argument:

items = container.query_items(
        query="SELECT * FROM r where r.city = 'Seattle'",
        partition_key="Washington"
    )

Het paginaformaat afstemmen

Wanneer u een SQL-query uitgeeft, worden de resultaten gesegmenteerd geretourneerd als de resultatenset te groot is. Met de max_item_count kunt u het maximum aantal items instellen dat moet worden geretourneerd in de opsommingsbewerking.

items = container.query_items(
        query="SELECT * FROM r where r.city = 'Seattle'",
        partition_key="Washington",
        max_item_count=1000
    )

Volgende stappen

Voor meer informatie over het gebruik van de Python SDK voor API voor NoSQL:

Queryplan-aanroepen verminderen

Als u een query wilt uitvoeren, moet een queryplan worden gebouwd. Dit vertegenwoordigt in het algemeen een netwerkaanvraag voor de Azure Cosmos DB-gateway, die wordt toegevoegd aan de latentie van de querybewerking. Er is een manier om deze aanvraag te verwijderen en de latentie van de querybewerking met één partitie te verminderen. Voor query's met één partitie kan het bereik van een query naar één partitie op twee manieren worden uitgevoerd.

Een geparameteriseerde query-expressie gebruiken en partitiesleutel opgeven in de query-instructie. De query is programmatisch samengesteld op SELECT * FROM todo t WHERE t.partitionKey = 'Bikes, Touring Bikes':

// find all items with same categoryId (partitionKey)
const querySpec = {
    query: "select * from products p where p.categoryId=@categoryId",
    parameters: [
        {
            name: "@categoryId",
            value: "Bikes, Touring Bikes"
        }
    ]
};

// Get items 
const { resources } = await container.items.query(querySpec).fetchAll();

for (const item of resources) {
    console.log(`${item.id}: ${item.name}, ${item.sku}`);
}

U kunt ook partitionKey FeedOptions opgeven en doorgeven als argument:

const querySpec = {
    query: "select * from products p"
};

const { resources } = await container.items.query(querySpec, { partitionKey: "Bikes, Touring Bikes" }).fetchAll();

for (const item of resources) {
    console.log(`${item.id}: ${item.name}, ${item.sku}`);
}

Het paginaformaat afstemmen

Wanneer u een SQL-query uitgeeft, worden de resultaten gesegmenteerd geretourneerd als de resultatenset te groot is. Met maxItemCount kunt u het maximum aantal items instellen dat moet worden geretourneerd in de opsommingsbewerking.

const querySpec = {
    query: "select * from products p where p.categoryId=@categoryId",
    parameters: [
        {
            name: "@categoryId",
            value: items[2].categoryId
        }
    ]
};

const { resources } = await container.items.query(querySpec, { maxItemCount: 1000 }).fetchAll();

for (const item of resources) {
    console.log(`${item.id}: ${item.name}, ${item.sku}`);
}

Volgende stappen

Meer informatie over het gebruik van de Node.js SDK voor API voor NoSQL: