DynamoDB BatchGetItem in Node.js (AWS SDK v3)
BatchGetItem recupera fino a 100 Item per chiave primaria in una sola richiesta. Nell'AWS SDK v3 la chiamata deve essere un loop, perché UnprocessedKeys arriva in una risposta riuscita invece che come errore. Cosa lo riempie, e perché 16 MB e 1 MB per partizione sono i numeri che contano, è trattato in operazioni batch in DynamoDB. Questa pagina riguarda la chiamata v3 e ciò che ti restituisce.
Codice
import {BatchGetItemCommand, DynamoDBClient} from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({region: 'us-east-1'});
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
let requestItems = {
Music: {
Keys: [
{Artist: {S: 'Arturo Sandoval'}, SongTitle: {S: 'Cubano Chant'}},
{Artist: {S: 'Arturo Sandoval'}, SongTitle: {S: 'A Mis Abuelos'}},
{Artist: {S: 'Ella Fitzgerald'}, SongTitle: {S: 'Misty'}}
]
}
};
const items = [];
let attempt = 0;
do {
const response = await client.send(new BatchGetItemCommand({RequestItems: requestItems}));
items.push(...(response.Responses?.Music ?? []));
// A partial result is NOT an error: throttling, a >16 MB response, or an
// internal failure returns the leftovers in UnprocessedKeys. Retry them
// with exponential backoff.
requestItems = response.UnprocessedKeys;
if (requestItems && Object.keys(requestItems).length > 0) {
attempt += 1;
await sleep(Math.min(100 * 2 ** attempt, 5000));
}
} while (requestItems && Object.keys(requestItems).length > 0);
console.log(`Fetched ${items.length} items`);Spiegazione
- L'optional chaining non è rumore difensivo.
ResponseseUnprocessedKeyssono entrambi opzionali nei tipi v3, quindiresponse.Responses?.Music ?? []e la guardia conObject.keys()sono esattamente ciò che chiede il compilatore. In JavaScript puro sono ciò che impedisce alla prima risposta vuota di lanciare un errore. - Ramifica su
err.name. v3 ci mette il codice di errore del servizio, e i due fallimenti che questo comando solleva davvero non sono ripetibili, quindi non devono mai finire nel loop di backoff. Oltre 100 chiavi dannoValidationException/Too many items requested for the BatchGetItem call; la stessa chiave due volte dàProvided list of item keys contains duplicates. Entrambi sono riprodotti alla lettera nella pagina Python. UnprocessedKeysarriva già nella forma diRequestItems, che è l'unico motivo per cui il loop può riassegnarlo direttamente. Non è un cursore di paginazione e non significa che la chiamata sia fallita.- Il backoff è un'istruzione di AWS, non una gentilezza. Il riferimento dell'API ti dice di usare "an exponential backoff algorithm" perché un retry immediato atterra sulla stessa partizione sottoposta a throttling.
ConsistentReadeProjectionExpressionsono per tabella, si impostano dentro ogni voce diRequestItemse non al livello superiore. È facile non accorgersene quando la mappa ha una sola chiave e sembra una richiesta piatta.
Com'è fatta davvero la risposta
Esegui il blocco qui sopra su DynamoDB Local 3.3.0 con tutte e tre le canzoni presenti, aggiungi ReturnConsumedCapacity: 'TOTAL' e stampa i titoli invece del conteggio:
order: [ 'A Mis Abuelos', 'Misty', 'Cubano Chant' ]
UnprocessedKeys: {}
ConsumedCapacity: [ { TableName: 'Music', CapacityUnits: 1.5 } ]La richiesta elencava Cubano Chant, A Mis Abuelos, Misty. La risposta non è in nessuna di quelle posizioni, ed è per questo che il loop accumula in un array piatto invece di indicizzare per posizione. Riassocia gli Item alle richieste tramite i loro attributi chiave, e includi quelle chiavi in qualsiasi ProjectionExpression così ti resta qualcosa su cui fare l'associazione.
Imposta ConsistentRead: true su quella stessa voce Music e le stesse tre chiavi costano 3 unità invece di 1,5. Tre Item sotto i 4 KB ciascuno vengono fatturati come tre letture GetItem separate, a mezza unità con coerenza eventuale e a un'unità intera con coerenza forte. Il calcolatore dei prezzi converte quell'aritmetica per Item in una cifra mensile prima che tu ti impegni su un pattern di lettura.
Ora elimina Misty e riesegui: due Item, un UnprocessedKeys vuoto e 1,0 unità. La chiave mancante non è stata fatturata. Quello è un artefatto di DynamoDB Local e non il contratto; il riferimento di BatchGetItem (consultato il 2026-07-28) dice che le richieste di Item inesistenti consumano la capacità di lettura minima secondo il tipo di lettura. Non dimensionare un batch di cache miss da un'esecuzione locale.
Per recuperare un insieme di chiavi e vedere cos'è tornato davvero, senza scrivere prima il loop, scarica DynoTable.
Esempi correlati
- DynamoDB BatchGetItem in Python — la stessa lettura batch con boto3.
- DynamoDB BatchGetItem con la AWS CLI — la stessa lettura batch dalla shell.
- DynamoDB GetItem in Node.js — la lettura di un singolo Item che questa raggruppa.
- Operazioni batch in DynamoDB — limiti, fallimento parziale e quando conviene fare batch.
- "Too many items requested for the BatchGetItem call" — più di 100 chiavi in una richiesta.
- "Provided list of item keys contains duplicates" — la stessa chiave due volte in un batch.
Riferimenti
- BatchGetItem — Amazon DynamoDB API Reference
- Error handling with DynamoDB — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
Ultima verifica 2026-07-28 rispetto alla documentazione ufficiale AWS collegata sopra.