DynamoDBのS3エクスポートにフィルタ指定が追加。FullとIncrementalで試してみた

DynamoDBのS3エクスポートにフィルタ指定が追加。FullとIncrementalで試してみた

DynamoDBのExport to S3に追加されたフィルタ指定を、FullとIncrementalで試しました。更新の多いテーブルのスナップショットなどで、必要な項目だけを出力できるかを確認しています。
2026.10.04

はじめに

2026-10-01 に、DynamoDB の Export to S3 が Filtered export に対応しました。Full export と Incremental export の両方で使え、GovCloud を除く全リージョンで利用できます。

https://aws.amazon.com/blogs/database/introducing-filtered-export-from-amazon-dynamodb-to-amazon-s3/

https://aws.amazon.com/about-aws/whats-new/2026/10/amazon-dynamodb-introduces-filtered-export/

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/S3DataExport.Filtered.html

指定できる3つの式

Filtered export では、--filter-specification に次の3つの式を指定できます。

式 書き方の規則 読む量
KeyCondition Query と同じ。PK は単一の値との等価条件、SK は任意の条件 減る
Filter Scan と同じ。読んだ後に適用される 減らない
Projection 出力する属性を指定する —

export は非同期に実行され、読み取りキャパシティ(RCU)を消費せず、テーブルの性能にも影響しません。料金は従来の export と同じ単価で、フィルタの追加料金はありません。KeyCondition で PK を1つの値に絞った export は、読んだ分だけが課金対象で、最小課金は1回の export あたり 10MB です。Incremental export の最小課金も 10MB です。

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/S3DataExport.HowItWorks.html

検証環境

  • リージョン:ap-northeast-1
  • AWS CLI:aws-cli/2.37.8
  • テーブル:PK は TenantId、SK は WorkOrderId、オンデマンド、PITR 有効
  • 属性:Status / Priority / CustomerEmail / CustomerPhone / AmountDue / UpdatedAt
  • 件数:tenant-A 400件、tenant-B 400件、tenant-C 200件の合計1,000件(すべて架空のデータ)

PK でテナントを管理するテーブルを想定した例です。1,000件程度ならフィルタなしの export でも困らない規模ですが、各式がどのように出力を絞るかを確認する目的なので、少量のデータで試しています。

Full export で絞り込む

KeyCondition で PK の値と SK の前方一致を指定する

tenant-A のうち、WorkOrderId が WO-01 で始まる項目だけを出力しました。指定を f1-filter.json に保存し、--filter-specification で渡しました。

{
  "KeyConditionExpression": "#tid = :tid AND begins_with(#wo, :prefix)",
  "ExpressionAttributeNames": {"#tid": "TenantId", "#wo": "WorkOrderId"},
  "ExpressionAttributeValues": {":tid": {"S": "tenant-A"}, ":prefix": {"S": "WO-01"}}
}
aws dynamodb export-table-to-point-in-time --table-arn <テーブルARN> --export-time 2026-10-03T09:54:00Z --s3-bucket <バケット名> --s3-prefix f1/ --export-format DYNAMODB_JSON --filter-specification file://f1-filter.json

出力は100件で、すべて tenant-A の WO-0100〜WO-0199 でした。同じ条件の Query(--select COUNT)も100件でした。1行目は次のとおりです。

{"Item":{"WorkOrderId":{"S":"WO-0100"},"TenantId":{"S":"tenant-A"},"CustomerPhone":{"S":"+81-90-0000-0100"},"UpdatedAt":{"S":"2026-10-03T09:00:00Z"},"Priority":{"S":"NORMAL"},"AmountDue":{"N":"1100"},"Status":{"S":"IN_PROGRESS"},"CustomerEmail":{"S":"user0100@example.com"}}}

Full export の各行は、Item をキーに持つ DynamoDB JSON 形式でした。適用したフィルタ指定は、export を要求した直後のレスポンスには含まれません。DescribeExport の FilterSpecification で確認できます。

Filter と Projection で項目と属性を絞る

