使用 AWS NodeJS Lambda 读取 AWS dynamoDB 中的过滤数据

read filtered data in AWS dynamoDB with AWS NodeJS Lambda

我想从 DynamoDB 获取元素到我的 NodeJS AWS Lambda。我想按“所有者”列选择但不起作用。我对“id​​”列尝试了相同的语法,结果没问题。在dynamoDB 中添加索引?在哪里?

'use strict';

var AWS = require('aws-sdk');
var documentClient = new AWS.DynamoDB.DocumentClient({'region': 'eu-west-1'}); 

exports.handler = function(event, context, callback) {
  
  console.log(JSON.stringify(event));

  const claims = event.requestContext.authorizer.claims;
  const username = claims['cognito:username'];
  
  var params = {
    TableName : "tp-exam",
      Key: {
        owner: username 
      }
  };
  
    documentClient.get(params, function(err, data){
      if (err) {
      console.log("Error", err);
      const errResponse = {
        statusCode: 500,
        headers: {
          "Access-Control-Allow-Origin": "*"
        },
        body: JSON.stringify({ Error: 500, device : "DynamoDB"})
      };
      callback(null, errResponse);
    } else {
      console.log("Success", data.Item);
      const response = {
        statusCode: 200,
        headers: {
          "Access-Control-Allow-Origin": "*"
        },
        body: JSON.stringify(data.Item)
      };
        callback(null, response);
    }
        
    });

};

我的错误是:

ValidationException: The provided key element does not match the schema
    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-03-01T21:46:40.263Z,
  requestId: 'C7UHG8354A92SGP2T4FRRFU4GFVV4KQNSO5AEMVJF66Q9ASUAAJG',
  statusCode: 400,
  retryable: false,
  retryDelay: 32.73628085995177
}

此错误表明您没有为 DynamoDb#get 操作提供正确的主键。

一些提示:

  • 确保您提供的分区键名称正确。您确定您的分区键属性名为 owner 吗?
  • 确保您提供了整个主键。 DynamoDB 中的主键有两种形式,简单的和复合的。一个简单的主键由一个分区键组成。复合主键由分区键 和排序键 组成。您的错误表明您 可能 有一个复合主键,但没有指定主键的排序键部分。

如果这些问题都不能解决您的问题,post 您的 DynamoDB 的详细信息 table 以便我们可以查看您的键是如何定义的。

或者,如果 owner 属性 不是 主键的一部分,并且您想按该字段进行搜索,则有几个选择。

  1. 使用 owner 作为主键创建新的 GSI
  2. 您可以使用 scan 操作按非关键属性进行搜索。

请注意,第一个选项(创建 GSI)是首选方法。

我们需要 Global Secondary Index 来获取或查询备用键。

要使用 GSI 进行查询,我们需要使用查询 api。

let docClient = new AWS.DynamoDB.DocumentClient();

documentClient.query(
  {
    TableName: "tp-exam",
    IndexName: "owner-index",
    KeyConditionExpression: "#owner_attr = :ownerVal",
    ExpressionAttributeValues: {
      ":ownerVal": "John",
    },
    ExpressionAttributeNames: {
      "#owner_attr": "owner",
    },
  },
  function (err, data) {
    console.log("err", err, "data", data);
  }
);

owner是保留关键字,所以,我们需要用ExpressAttributeNames来替换实际的属性。