使用 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 属性。