如何使用 AWS iot 和 dynamodbv2 在同一行中存储多条消息

How to store multiple message in same row with AWS iot and dynamodbv2

我正在使用 AWS Iot 核心和 dynamodbv2 来存储我的 mqtt 消息。

我的 table 主分区键 deviceId 和规则查询语句 as

SELECT *, topic(2) AS deviceId FROM 'device/+' .

第一条消息发布{"deviceId": "Name1","temperature":25}.

table 商店喜欢:

deviceId    temperature 
Name1       25

当我发布第二条消息时 {"deviceId": "Name1","setpoint":23},

它将取代之前的消息。

deviceId    setpoint 
Name1       23

我要单独发布消息。是否可以保留上一条消息并像这样存储两条消息?谢谢。

deviceId    temperature    setpoint 
Name1       25             23

看起来您正在使用 dynamoDB PutItem 方法,如果找到相同的主键,该方法将替换一个项目。

根据 Aws DynamoDB docs PutItem 方法:

Creates a new item, or replaces an old item with a new item (including all the attributes). If an item already exists in the specified table with the same primary key, the new item completely replaces the existing item. You can perform a conditional put (insert a new item if one with the specified primary key doesn't exist), or replace an existing item if it has certain attribute values.

要确保新项目 不会替换现有项目,请使用条件 put 操作并将 Exists 设置为 false。

要了解如何使用 Node.js 执行此操作,请查看 here

来自tutorial you mentioned and the way the system behaves, it looks like the PutItem的方法用于将元素插入到DynamoDB中。这意味着如果已经存在具有相同主键的项目,则新项目将覆盖旧项目。

这里的问题是,您的 deviceId 是一个错误的主键,因为它不是唯一的。您希望有多个主键 Name1 的条目,这是不可能的。相反,我建议调整您的 SQL 语句以获得唯一密钥。此密钥可以使用 AWS IoT Core 的 timestamp() or traceid() 函数生成。你的 SQL 看起来像这样:

SELECT *, 
       topic(2) AS deviceId, 
       timestamp() as timestamp, 
       traceid() as traceId 
FROM 'device/+'

然后您使用 timestamptraceId 或由 timestamp+deviceId 组成的复合键作为您的 主键deviceId 可用作 排序键 。教程中也是这样描述的

  • sample_time is a primary key and describes the time the sample was recorded.
  • device_id is a sort key and describes the device that provided the sample
  • device_data is the data received from the device and formatted by the rule query statement

请注意,您不能像这样存储数据

deviceId    temperature    setpoint 
Name1       25             23

除非您的 MQTT 消息包含温度和设定值。否则它们将始终单独存储。

按照您的描述存储数据的唯一“解决方法”是编写一个小的 lambda,使用 PutItem to store the data if none exists and UpdateItem 将“设定值”或“温度”添加到已经存在的项目中。您很可能甚至可以不用 PutItem 作为 UpdateItem:

Edits an existing item's attributes, or adds a new item to the table if it does not already exist. You can put, delete, or add attribute values. You can also perform a conditional update on an existing item (insert a new attribute name-value pair if it doesn't exist, or replace an existing name-value pair if it has certain expected attribute values).

如果您只保留“温度”和“设定值”的最新值就可以了,此设置就可以了。如果您需要保留“温度”如何随时间变化的历史记录,那么您应该在消息中添加时间戳或使用 SQL timestamp() 函数并将时间戳用作或作为您的一部分首要的关键。如果你计划有很多,我的意思是很多,设备将它们的数据发送到 AWS IoT,那么时间戳作为主键可能不够好,你需要有一个由时间戳和 deviceId 组成的复合来保持独特。

有关 DynamoDB 工作原理、分区键、排序键、索引等的精彩介绍,请参见 this video of Marcia Villalba