はじめに
DynamoDB から CLI で項目を取得する際、通常はaws dynamodb query
を使用するかと思います。
しかし、aws dynamodb query
でパーティションキーを用いた絞り込みを行う場合、上記のページにあるように完全一致(=
)しか使用することができません。
そのため、パーティションキーを部分一致で絞り込んだ上で項目を出力したい場合は、代わりにaws dynamodb scan
を使用する必要があります。
結論
例えば、以下のように「your_partition_key
の値がfoo
から始まる」条件で検索したい場合、
- command を query から scan に変更
-
--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 は、query
のKeyConditionExpression
の適用後、query
, scan
のFilterExpression
適用前に適用されます。
そのため、scan
を使用した場合は、この制限がquery
で絞り込む場合よりもかかりやすくなります。
1Query オペレーションで、最大 1 MB のデータを取得できます。この制限は、結果への FilterExpression の適用前に適用されます。レスポンスに LastEvaluatedKey が存在し、Null 以外の場合、結果セットをページ分割する必要があります (テーブルクエリ結果をページ分割する を参照)。
参考: DynamoDB でのクエリの操作 - Amazon DynamoDB
QueryFilter
, KeyConditions
はレガシーパラメータなので注意
上記で紹介したように、それぞれ以下のパラメータを使用します。
-
QueryFilter
->FilterExpression
-
KeyConditions
->KeyConditionExpression