TypeScript环境下使用@aws-sdk/lib-dynamodb的QueryCommand获取全量宝可梦数据的ValidationException问题问询
解决DynamoDB全量获取数据的问题
你遇到的这个报错是因为DynamoDB的QueryCommand必须针对主键(分区键/排序键)设置查询条件——它是用来精准查询主键相关数据的操作,没法直接用来全量扫表。如果要获取表中所有数据,你应该使用ScanCommand而不是QueryCommand。
修改后的代码示例
// 替换QueryCommand为ScanCommand import { ScanCommand } from "@aws-sdk/lib-dynamodb"; // ... 其他初始化代码 ... const response = await this.dynamoDbClient.send( new ScanCommand({ TableName: this.tableName }) ); const array = response?.Items?.map( item => new PokemonDB({ pokemon: item.content, height: item.height }) ) ?? []; const max = array.reduce(function (prev, current) { return prev.height > current.height ? prev : current; }); return max.height;
额外注意事项
- 如果你的宝可梦数据表数据量很大(单次
Scan返回数据超过1MB),ScanCommand只会返回部分数据,此时需要检查响应中的LastEvaluatedKey字段,循环发送ScanCommand并带上ExclusiveStartKey: LastEvaluatedKey,直到LastEvaluatedKey不存在,才能拿到真正的全量数据。示例逻辑如下:let allItems = []; let lastEvaluatedKey = null; do { const response = await this.dynamoDbClient.send( new ScanCommand({ TableName: this.tableName, ExclusiveStartKey: lastEvaluatedKey }) ); allItems = [...allItems, ...(response.Items || [])]; lastEvaluatedKey = response.LastEvaluatedKey; } while (lastEvaluatedKey); // 后续用allItems进行reduce计算... Scan操作会遍历表中所有项目,相比Query性能开销更大。如果业务中频繁需要查询身高最大值,建议给height字段创建全局二级索引(GSI),后续可以通过索引优化查询效率;如果只是偶尔全量查询,用Scan就足够满足需求。
内容的提问来源于stack exchange,提问作者CMorillo
相关产品推荐
相关产品推荐

