DynamoDB Scan en Node.js (AWS SDK v3)

Le do/while ci-dessous n'est pas du codage défensif. Une page de Scan filtré peut revenir avec un tableau Items vide alors qu'il reste encore de la table à lire : s'arrêter à la première réponse, c'est exactement comme ça qu'un scan annonce zéro correspondance sur une table qui en contient. Query vs. Scan explique quand éviter complètement l'opération.

Code

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`);

Deux pages vides, 284,5 unités de lecture, 8 éléments

Le jeu d'essai fait 600 morceaux d'environ 3,9 Ko chacun, dont exactement 8 ont Year >= 2010, et ils se trient en dernier. Voici ce que la boucle ci-dessus reçoit réellement :

Aller-retourItems.lengthScannedCountUnités de lectureLastEvaluatedKey
10271128,5présente
20271128,5présente
385827,5absente

Deux pages consécutives ne renvoient rien et coûtent 128,5 unités de lecture chacune. Un code qui fait if (!response.Items.length) return annonce une table vide. La référence de l'API énonce la règle sans détour : "a scan result can result in no items meeting the criteria and the Count will result in zero", et, séparément, "a FilterExpression is applied after the items have already been read; the process of filtering does not consume any additional read capacity units".

Lis cette seconde phrase comme le fait ta facture. Le filtre est gratuit, et tout ce qu'il a jeté ne l'est pas : 284,5 unités de lecture pour livrer 8 éléments, exactement la facture que tu paierais sans aucun filtre.

Mesuré le 2026-07-28 contre DynamoDB Local (amazon/dynamodb-local) avec @aws-sdk/client-dynamodb 3.1095.0 sur node v24.18.0. Les comptes et la capacité sont les champs de réponse du moteur lui-même.

Explication

  • ExclusiveStartKey: lastEvaluatedKey vaut undefined au premier passage. Le sérialiseur v3 supprime les membres undefined, donc un seul littéral d'objet couvre la première requête et toutes les suivantes. Passer {} à la place échoue avec ValidationException: The provided starting key is invalid.
  • response.Items ?? [] fait un vrai travail. Combine-le avec le tableau ci-dessus : le coalescement de nullité garde l'accumulateur honnête sur les pages qui n'ont rien trouvé, et le while maintient la boucle en vie au-delà.
  • #filter0 n'est pas décoratif. Year figure sur la liste des mots réservés d'AWS, et l'utiliser sans alias renvoie ValidationException: Invalid FilterExpression: Attribute name is a reserved keyword; reserved keyword: Year.
  • Limit compte les éléments lus, pas les éléments renvoyés. Avec ce filtre, Limit: 10 donne Count: 0 et ScannedCount: 10. C'est un bouton de régulation pour les pics de capacité, pas un moyen de demander dix résultats.
  • Segment / TotalSegments répartissent un scan de table complet entre des workers. Ça divise le temps d'exécution, pas le coût — les mêmes 284,5 unités sont dépensées, simplement plus vite et plus concurremment.

Ce que ça coûte sur une vraie table

284,5 unités de lecture pour 8 éléments, c'est la forme du problème, et elle croît linéairement avec la table, pas avec le résultat. Avant d'expédier un scan filtré sur un chemin critique, chiffre la lecture complète de la table à ta taille d'élément et à ton trafic dans le calculateur de tarifs DynamoDB, puis compare-la à un GSI qui transforme le même modèle d'accès en Query.

Pour explorer tes tables dans une interface graphique, avec des grilles de résultats filtrées et paginées, télécharge DynoTable plutôt que de scanner à l'aveugle depuis un script.

Guides liés

Références

Construis cette requête visuellement

Compose cette opération dans le Générateur de requêtes DynamoDB gratuit — condition de clé, filtre, index, Limit, ordre de tri et boucle de pagination — et copie-la en retour comme programme exécutable SDK v3, CLI ou boto3.

Ouvrir le Générateur de requêtes DynamoDB

Travaille avec DynamoDB sans la Console

Un client de bureau rapide pour DynamoDB qui exécute le vrai SQL que DynamoDB ne peut pas — JOINs, GROUP BY, agrégations — avec édition visuelle et un agent IA sur tes propres clés Bedrock.

Essai gratuit de 30 jours, sans carte bancaire — ensuite la formule Gratuit, sans limite de durée.