首页 > 解决方案 > DynamoDB 读取问题

问题描述

我的设备收集一些数据并使用其 IoT MQTT 接口将其发送给 AWS。我的 lambda 读取数据并将其保存到 DynamoDB。下面是我的发电机中的一个示例记录,其中 timeStamp 是主分区键。

 Item{3}     

 message          String:   DOWN     

 payloadMap{4}

   direction      String:   -

   message        String:   DOWN

   timeStamp      String:   2018-08-30 07:18:09.247373

   value          String:     -70.0000    

 timeStamp      String: 2018-08-30 07:18:09.247373

然后我试图在我的小节点应用程序上查询发电机,我无法使用以下脚本访问数据:

dynamodb.getItem({
      TableName: 'myTableName',
      Key: {
        'timeStamp' : {'S': '2018-08-30 07:18:09.247373'}
      }
    },(err,result)=>{
      if(err){
        console.log(err);
      }
      else {
        console.log('success');  
      }
    });

下面是我的 dynamoDB 初始化:

function initDynamoAWS(){
  AWS.config.apiVersion = {dynamodb: '2012-08-10'};
  AWS.config.update({accessKeyId:access_key_id,
                     secretAccessKey:secret_access_key,
                     region:'us-west-2'});
  dynamodb = new AWS.DynamoDB({ARN:ARN});
}

所有凭据都很好,因为我可以获得包含所有详细信息的 dynamodb.describeTable,但我无法从表中获取单个项目,但我只能得到“错误:提供的关键元素与架构不匹配”。我错过了什么?

当我将代码更改为:

    let params = {};
    let key = {'timeStamp' :'2018-08-30 07:18:09.247373'};
    params.TableName = 'myTableName';
    params.Key = key;
    dynamodb.getItem(params,(err,result)=>{
      if(err){
        // debugger;
        console.log(err);
      }
      else {
        console.log('success');  
      }
    });

我收到一个不同的错误:“InvalidPatemeterType:预期的 params.Key['timeStamp'] 是一个结构”“UnexpectedPatameter:在 params.Key['timeStamp'] 中找到意外的键 '0'”......以及同样的错误最多 25 的数字。

我可以通过“描述表”从 AWS 获取有关我的表的以下详细信息

Table : AttributeDefinitions : 
  Array(2) 
     0 : AttributeName : "message"
         AttributeType : "S"
     1 : AttributeName : "timeStamp" 
         AttributeType : "S"
     ItemCount : 42 
TableSizeBytes : 5434 TableStatus : "ACTIVE"
KeySchema:
  Array(2)
  0:{AttributeName: "timeStamp", KeyType: "HASH"}
  1:{AttributeName: "message", KeyType: "RANGE"}

标签: node.jsamazon-web-servicesamazon-dynamodb

解决方案


问题是您的表有一个复合主键timeStamp + message. 为了从该表中获取项目,您需要提供该项目的完整密钥。您只提供时间戳。

如果要查找与特定时间戳匹配的所有项目,则需要使用query而不是getItem

下面是一个使用查询的例子:

const params = {
  ExpressionAttributeValues: {
    ':v1': {
      S: '2018-08-30 07:18:09.247373',
    },
  },
  KeyConditionExpression: '#t = :v1',
  ExpressionAttributeNames: { '#t': 'timeStamp' },
  TableName: 'myTableName',
};

dynamodb.query(params, (err, data) => {
  if (err) {
    console.log('query error:', err);
  } else {
    console.log('query data:', data);
  }
});

请注意,这timeStamp是一个DynamoDB 保留字。如果您需要编写包含与 DynamoDB 保留字冲突的属性名称的表达式,则需要定义一个表达式属性名称以用于代替保留字。我在这个例子中使用#t过。timeStamp

PS 分区键是时间戳是不寻常的。通常,时间戳将是排序键,在您的情况下,message它将是项目的简单属性,而不是排序键。您可能需要重新考虑您的数据库架构。如果您只是在寻找一个唯一的、不透明的标识符,那么您可以使用 UUID。


推荐阅读