Query do DynamoDB em Node.js (AWS SDK v3)
Um Query completo no AWS SDK v3 é o do/while abaixo, não o único client.send() que a maioria dos trechos mostra: uma página é limitada a 1 MB, e o resto da partição só chega se você devolver LastEvaluatedKey. Veja Query vs. Scan para saber quando o Query é a leitura certa, para começo de conversa.
Código
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`);O que o loop faz de verdade
Contra um conjunto de teste de 600 músicas, cada uma de ~3,9 KB e todas sob Artist = "Arturo Sandoval", o loop acima envia três requisições:
| Ida e volta | Count | ScannedCount | Unidades de leitura | LastEvaluatedKey |
|---|---|---|---|---|
| 1 | 271 | 271 | 128,5 | presente |
| 2 | 271 | 271 | 128,5 | presente |
| 3 | 58 | 58 | 27,5 | ausente |
Ninguém configurou 271. É ali que 1 MB se esgotou, então o limite da página se move sempre que o tamanho dos seus itens se move. Uma partição que hoje pagina uma vez pagina duas depois que você adiciona um atributo, e um código que lê response.Items de um único send() devolve silenciosamente 271 de 600 músicas sem erro nenhum.
Agora adicione Limit: 10 e uma FilterExpression sobre Year à mesma consulta:
Count: 0 ScannedCount: 10 ConsumedCapacity: 5 LastEvaluatedKey: setDez itens avaliados, zero retornados, e a requisição ainda assim custou capacidade de leitura. Limit limita o que o DynamoDB lê, e o filtro roda depois disso, então um Limit escolhido para significar "me dê 10 resultados" te dá entre 0 e 10.
Medido em 2026-07-28 contra o DynamoDB Local (amazon/dynamodb-local) com @aws-sdk/client-dynamodb 3.1095.0 no node v24.18.0. As contagens e a capacidade são os próprios campos de resposta do motor.
Explicação
ExclusiveStartKey: lastEvaluatedKeyéundefinedna primeira passada, e isso é deliberado: o serializador do v3 descarta membrosundefined, então o mesmo literal de objeto serve para a primeira requisição e para todas as seguintes. Substituí-lo por{}— o palpite óbvio para "comece do começo" — falha comValidationException: The provided starting key is invalid.- O
@aws-sdk/client-dynamodbnunca faz o marshalling por você. Os valores entram como{S: 'Arturo Sandoval'}e os itens voltam do mesmo jeito. Esse é o preço de não puxar o DocumentClient; se você preferir escrever objetos JS simples,@aws-sdk/lib-dynamodbé o wrapper a que recorrer. - Números sobrevivem à ida e volta como strings. Desfazer o marshalling de
{N: '9007199254740993'}com ounmarshalldo@aws-sdk/util-dynamodbretorna umbigintdo JS, não umnumbercom perda; passe{wrapNumbers: true}e você recebe{value: '9007199254740993'}no lugar. De qualquer forma, não apliqueNumber()a umNdo DynamoDB cujo tamanho você não conferiu. KeyConditionExpressionaceita uma igualdade na chave de partição mais, no máximo, uma condição de chave de ordenação (=,<,<=,>,>=,BETWEEN,begins_with). Qualquer outra coisa vai em umaFilterExpression, que roda depois da leitura.ScanIndexForward: falseinverte a ordem da chave de ordenação; ascendente é o padrão.IndexNamemuda o mesmo comando para um índice secundário.
Faça isso visualmente
O construtor de consultas do DynamoDB emite esse formato inteiro — condição de chave, mapas de nomes e valores, e o loop de LastEvaluatedKey — como um programa SDK v3 pronto para executar, para que a paginação não seja a parte que você esquece.
Para rodar consultas contra tabelas reais em uma GUI, com um formulário de condição de chave e uma grade de resultados paginada, baixe o DynoTable.
Guias relacionados
- Query vs. Scan — por que o
Queryé o padrão certo. - Expressões de condição de chave — todos os operadores válidos de chave de partição/ordenação.
- "Query condition missed key schema element" — a condição de chave nomeia o atributo errado ou pula a chave de partição.
- "Query key condition not supported" — um operador que a condição de chave não pode usar, como contains ou uma segunda condição de chave de ordenação.