使用 begins_with 查询 dynamodb
Query dynamodb with begins_with
我有一个 table 使用无服务器框架创建的:
resources:
Resources:
withdawlRequestTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:provider.environment.WITHDRAWAL_REQUEST_TABLE}
AttributeDefinitions:
- AttributeName: pk
AttributeType: S
- AttributeName: sk
AttributeType: S
KeySchema:
- AttributeName: pk
KeyType: HASH
- AttributeName: sk
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
GlobalSecondaryIndexes:
- IndexName: sk-pk-index
KeySchema:
- AttributeName: sk
KeyType: HASH
- AttributeName: pk
KeyType: RANGE
Projection:
ProjectionType: ALL
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
我现在正尝试使用 begins_with
运算符查询 table,但我不断收到此错误:
INFO ValidationException: Invalid KeyConditionExpression: Incorrect operand type for operator or function; operator or function: begins_with, operand type: M
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:52:27)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)
at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
code: 'ValidationException',
time: 2021-04-02T19:51:30.009Z,
requestId: 'NC1F1C5708U6ARMJKQ05IKJLE3VV4KQNSO5AEMVJF66Q9ASUAAJG',
statusCode: 400,
retryable: false,
retryDelay: 14.409529163729463
}
不确定我做错了什么,因为 pk 是分区键而 sk 是排序键,我应该可以使用 KeyConditionExpression
进行查询,但它不起作用。
这是我在 nodejs
中的代码:
module.exports.get = async function(userId, withdrawlId) {
const getParams = {
TableName: tableName,
KeyConditionExpression: 'pk = :userId AND begins_with(sk, :withdrawlId)',
ExpressionAttributeValues: {
':userId': {'S': 'USER#' + userId},
':withdrawlId': {'S': withdrawlId}
}
}
let getResult
try {
getResult = await dynamodb.query(getParams).promise()
return getResult.Item
} catch (error) {
console.log(error)
throw new Error(error)
}
}
使用 DocumentClient
时,您没有在 ExpressionAttributeValues
中指定类型。所以你的代码应该看起来像这样。
module.exports.get = async function(userId, withdrawlId) {
const getParams = {
TableName: tableName,
KeyConditionExpression: '#pk = :userId AND begins_with(#sk, :withdrawlId)',
ExpressionAttributeValues: {
':userId': 'USER#' + userId,
':withdrawlId': withdrawlId
},
ExpressionAttributeNames: {
'#pk': 'pk',
'#sk': 'sk'
}
}
let getResult
try {
getResult = await dynamodb.query(getParams).promise()
return getResult.Items
} catch (error) {
console.log(error)
throw new Error(error)
}
}
我总是倾向于使用 ExpressionAttributeNames
来避免潜在的保留字冲突,但我认为在您的情况下您不必这样做。
另请注意,结果有一个 Items
属性,而不是 Item
属性。
我有一个 table 使用无服务器框架创建的:
resources:
Resources:
withdawlRequestTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:provider.environment.WITHDRAWAL_REQUEST_TABLE}
AttributeDefinitions:
- AttributeName: pk
AttributeType: S
- AttributeName: sk
AttributeType: S
KeySchema:
- AttributeName: pk
KeyType: HASH
- AttributeName: sk
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
GlobalSecondaryIndexes:
- IndexName: sk-pk-index
KeySchema:
- AttributeName: sk
KeyType: HASH
- AttributeName: pk
KeyType: RANGE
Projection:
ProjectionType: ALL
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
我现在正尝试使用 begins_with
运算符查询 table,但我不断收到此错误:
INFO ValidationException: Invalid KeyConditionExpression: Incorrect operand type for operator or function; operator or function: begins_with, operand type: M
at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:52:27)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:688:14)
at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:690:12)
at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
code: 'ValidationException',
time: 2021-04-02T19:51:30.009Z,
requestId: 'NC1F1C5708U6ARMJKQ05IKJLE3VV4KQNSO5AEMVJF66Q9ASUAAJG',
statusCode: 400,
retryable: false,
retryDelay: 14.409529163729463
}
不确定我做错了什么,因为 pk 是分区键而 sk 是排序键,我应该可以使用 KeyConditionExpression
进行查询,但它不起作用。
这是我在 nodejs
中的代码:
module.exports.get = async function(userId, withdrawlId) {
const getParams = {
TableName: tableName,
KeyConditionExpression: 'pk = :userId AND begins_with(sk, :withdrawlId)',
ExpressionAttributeValues: {
':userId': {'S': 'USER#' + userId},
':withdrawlId': {'S': withdrawlId}
}
}
let getResult
try {
getResult = await dynamodb.query(getParams).promise()
return getResult.Item
} catch (error) {
console.log(error)
throw new Error(error)
}
}
使用 DocumentClient
时,您没有在 ExpressionAttributeValues
中指定类型。所以你的代码应该看起来像这样。
module.exports.get = async function(userId, withdrawlId) {
const getParams = {
TableName: tableName,
KeyConditionExpression: '#pk = :userId AND begins_with(#sk, :withdrawlId)',
ExpressionAttributeValues: {
':userId': 'USER#' + userId,
':withdrawlId': withdrawlId
},
ExpressionAttributeNames: {
'#pk': 'pk',
'#sk': 'sk'
}
}
let getResult
try {
getResult = await dynamodb.query(getParams).promise()
return getResult.Items
} catch (error) {
console.log(error)
throw new Error(error)
}
}
我总是倾向于使用 ExpressionAttributeNames
来避免潜在的保留字冲突,但我认为在您的情况下您不必这样做。
另请注意,结果有一个 Items
属性,而不是 Item
属性。