Query DynamoDB in Node.js (AWS SDK v3)
Una Query completa in AWS SDK v3 è il do/while qui sotto, non la singola client.send() che mostrano quasi tutti gli snippet: una pagina è limitata a 1 MB, e il resto della partizione arriva solo se rimetti dentro LastEvaluatedKey. Vedi Query vs. Scan per capire quando Query è la lettura giusta.
Codice
import {DynamoDBClient, QueryCommand} from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({region: 'us-east-1'});
const items = [];
let lastEvaluatedKey;
do {
const response = await client.send(
new QueryCommand({
TableName: 'Music',
KeyConditionExpression: '#hashKey = :hashKeyValue AND begins_with(#rangeKey, :rangeKeyValue)',
ExpressionAttributeNames: {
'#hashKey': 'Artist',
'#rangeKey': 'SongTitle'
},
ExpressionAttributeValues: {
':hashKeyValue': {S: 'Arturo Sandoval'},
':rangeKeyValue': {S: 'C'}
},
ExclusiveStartKey: lastEvaluatedKey
})
);
items.push(...(response.Items ?? []));
lastEvaluatedKey = response.LastEvaluatedKey;
} while (lastEvaluatedKey);
console.log(`Found ${items.length} items`);Cosa fa davvero il loop
Su una fixture di 600 brani, ognuno da ~3,9 KB e tutti sotto Artist = "Arturo Sandoval", il loop qui sopra invia tre richieste:
| Round trip | Count | ScannedCount | Unità di lettura | LastEvaluatedKey |
|---|---|---|---|---|
| 1 | 271 | 271 | 128,5 | presente |
| 2 | 271 | 271 | 128,5 | presente |
| 3 | 58 | 58 | 27,5 | assente |
Nessuno ha configurato 271. È il punto in cui è finito 1 MB, quindi il confine di pagina si sposta ogni volta che cambia la dimensione dei tuoi Item. Una partizione che oggi pagina una volta ne paginerà due dopo che avrai aggiunto un attributo, e il codice che legge response.Items da una singola send() restituisce silenziosamente 271 brani su 600 senza alcun errore.
Ora aggiungi Limit: 10 e una FilterExpression su Year alla stessa query:
Count: 0 ScannedCount: 10 ConsumedCapacity: 5 LastEvaluatedKey: setDieci Item valutati, zero restituiti, e la richiesta è comunque costata capacità di lettura. Limit limita ciò che DynamoDB legge, e il filtro viene eseguito dopo, quindi un Limit scelto pensando "dammi 10 risultati" te ne dà tra 0 e 10.
Misurato il 2026-07-28 su DynamoDB Local (amazon/dynamodb-local) con @aws-sdk/client-dynamodb 3.1095.0 su node v24.18.0. I conteggi e la capacità sono i campi di risposta del motore stesso.
Spiegazione
ExclusiveStartKey: lastEvaluatedKeyèundefinedal primo passaggio, ed è voluto: il serializzatore v3 scarta i membriundefined, quindi lo stesso oggetto letterale funziona per la prima richiesta e per tutte le successive. Sostituirlo con{}— l'ipotesi ovvia per "parti dall'inizio" — fallisce conValidationException: The provided starting key is invalid.@aws-sdk/client-dynamodbnon fa mai il marshalling per te. I valori entrano come{S: 'Arturo Sandoval'}e gli Item tornano allo stesso modo. È il prezzo per non tirare dentro il DocumentClient; se preferisci scrivere oggetti JS semplici, il wrapper a cui ricorrere è@aws-sdk/lib-dynamodb.- I numeri sopravvivono al round trip come stringhe. Fare l'unmarshalling di
{N: '9007199254740993'}conunmarshallda@aws-sdk/util-dynamodbrestituisce unbigintJS, non unnumbercon perdita di precisione; passa{wrapNumbers: true}e ottieni invece{value: '9007199254740993'}. In ogni caso, non fareNumber()su unNdi DynamoDB di cui non hai verificato la dimensione. KeyConditionExpressionprende un'uguaglianza sulla partition key più al massimo una condizione sulla sort key (=,<,<=,>,>=,BETWEEN,begins_with). Tutto il resto appartiene a unaFilterExpression, che viene eseguita dopo la lettura.ScanIndexForward: falseinverte l'ordine della sort key; l'ordine crescente è il default.IndexNamefa passare lo stesso comando a un indice secondario.
Fallo visivamente
Il query builder DynamoDB emette tutta questa struttura — condizione di chiave, mappe di nomi e valori e il loop su LastEvaluatedKey — come programma SDK v3 eseguibile, così la paginazione non è la parte che dimentichi.
Per eseguire query su tabelle reali in una GUI, con un modulo per la condizione di chiave e una griglia di risultati paginata, scarica DynoTable.
Guide correlate
- Query vs. Scan — perché
Queryè il default giusto. - Espressioni di condizione di chiave — ogni operatore legale su partition/sort key.
- "Query condition missed key schema element" — la condizione di chiave nomina l'attributo sbagliato o salta la partition key.
- "Query key condition not supported" — un operatore che la condizione di chiave non può usare, come contains o una seconda condizione sulla sort key.