Node.js(AWS SDK v3)의 DynamoDB Query

AWS SDK v3에서 완전한 Query는 대부분의 스니펫이 보여주는 단 한 번의 client.send()가 아니라 아래의 do/while입니다. 한 페이지는 1 MB에서 잘리고, 파티션의 나머지는 LastEvaluatedKey를 되먹여야만 도착합니다. 애초에 Query가 올바른 읽기인지는 Query vs. Scan을 참조하세요.

코드

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

이 루프가 실제로 하는 일

곡마다 약 3.9 KB이고 모두 Artist = "Arturo Sandoval" 아래에 있는 600곡 픽스처를 상대로, 위 루프는 요청을 세 번 보냅니다:

왕복CountScannedCount읽기 단위LastEvaluatedKey
1271271128.5있음
2271271128.5있음
3585827.5없음

271을 설정한 사람은 아무도 없습니다. 그 지점에서 1 MB가 소진된 것이며, 따라서 항목 크기가 달라질 때마다 페이지 경계도 움직입니다. 오늘 한 번 페이징하는 파티션은 속성을 하나 추가하면 두 번 페이징하게 되고, 단 한 번의 send()에서 response.Items를 읽는 코드는 600곡 중 271곡을 오류 없이 조용히 반환합니다.

이제 같은 쿼리에 Limit: 10Year에 대한 FilterExpression을 추가해 보세요:

Count: 0   ScannedCount: 10   ConsumedCapacity: 5   LastEvaluatedKey: set

열 개를 평가했고, 반환된 것은 0개이며, 그럼에도 요청은 읽기 용량을 소비했습니다. Limit은 DynamoDB가 읽는 양을 제한하고 필터는 그 뒤에 실행되므로, "결과 10개를 달라"는 의미로 고른 Limit은 0개에서 10개 사이를 줍니다.

2026-07-28에 node v24.18.0에서 @aws-sdk/client-dynamodb 3.1095.0으로 DynamoDB Local(amazon/dynamodb-local)을 상대로 측정했습니다. 개수와 용량은 엔진 자신의 응답 필드입니다.

설명

  • 첫 회차의 ExclusiveStartKey: lastEvaluatedKeyundefined이며, 그것은 의도된 것입니다. v3 직렬화기가 undefined 멤버를 버리므로 같은 객체 리터럴이 첫 요청과 이후 모든 요청에 그대로 동작합니다. "처음부터 시작"의 뻔한 짐작인 {}로 바꾸면 ValidationException: The provided starting key is invalid로 실패합니다.
  • @aws-sdk/client-dynamodb는 절대 대신 마샬링해 주지 않습니다. 값은 {S: 'Arturo Sandoval'}로 들어가고 항목도 같은 방식으로 돌아옵니다. DocumentClient를 끌어들이지 않는 대가입니다. 평범한 JS 객체를 쓰고 싶다면 @aws-sdk/lib-dynamodb가 손을 뻗을 래퍼입니다.
  • 숫자는 왕복 동안 문자열로 살아남습니다. @aws-sdk/util-dynamodbunmarshall{N: '9007199254740993'}을 언마샬링하면 손실이 있는 number가 아니라 JS bigint가 반환됩니다. {wrapNumbers: true}를 전달하면 대신 {value: '9007199254740993'}을 받습니다. 어느 쪽이든, 크기를 확인하지 않은 DynamoDB NNumber()를 쓰지 마세요.
  • KeyConditionExpression — 파티션 키에 대한 등호 하나에 정렬 키 조건 최대 하나(=, <, <=, >, >=, BETWEEN, begins_with)를 받습니다. 그 밖의 것은 읽기 뒤에 실행되는 FilterExpression에 속합니다.
  • ScanIndexForward: false — 정렬 키 순서를 뒤집습니다. 기본값은 오름차순입니다. IndexName은 같은 명령을 보조 인덱스로 전환합니다.

시각적으로 해보기

DynamoDB 쿼리 빌더가 이 전체 형태 — 키 조건, 이름과 값 맵, LastEvaluatedKey 루프 — 를 실행 가능한 SDK v3 프로그램으로 내보내므로, 페이지네이션이 깜빡 잊는 부분이 되지 않습니다.

키 조건 폼과 페이지네이션된 결과 그리드를 갖춘 GUI에서 실제 테이블을 상대로 쿼리를 실행하려면, DynoTable을 다운로드하세요.

관련 가이드

참고 자료

이 요청을 시각적으로 만들기

무료 DynamoDB 쿼리 빌더에서 이 작업을 구성하세요 — 키 조건, 필터, 인덱스, Limit, 정렬 순서, 페이지네이션 루프 — 그리고 실행 가능한 SDK v3, CLI, boto3 프로그램으로 다시 복사하세요.

DynamoDB 쿼리 빌더 열기

Console 없이 DynamoDB 작업하기

DynamoDB로는 실행할 수 없는 진짜 SQL(JOINs, GROUP BY, 집계)을 실행하는 빠른 DynamoDB 데스크톱 클라이언트. 시각적 편집과 여러분 자신의 Bedrock 키로 동작하는 AI 에이전트를 제공합니다.

30일 무료 체험, 신용카드 불필요 — 이후 기간 제한 없는 무료 요금제.