Scan do DynamoDB em Node.js (AWS SDK v3)
O do/while abaixo não é programação defensiva. Uma página de Scan filtrado pode voltar com um array Items vazio e ainda assim sobrar tabela, então parar na primeira resposta é a forma de um scan reportar zero correspondências em uma tabela que as tem. Query vs. Scan cobre quando evitar a operação por completo.
Código
import {DynamoDBClient, ScanCommand} from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({region: 'us-east-1'});
const items = [];
let lastEvaluatedKey;
do {
const response = await client.send(
new ScanCommand({
TableName: 'Music',
FilterExpression: '#filter0 >= :filterValue0',
ExpressionAttributeNames: {
'#filter0': 'Year'
},
ExpressionAttributeValues: {
':filterValue0': {N: '2010'}
},
ExclusiveStartKey: lastEvaluatedKey
})
);
items.push(...(response.Items ?? []));
lastEvaluatedKey = response.LastEvaluatedKey;
} while (lastEvaluatedKey);
console.log(`Matched ${items.length} items`);Duas páginas vazias, 284,5 unidades de leitura, 8 itens
O fixture são 600 músicas de aproximadamente 3,9 KB cada, das quais exatamente 8 têm Year >= 2010, e elas ficam por último na ordenação. Isto é o que o laço acima de fato recebe:
| Ida e volta | Items.length | ScannedCount | Unidades de leitura | LastEvaluatedKey |
|---|---|---|---|---|
| 1 | 0 | 271 | 128,5 | definido |
| 2 | 0 | 271 | 128,5 | definido |
| 3 | 8 | 58 | 27,5 | ausente |
Duas páginas consecutivas retornam nada e custam 128,5 unidades de leitura cada. Um código que faz if (!response.Items.length) return reporta uma tabela vazia. A referência da API declara a regra sem rodeios: "a scan result can result in no items meeting the criteria and the Count will result in zero", e, separadamente, que "a FilterExpression is applied after the items have already been read; the process of filtering does not consume any additional read capacity units".
Leia essa segunda frase do jeito que a sua fatura a lê. O filtro é grátis, e tudo o que ele descartou não é: 284,5 unidades de leitura para entregar 8 itens, a mesma conta que você pagaria sem filtro nenhum.
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 campos da própria resposta do motor.
Explicação
ExclusiveStartKey: lastEvaluatedKeyéundefinedna primeira passagem. O serializador da v3 descarta membrosundefined, então um único literal de objeto cobre a primeira requisição e todas as seguintes. Passar{}no lugar falha comValidationException: The provided starting key is invalid.response.Items ?? []faz trabalho de verdade. Combine isso com a tabela acima: o operador de coalescência nula mantém o acumulador honesto nas páginas que não casaram com nada, e owhilemantém o laço vivo depois delas.#filter0não é decoração.Yearestá na lista de palavras reservadas da AWS, e usá-lo sem alias retornaValidationException: Invalid FilterExpression: Attribute name is a reserved keyword; reserved keyword: Year.Limitconta itens lidos, não itens retornados. Com este filtro,Limit: 10produzCount: 0eScannedCount: 10. É um botão de contenção para picos de capacidade, não um jeito de pedir dez resultados.Segment/TotalSegmentsdividem um scan de tabela inteira entre workers. Isso divide o tempo de relógio, não o custo — as mesmas 284,5 unidades são gastas, só que mais rápido e com mais concorrência.
Quanto isso custa em uma tabela de verdade
284,5 unidades de leitura para 8 itens é o formato do problema, e ele escala linearmente com a tabela, não com o resultado. Antes de colocar um scan filtrado em um caminho quente, precifique a leitura da tabela inteira com o seu tamanho de item e o seu tráfego na calculadora de preços do DynamoDB, e compare com um GSI que transforme o mesmo padrão de acesso em um Query.
Para explorar tabelas em uma GUI, com grades de resultado filtradas e paginadas, baixe o DynoTable em vez de escanear às cegas a partir de um script.
Guias relacionados
- Query vs. Scan — quando (raramente) um
Scanse justifica. - Por que meu Scan do DynamoDB é lento e caro? — o modelo de custo e como evitá-lo.
- DynamoDB ProvisionedThroughputExceededException — o que um scan de tabela inteira faz com a capacidade de uma tabela provisionada.
- DynamoDB ThrottlingException — o outro throttle, e como o backoff exponencial lida com ele.