在 AWS ServerLess 中使用来自 dynamodb 的 gsi 密钥检索员工详细信息

To retrieve Employee Details by using gsikey from dynamo db in AWS ServerLess

我想使用 GSI 密钥从 dynamoDb 中检索员工详细信息。这里我有一个 table 描述了员工和部门之间的关系,我想通过使用 employeeId 来获取员工详细信息。 无服务器模板如下

    service: dynaUser

custom:
  settings:
    POSTS_TABLE: Tbl-tblMasterDepartmentEmp1
provider:
  name: aws
  runtime: nodejs10.x
  region: ap-northeast-1
  environment: ${self:custom.settings}
  
  iamRoleStatements:
   - Effect: "Allow"
     Action:
        - dynamodb:Query
        - dynamodb:DescribeTable
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
     Resource:
      - "arn:aws:dynamodb:${self:provider.region}:*:table/${self:custom.settings.POSTS_TABLE}"      
   - Effect: Allow
     Action:
        - dynamodb:Query
        - dynamodb:Scan
     Resource: 
      - "arn:aws:dynamodb:${self:provider.region}:*:table/${self:custom.settings.POSTS_TABLE}/index/*"
functions:
  createPost:
    handler: handler.createPost
    events:
    - http:
        path: /createEmployee
        method: post
        # integration: lambda
        # request:
        #   passThrough: NEVER
  createDepartment:
    handler: handler.createDepartmententry
    events:
    - http:
        path: /createDepartment
        method: post
        # integration: lambda
        # request:
        #   passThrough: NEVER        
  getEmpDataByID:
    handler: handler.getEmployeeDetails
    events:
    - http:
        path: /getemployee/{id}
        method: get
  getEmpDataByDeptID:
    handler: handler.getEmployeeDetailsByDeptId
    events:
    - http:
        method: get
        path: /getemployeeByDept
        integration: lambda
        request:
          template:
            application/json: '{ "deptId" : "$input.params(''deptId'')" }'  
resources:
  Resources:
    PostsTable:
      Type: AWS::DynamoDB::Table
      Properties:
        AttributeDefinitions:
        - AttributeName: Pk_id
          AttributeType: "S"  
        - AttributeName: Sk_id
          AttributeType: "S"  
        - AttributeName: cat_type
          AttributeType: "S"  
        KeySchema:
        - AttributeName: "Pk_id"
          KeyType: "HASH"
        - AttributeName: "Sk_id"
          KeyType: "RANGE"
        TableName: ${self:custom.settings.POSTS_TABLE}
        GlobalSecondaryIndexes:
          - IndexName: empIdIndex
            KeySchema:
              - AttributeName: cat_type
                KeyType: HASH
              - AttributeName: Sk_id
                KeyType: RANGE
            Projection:
              ProjectionType: 'ALL'
        TimeToLiveSpecification:
          AttributeName: ttl
          Enabled: true
        BillingMode: PAY_PER_REQUEST

还使用查询从 Db 和 Given 中检索员工数据

//通过Id获取员工详情

module.exports.getEmployeeDetails = (event, context, callback) => {
  const id = event.pathParameters.id;
  const params = {
    Key: {
      Sk_id: id,
      type:"Stud"
    },
    TableName: deptTable,
    IndexName:"empIdIndex"
  };

  return db
    .get(params)
    .promise()
    .then((res) => {
      if (res.Item) callback(null, response(200, res.Item));
      else callback(null, response(404, { error: 'Post not found' }));
    })
    .catch((err) => callback(null, response(err.statusCode, err)));
};

  here I inclued error like

 {
    "message": "The provided key element does not match the schema",
    "code": "ValidationException",
    "time": "2020-12-09T17:27:24.439Z",
    "requestId": "E4QR1ITHPKNE7TQDS6S7R211O7VV4KQNSO5AEMVJF66Q9ASUAAJG",
    "statusCode": 400,
    "retryable": false,
    "retryDelay": 22.385564476989238
}

如何从 dynamodb 中检索项目而不出现任何错误,我是 aws 世界的新手?

检查错误信息:

Invalid KeyConditionExpression: Attribute name is a reserved keyword; reserved keyword: type

DynamoDB 告诉您您的 KeyCondition 使用了一个名为 type 的保留关键字。保留关键字的完整列表记录在 here.

现在看看你的KeyConditionExpression:

'emp_id = :emp_id AND type = :type '

注意:此表达式末尾也有空格。

您有两种选择来解决此问题:

  1. 更改属性的名称。
  2. 使用ExpressionAttributeNames“重命名”查询中的属性。

选项 1 不言自明,选项 2 可能如下所示:

const params = {
    KeyConditionExpression: 'emp_id = :emp_id AND #employeeType = :type',
    ExpressionAttributeNames: { 
        "#employeeType": "type" 
    },
    ExpressionAttributeValues: {
        ':emp_id': {'S': '1'},
        ':type':{'S':'Stud'}
    },
    TableName: deptTable,
    IndexName:"empIdIndex"   
};

两件事发生了变化:

  1. KeyConditionExpression 现在使用名为 #employeeType 的“占位符”属性名称(# 似乎是常见的 DynamoDB 约定)而不是保留关键字 type .
  2. 占位符名称 #employeeTypeExpressionAttributeNames 中的实际属性名称 type 之间现在存在“映射”。

就个人而言,我建议不要使用保留关键字作为属性名称(选项 1)。