查询DynamoDB GSI时要求提供主表分区键的问题解决
DynamoDB全局二级索引(GSI)查询异常解决记录
主表结构
- 分区键:
test_id(字符串类型) - 排序键:
version(字符串类型) - 其他属性:
createdAt、tags等
GSI创建背景与结构
需求是获取所有排序键为v0_test的条目,且不按分区键过滤,为避免全表扫描,创建了如下GSI:
- 分区键:
version(字符串类型) - 排序键:
createdAt(数字类型) - 其他属性:
test_id、tags等
问题现象
在AWS控制台中查询该GSI,按分区键v0_test可得到预期结果,但在Node.js 16.x运行时的Lambda函数中查询报错。
原查询代码
const dynamoDb = new AWS.DynamoDB.DocumentClient(); let params = { TableName: dynamoTable, IndexName: dynamoTableIndex , KeyConditionExpression: 'version = :v0 AND createdAt BETWEEN :tLower AND :tUpper', ExpressionAttributeValues: { ':v0': 'v0_test', ':tUpper': Math.floor(Date.now() / 1000).toString(), ':tLower': '0' } }; let result = await dynamoDb.query(params).promise(); console.log("Success", result);
报错信息
ERROR ValidationException: Query condition missed key schema element: test_id
系统错误要求提供主表的分区键。
尝试过的无效方法
- 改用
AWS.DynamoDB替代AWS.DynamoDB.DocumentClient,仍报错 - 将查询中的
version改为test_id,报错:ERROR ValidationException: Query condition missed key schema element: version - 在
KeyConditionExpression中同时传入version和test_id,报错:ERROR ValidationException: KeyConditionExpressions must only contain one condition per key - 新建DynamoDB表和GSI,仍出现相同错误
解决方法
通过指定ExpressionAttributeNames,用别名替代属性名后问题解决,修改后的代码如下:
const dynamoDb = new AWS.DynamoDB.DocumentClient(); let params = { TableName: 'CLASSIFIER_TESTS_DEV_us-east-1', IndexName: 'version-createdAt-index', KeyConditionExpression: '#versionAttr = :version AND #ca BETWEEN :tLower AND :tUpper', ExpressionAttributeNames: { "#versionAttr": "version", "#ca": "createdAt" }, ExpressionAttributeValues: { ":version": "v0_test", ":tUpper": Date.now(), ":tLower": 0 } }; let result = await dynamoDb.query(params).promise();
内容的提问来源于stack exchange,提问作者agus97v
相关产品推荐
相关产品推荐

