使用 begin_with 查询 dynamodb

Rém*_*émi 2 node.js amazon-dynamodb dynamodb-queries

我有一个使用无服务器框架创建的表:

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
Run Code Online (Sandbox Code Playgroud)

我现在尝试使用运算符查询该表begins_with,但我不断收到此错误:

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
}
Run Code Online (Sandbox Code Playgroud)

不确定我做错了什么,因为 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

Jas*_*rth 5

使用时,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)
    }
}
Run Code Online (Sandbox Code Playgroud)

我倾向于总是赞成使用ExpressionAttributeNames以避免潜在的保留字冲突,但我不认为你应该在你的情况下这样做。

还要注意,结果有一个Items属性,而不是一个Item属性。