Status が COMPLETED の項目に絞り、出力する属性を4つにしました。Status は予約語のため、式の中では別名(#st)を使っています。指定を f2-filter.json に保存して実行しました。

{
  "FilterExpression": "#st = :done",
  "ProjectionExpression": "#tid, #wo, #st, #amt",
  "ExpressionAttributeNames": {"#tid": "TenantId", "#wo": "WorkOrderId", "#st": "Status", "#amt": "AmountDue"},
  "ExpressionAttributeValues": {":done": {"S": "COMPLETED"}}
}
aws dynamodb export-table-to-point-in-time --table-arn <テーブルARN> --export-time 2026-10-03T09:54:00Z --s3-bucket <バケット名> --s3-prefix f2/ --export-format DYNAMODB_JSON --filter-specification file://f2-filter.json

出力は333件で、内訳は tenant-A が133件、tenant-B が133件、tenant-C が67件でした。1行目は次のとおりです。

{"Item":{"AmountDue":{"N":"1002"},"Status":{"S":"COMPLETED"},"TenantId":{"S":"tenant-A"},"WorkOrderId":{"S":"WO-0002"}}}

全行が Status=COMPLETED で、CustomerEmail と CustomerPhone を含む指定外の属性は出力されませんでした。連絡先を除いた出力は、Projection に残す属性を並べるだけで作れます。

Incremental export で絞り込む

対象期間内の変更と KeyCondition

ExportFromTime から ExportToTime までの15分間を対象期間にしました。1,000件の投入は対象期間の開始前に終えており、開始後に次の変更を加えました。

変更 TenantId WorkOrderId 変更前 → 後
更新 tenant-A WO-0003 OPEN → COMPLETED、AmountDue 1003 → 999001
更新 tenant-A WO-0002 COMPLETED → OPEN、AmountDue 1002 → 999002
更新 tenant-A WO-0008 COMPLETED のまま、AmountDue 1008 → 999003
更新 tenant-B WO-0003 OPEN → COMPLETED、AmountDue 1003 → 999004
削除 tenant-A WO-0005 削除前は COMPLETED
削除 tenant-A WO-0004 削除前は IN_PROGRESS
追加 tenant-A WO-0401 COMPLETED、AmountDue 500
追加して削除 tenant-A WO-0402 追加後に対象期間内で削除

対象期間は incremental-spec.json に指定しました。

{"ExportFromTime": "2026-10-03T09:54:30Z", "ExportToTime": "2026-10-03T10:09:30Z", "ExportViewType": "NEW_AND_OLD_IMAGES"}

tenant-A だけに絞る KeyCondition は、i1-filter.json として保存しました。この export を以下 I1 と呼びます。

{
  "KeyConditionExpression": "#tid = :tid",
  "ExpressionAttributeNames": {"#tid": "TenantId"},
  "ExpressionAttributeValues": {":tid": {"S": "tenant-A"}}
}
aws dynamodb export-table-to-point-in-time --table-arn <テーブルARN> --export-type INCREMENTAL_EXPORT --incremental-export-specification file://incremental-spec.json --s3-bucket <バケット名> --s3-prefix i1/ --export-format DYNAMODB_JSON --filter-specification file://i1-filter.json

出力は6件で、すべて tenant-A の項目でした。各行は Keys / Metadata / NewImage / OldImage を持つ構造で、Full export の Item とは形が異なります。Projection を指定していないため、各イメージは8属性でした。

更新した3件(WO-0002、WO-0003、WO-0008)は、OldImage と NewImage の両方が出力されました。削除した2件(WO-0004、WO-0005)は OldImage のみ、追加した1件(WO-0401)は NewImage のみでした。tenant-B の WO-0003 は、PK の値が KeyCondition と異なるため含まれませんでした。追加して対象期間内で削除した WO-0402 も、出力に含まれませんでした。

Filter は最新イメージで評価される

KeyCondition は付けず、同じ対象期間に対して Filter と Projection を指定しました。指定は f2-filter.json と同じ(Status が COMPLETED の Filter と、4属性の Projection)で、i2-filter.json として保存しています。この export を以下 I2 と呼びます。実行したコマンドは、前の小節のコマンドの --s3-prefix と --filter-specification の値を、i2/ と file://i2-filter.json に置き換えたものです。

出力は5件でした。対象期間内の変更のうち、追加して削除した WO-0402 を除く7件について、I1(KeyCondition のみ)と I2(Filter と Projection)の出力を対応づけます。

TenantId / WorkOrderId 変更 最新のイメージ I1(KeyCondition のみ) I2(Filter: Status=COMPLETED)
tenant-A / WO-0003 OPEN → COMPLETED COMPLETED 含まれる 含まれる
tenant-A / WO-0008 COMPLETED のまま金額変更 COMPLETED 含まれる 含まれる
tenant-A / WO-0401 追加(COMPLETED) COMPLETED 含まれる 含まれる
tenant-A / WO-0005 削除(削除前は COMPLETED) なし(旧イメージで判定) 含まれる 含まれる
tenant-B / WO-0003 OPEN → COMPLETED COMPLETED 含まれない 含まれる
tenant-A / WO-0002 COMPLETED → OPEN OPEN 含まれる 含まれない
tenant-A / WO-0004 削除(削除前は IN_PROGRESS) なし(旧イメージで判定) 含まれる 含まれない

Incremental export の Filter は、各項目の最新イメージに対して評価されます。削除された項目は、旧イメージで評価されます。

I2 の1行目(tenant-A の WO-0003)を見ると、Projection は OldImage と NewImage の両方に適用されていました。

{"Metadata":{"WriteTimestampMicros":{"N":"1791021301924409"}},"Keys":{"TenantId":{"S":"tenant-A"},"WorkOrderId":{"S":"WO-0003"}},"OldImage":{"AmountDue":{"N":"1003"},"Status":{"S":"OPEN"},"TenantId":{"S":"tenant-A"},"WorkOrderId":{"S":"WO-0003"}},"NewImage":{"AmountDue":{"N":"999001"},"Status":{"S":"COMPLETED"},"TenantId":{"S":"tenant-A"},"WorkOrderId":{"S":"WO-0003"}}}

指定が不正なときのエラー

次の4通りの指定を試したところ、いずれも export が始まる前に ValidationException が返りました。

指定 メッセージ
指定が空({}) Invalid FilterSpecification: The specification can not be empty
KeyCondition と Filter の両方に TenantId Invalid FilterExpression: key attributes are not allowed in the filter expression when a KeyConditionExpression is present: TenantId
KeyCondition の PK で等価以外(#tid > :tid)を使用 Invalid KeyConditionExpression: only the equality operator is supported for the partition key: TenantId
Filter で予約語 Status を別名化せず記述(Status = :done) Invalid FilterExpression: Attribute name is a reserved keyword; reserved keyword: Status

まとめ

DynamoDB の Export to S3 に今回追加されたフィルタ指定(--filter-specification)は、Full export と Incremental export のどちらでも機能することが確認できました。

更新の多いテーブルから1日1回、その時点のデータをスナップショットとして保存する用途なら、Full export に条件を付けて、必要な項目と属性だけを S3 に書き出せます。

DynamoDB 上の特定条件の項目のみ S3 に保存したい場合や、S3 のプレフィックスでデータをあらかじめ分類しておきたい場合などに、ご活用ください。

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事