環境
- Nest.JS
- DynamoDB
- ※環境は関係なさそうなのでバージョン等は割愛
事象
DynamoDB上にデータは存在するにも関わらず、データが取れない事象がありました。
「Between句が効いていないのでは」
「timestampがおかしいのでは」
「GSI(グローバルセカンダリインデックス)が効いていないのでは」
などと疑いましたが、どれも正しく設定されていました。
結論
DynamoDBは、クエリー・スキャン共に1回のリクエストで最大1MBまでしかレスポンスできない制約がありました。
参考: https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Limits.html
解決方法
DynamoDBのレスポンスにある「LastEvaluatedKey」を使用します。
「LastEvaluatedKey」は、まだ取得できないデータがある場合にオブジェクトを返してきます。
そのオブジェクトを「ExclusiveStartKey」に設定し、再度リクエストすることで、欲しかったデータを複数回のリクエストに分割して全件取得することができます。
実際のコードがこちら
/**
* @param clients DynamoDB.DocumentClient
* @param params
*/
async getAllQuery(clients, params) {
let items = [];
let startKey = '';
while (true) {
if (startKey) {
params.ExclusiveStartKey = startKey;
}
const res = await clients.dynamo.query(params).promise();
if (res.Items) {
items = items.concat(res.Items);
startKey = res.LastEvaluatedKey;
}
if (!startKey) {
break;
}
}
return items;
}
まとめ
原因がわかればなんてことないですよね。
とても簡単な処理で値を取り出すことができました。
DynamoDBなんてグラフのデータにしたり1MB超えること多々あると思うので、困っている方の参考になれば幸いです。