LoginSignup
7
3

More than 1 year has passed since last update.

【AWS CLI】【DynamoDB】パーティションキーの部分一致で項目を絞り込んだ上で出力する方法

Posted at

はじめに

DynamoDB から CLI で項目を取得する際、通常はaws dynamodb queryを使用するかと思います。

しかし、aws dynamodb queryでパーティションキーを用いた絞り込みを行う場合、上記のページにあるように完全一致(=)しか使用することができません。

そのため、パーティションキーを部分一致で絞り込んだ上で項目を出力したい場合は、代わりにaws dynamodb scan を使用する必要があります。

結論

例えば、以下のように「your_partition_keyの値がfooから始まる」条件で検索したい場合、

  1. command を query から scan に変更
  2. --key-condition-expressionオプションを--filter-expressionに変更

のように修正します。

# Before
$ aws dynamodb query \
    --table-name your_table_name \
    --key-condition-expression 'begins_with(your_partition_key, :your_partition_key)' \
    --expression-attribute-values '{":your_partition_key":{"S":"foo"}}'

#  An error occurred (ValidationException) when calling the Query operation: Query key condition not supported
# After
$ aws dynamodb scan \
    --table-name your_table_name \
    --filter-expression 'begins_with(your_partition_key, :your_partition_key)' \
    --expression-attribute-values  '{":your_partition_key":{"S":"foo"}}'

# {
#     "Items": [
#         {...}
#      ]

参考

フィルターに使用できる条件式

参考: 比較演算子および関数リファレンス - Amazon DynamoDB

全部は試していませんが、以下が動作することは確認しました。

  • attribute_exists
  • attribute_not_exists
  • begins_with
  • contains

注意点

DynamoDB の項目のデータ量の合計が 1MB を超える場合、1 度に フィルター結果を全件取得できない

参考: テーブルクエリ結果をページ分割する - Amazon DynamoDB

DynamoDB の項目のデータ量の合計が 1MB を超える場合、1 度目のレスポンスに含まれるLastEvaluatedKeyを用いて、再度レスポンスを取得する必要があります。
(以下、一部上記のページより抜粋)

# 最初のリクエスト
$ aws dynamodb query --table-name Movies \
    --projection-expression "title" \
    --key-condition-expression "#y = :yyyy" \
    --expression-attribute-names '{"#y":"year"}' \
    --expression-attribute-values '{":yyyy":{"N":"1993"}}' \
    --page-size 5 \
    --debug

# 2017-07-07 11:13:15,603 - MainThread - botocore.parsers - DEBUG - Response body:
# b'{"Count":5,"Items":[{"title":{"S":"A Bronx Tale"}},
# {"title":{"S":"A Perfect World"}},{"title":{"S":"Addams Family Values"}},
# {"title":{"S":"Alive"}},{"title":{"S":"Benny & Joon"}}],
# "LastEvaluatedKey":{"year":{"N":"1993"},"title":{"S":"Benny & Joon"}},
# "ScannedCount":5}'

# 上で返却された LastEvaluatedKey を、queryに含めると、続きから取得可能
$ aws dynamodb query --table-name Movies \
    --projection-expression "title" \
    --key-condition-expression "#y = :yyyy" \
    --expression-attribute-names '{"#y":"year"}' \
    --expression-attribute-values '{":yyyy":{"N":"1993"}}' \
    --page-size 5 \
    --last-evaluated-key '{"year":{"N":"1993"},"title":{"S":"Benny & Joon"}}' \ # <- Here
    --debug

こちらの挙動はscanでもqueryでも共通です。
しかし、しきい値の 1MB は、queryKeyConditionExpressionの適用後、query, scanFilterExpression適用前に適用されます。
そのため、scanを使用した場合は、この制限がqueryで絞り込む場合よりもかかりやすくなります。

1Query オペレーションで、最大 1 MB のデータを取得できます。この制限は、結果への FilterExpression の適用前に適用されます。レスポンスに LastEvaluatedKey が存在し、Null 以外の場合、結果セットをページ分割する必要があります (テーブルクエリ結果をページ分割する を参照)。

参考: DynamoDB でのクエリの操作 - Amazon DynamoDB

QueryFilter, KeyConditions はレガシーパラメータなので注意

上記で紹介したように、それぞれ以下のパラメータを使用します。

  • QueryFilter -> FilterExpression
  • KeyConditions -> KeyConditionExpression

参考まとめ

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3