初級読了 2 分

DynamoDBを降順でクエリする方法

デフォルトでは、DynamoDBのQueryはアイテムをソートキーの昇順で返します。しかし、 ほとんどの「最新のものを取得する」アクセスパターンは、その逆 — 新しい順を求めます。 そのつまみは、Queryにある単一のブール値、**ScanIndexForward**です。これをfalseに 設定すると、同じクエリがパーティションを逆順に読み取ります。

たった1つのパラメータですが、人をつまずかせます。事後に結果をソートすること (DynamoDBはそれをしません)と混同しやすく、また名前が制御する内容と逆向きに読める からです。

DynamoDBを降順でクエリするにはどうすればいいですか?

**ScanIndexForward=false**をQueryに設定します。デフォルトでは、DynamoDBはアイテムをソートキーの昇順で返します。このブール値1つを切り替えるだけでパーティションを逆順に読み取り、ソートキーがタイムスタンプやシーケンスの場合に新しい順の結果が得られます。順序が変わるだけで、どのアイテムが一致するかは変わらず、逆順の読み取りは順方向と同じコストです。

  • ScanIndexForward=true(デフォルト) → ソートキーの昇順。
  • ScanIndexForward=false → 降順 — ソートキーがタイムスタンプやシーケンスなら新しい順。
  • 順序にのみ影響し、どのアイテムが一致するかには影響しません — それを決めるのは 依然としてキー条件です。
  • 無料です。 逆順は順方向と同じコストです。DynamoDBはどちらの場合もパーティションに 保存された順序を読み取ります。
  • Limitと組み合わせて、「最新のN件」を1回の安価な読み取りで取得しましょう。

問題:「最新のものを先に見せて」

マルチプレイヤーのリーダーボードを運用していて、各プレイヤーのスコアイベントを1つの パーティションキーの下に、増加するタイムスタンプでソートして保存しているとします:

PK: GAME#42   SK: SCORE#2026-06-27T10:00:00Z   points
PK: GAME#42   SK: SCORE#2026-06-27T10:05:00Z   points
PK: GAME#42   SK: SCORE#2026-06-27T10:09:00Z   points

ダッシュボードは最新のスコアを必要とします。GAME#42に対する単純なQueryは それらを古い順で返すので、すべてを読み取ってアプリ内で逆順にしたくなります — 無駄が 多く、Limitを追加した瞬間に壊れます。DynamoDBは新しい順で直接返すことができます。

ScanIndexForwardの仕組み

パーティション内のアイテムは、物理的にソートキー順に保存されています。Queryは その順序をたどります。ScanIndexForwardはそのたどる方向を選ぶだけです:

  • true(デフォルト) — 最も小さいソートキーから始め、上へ進む(昇順)。
  • false — 最も大きいソートキーから始め、下へ進む(降順)。

重要なのは、これはテーブルではなく読み取りの性質だということです — 同じアイテム、 同じキー条件で、ただ逆になるだけです。そしてDynamoDBはすでにソート済みのデータに対して 方向を選んでいるだけなので、降順の読み取りは昇順と まったく同じだけ安価 です。Limit=10と組み合わせれば、「最新10件のスコアイベント」を1回の最小コストの Queryで取得できます。

true(デフォルト)falseQuery GAME#42ScanIndexForward?古いスコアが先新しいスコアが先

1つ微妙な点があります:降順の結果セットを逆方向にページングするとき、 LastEvaluatedKey/ExclusiveStartKeyのカーソルは引き続き機能します — ただし、同じ スキャンのすべてのページでScanIndexForward=falseを一貫させてください。さもないと、 カーソルの方向と順序が食い違います。

DynoTableでのクエリ構築

キー条件そのものを組み立てる(そして対応する属性名/値マップを確認する)には、 DynamoDB式ビルダーを使ってください。

DynoTableでは、選択したキーを通じてタブを読み取り、タブ上のトグルでソート方向を設定します — ScanIndexForwardを手書きする必要はありません。トグルを切り替えて、新しい順の結果を プレビューしましょう。

DynoTableでクエリタブを降順(新しい順)に切り替えているところ。
DynoTableでクエリタブを降順(新しい順)に切り替えているところ。

落とし穴と次のステップ

  • ScanIndexForwardは逆順にするだけで、任意の属性でソートするわけではない。 順序は 常にソートキーによります — 別のものでソートするには、その属性をソートキーとして 持つ必要があります(多くはGSI経由)。
  • アプリ内で全件読み取り→逆順にしてはいけない — フラグを設定してLimitを追加 しましょう。
  • 複数ページのスキャンをページングする間、フラグを一貫させる — さもないとカーソルが 順序とぶつかります。
  • 数値で新しい順にしたい? ソートキーが正しくソートされるようにしましょう — 辞書順が 一致するよう数値をゼロ埋めします。
  • 関連: ソートキー戦略ページネーション

APIパラメータに触れずに結果の順序を反転したいですか? DynoTableをダウンロードして、テーブルを直接クエリしてください。

更新日