From the tutorial you mentioned and the way the system behaves, it looks like the PutItem method is used to insert elements into DynamoDB. Meaning new items will overwrite old items if an item with the same primary key already exists.
The problem here is, that your deviceId
is a bad primary key as it is not unique. You expect to have more than one entry with primary key Name1
which is not possible. Instead, I suggest to adjust your SQL statement to get a unique key. This key could be generated with the timestamp() or traceid() functions of AWS IoT Core. Your SQL could the look ike this:
SELECT *,
topic(2) AS deviceId,
timestamp() as timestamp,
traceid() as traceId
FROM 'device/+'
Then you use the timestamp
or traceId
or a compound key made up of timestamp
+deviceId
for instance as your primary key. The deviceId
can be used as the sort key. This is also how it was described in the tutorial
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
Be aware, that you cannot store the data like this
deviceId temperature setpoint
Name1 25 23
unless your MQTT message containts temperature and setpoint. Otherwise they will always be stored separately.
The only "workaround" to store the data as you described is to write a small lambda that uses PutItem to store the data if none exists and UpdateItem to add "setpoint" or "temperature" to an already existing item. You could, most likely, even do without PutItem as 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).
If you are fine with only keeping the latest value of "temperature" and "setpoint" this set up is fine. If you need to keep a history of how the "temperature" changed over time then you should either add a timestamp to your message or use the SQL timestamp()
function and use the timestamp as or as part of your primary key. In case you plan to have a lot, and I mean a lot, of devices sending their data to AWS IoT then the timestamp may not be good enough as a primary key and you need to have a compound made up by the timestamp and deviceId to keep it unique.
A great introduction on how DynamoDB works, partition keys, sort keys, indexes and more can be found in this video of Marcia Villalba.