AWS CLI での DynamoDB Query
aws dynamodb query は 1 つのパーティションを読み、必要ならソートキーで絞り込みます(それが正しい選択となる場面は Query と Scan の比較が扱い、使える演算子はキー条件式が網羅しています)。CLI がその上に乗せてくるのは独自のページネーション層で、このコマンドで驚かされることの大半はそこが原因です。
コード
aws dynamodb query \
--table-name 'Music' \
--key-condition-expression '#hashKey = :hashKeyValue AND begins_with(#rangeKey, :rangeKeyValue)' \
--expression-attribute-names '{"#hashKey":"Artist","#rangeKey":"SongTitle"}' \
--expression-attribute-values '{":hashKeyValue":{"S":"Arturo Sandoval"},":rangeKeyValue":{"S":"C"}}'#hashKey/#rangeKey のエイリアスは --expression-attribute-names を通じて Artist/SongTitle に解決されます。これが予約語でコマンドが壊れるのを防いでいます。ソートキーの 降順 には --no-scan-index-forward を追加してください。既定は昇順です。
ページネーション
既定で CLI は 自動でページ送り します。内部で LastEvaluatedKey をたどり、まとめた結果を出力します。手動でページ送りしたい場合(大きな結果セットなど)は、次のように制御します。
aws dynamodb query \
--table-name 'Music' \
--key-condition-expression '#hashKey = :hashKeyValue' \
--expression-attribute-names '{"#hashKey":"Artist"}' \
--expression-attribute-values '{":hashKeyValue":{"S":"Arturo Sandoval"}}' \
--page-size 100 \
--max-items 50
# The output includes a "NextToken"; pass it back with --starting-token to continue.解説
CLI はページネーションを隠します。コストの数字からも隠します。約 60 KB のアイテムを 30 件、合計およそ 1.8 MB、つまりサービス側で 2 ページになるパーティションを用意し、同じクエリを --return-consumed-capacity TOTAL 付きで 3 通り実行しました。
default (auto-paginate) Count: 30 CapacityUnits: 132.0 LastEvaluatedKey: null
--no-paginate Count: 18 CapacityUnits: 132.0 LastEvaluatedKey: {…S017}
--max-items 3 Count: 18 items printed: 3 NextToken: eyJFeGNsdXNpdmVTdGFydEtleSI6…手でページ送りすると本当のコストが見えます。1 ページ目は 18 件で 132.0 ユニット、2 ページ目は 12 件で 88.0 ユニット。つまりこのクエリが実際に消費したのは 220.0 読み取りユニット です。自動ページ送りの実行は両方の呼び出しを行い、30 件すべてを返しながら、報告したのは 132.0 でした。CLI は Items と Count はページ間でマージしますが ConsumedCapacity はマージしないので、出力された数字はこのクエリを 40% 過小に見せています。CLI の出力からキャパシティを見積もっているなら、手動でページ送りしてください。さもないと 1 ページ分でサイジングすることになります。
--max-items は表示上の制限であって、Limit ではありません。上の 3 番目の実行は 3 件を出力しつつ、Count: 18 と ScannedCount: 18 を報告しました。切り詰められたサービス側のページが 18 件、およそ 1 MB だったからです。その全部に課金されています。読み取りを本当に制限する DynamoDB のパラメータは Limit で、CLI はそれを --page-size として公開しています。
つまりこの 2 つのフラグは無関係な仕事をしています。--page-size は API の Limit になり、各サービス呼び出しが読む量を変えます。--max-items はマージ済みの結果のうちどれだけを端末に届けるかを決めるだけで、残りのために NextToken を出します。そのトークンは CLI 自身の帳簿を base64 にした塊であり、DynamoDB の LastEvaluatedKey ではありません。戻すときは --starting-token から入れます。
--limit も --exclusive-start-key も存在しません。2.36.9 で aws dynamodb query help を確認すると、どちらも構文概要に出てきません。CLI は DynamoDB のページネーション用パラメータを両方とも取り除き、自前の 3 つで置き換えています。ですから、ある呼び出しの LastEvaluatedKey を次に渡すという自然なループには、渡すためのフラグがありません。生の API に戻る手段は --cli-input-json で、リクエストをそのまま受け取ります。
--cli-input-json with "Limit": 5 and an "ExclusiveStartKey"
→ Count: 5 CapacityUnits: 37.0 LastEvaluatedKey: {"Artist":…,"SongTitle":"S007"}なお、これはページネータも切ります。--no-paginate なしでも、この実行は 1 ページと本物の LastEvaluatedKey を返しました。大きなパーティションに対してシェルのループを書くなら、--cli-input-json が正直な形で、--no-paginate が手軽な形です。
--query はお金を使い切った後に走ります。グローバルな --query フラグは、手元のシェルでレスポンスに適用される JMESPath です。Items[?Year > '2010'] のような JMESPath 式はフィルタのように見えますが違います。JMESPath が見る前に、すべてのアイテムが読まれ、転送され、課金されています。--filter-expression なら少なくともデータの転送は止まりますが、AWS は「is applied after the items have already been read; the process of filtering does not consume any additional read capacity units」と明言しています(2026-07-28 取得)。これは両刃で、フィルタが読み取りユニットを減らしもしないという意味でもあります。読む量を減らす唯一の方法は、より狭いキー条件かインデックスです。
1 ページは 1 MB で、何を要求したかは関係ありません。「A single Query operation will read up to the maximum number of items set (if using the Limit parameter) or a maximum of 1 MB of data」(2026-07-28 取得)。それより広いパーティションは常にページ分割されます。だからこそ上の 30 件のクエリは 1 回の呼び出しにはならなかったのです。
インデックスへのクエリにはフラグがもう 1 つ要ります。--index-name はキー条件をそのインデックスのキーに切り替えます。グローバルセカンダリインデックスは --consistent-read も拒否します。AWS CLI で GSI をクエリするを参照してください。
ビジュアルに行う
キー条件、2 つのプレースホルダーマップ、そしてページネーションのループを 1 つのコマンドで正しく組み立てること — ここでの難しさはそれに尽きます。無料の DynamoDB クエリビルダーは、インデックスやページ送りも含めてリクエストを組み立て、実行可能な CLI コマンドとして出力します。
自分のテーブルに対してクエリを実行するには — キー条件のフォーム、スクロールに合わせてページ送りするグリッド、リクエストを CLI コマンドとしてコピーし直す機能 — DynoTable をダウンロードしてください。
関連ガイド
- Query と Scan の比較 — なぜ
queryが正しい既定なのか。 - ページネーション —
LastEvaluatedKey、ExclusiveStartKey、そしてLimitがページサイズではない理由。 - 「Query condition missed key schema element」 — キー条件が誤った属性を指しているか、パーティションキーを飛ばしている。
- 「Query key condition not supported」 — contains や 2 つ目のソートキー条件など、キー条件では使えない演算子。
参考資料
- Query — Amazon DynamoDB API Reference
- query — AWS CLI Command Reference
- Using the pagination options in the AWS CLI — AWS CLI User Guide
- Filtering AWS CLI output — AWS CLI User Guide
- Querying tables — Amazon DynamoDB Developer Guide
2026-07-28 に、約 60 KB のアイテム 30 件からなるパーティションに対し、ポート 9000 の DynamoDB Local(amazon/dynamodb-local)で aws-cli/2.36.9 を使って測定しました。上記の件数、トークン、キャパシティの読み取り値はそのままの出力です。DynamoDB Local はドキュメントどおりの丸め規則でキャパシティを計算します。絶対値は挙動の形を示すデモとして扱い、サイジングの前に実際のサービスで自分のテーブルを測定してください。