Banging my head for a couple hours with this and I can't understand why it's not working 🙁
I have a DynamoDBv2 table (top level attributes are shown as separate columns) with items like these:
{
gateway: 'gateway1',
device_id: '2',
state: { temperature: 20, humidity: 30, pressure: 101049 },
timestamp: 1498331237261
},
{
gateway: 'gateway1',
device_id: '2',
state: { temperature: 20, humidity: 30, pressure: 101049, lat: 2, long: 1 },
timestamp: 1498331237262
}
Primary partition key: device_id
(String)
Primary sort key: timestamp
(Number)
I'm trying to get the latest item for a certain device that has the attributes lat
and long
.
const docClient = new AWS.DynamoDB.DocumentClient();
const id = 2;
const params = {
TableName: 'device_telemetry',
KeyConditionExpression: 'device_id = :id',
ProjectionExpression: '#s, #lat, #lng, #ts',
FilterExpression: 'attribute_exists(#lat) AND attribute_exists(#lng)',
ExpressionAttributeNames: {
'#s': 'state',
'#lat': 'state.lat',
'#lng': 'state.long',
'#ts': 'timestamp'
},
ExpressionAttributeValues: {
':id': id.toString()
},
ScanIndexForward: false,
Limit: 1
};
const onResult = (res) => {
console.info('devices res for: ', id, res);
};
console.info('query: ', params);
docClient.query(params).promise().then(onResult);
If I use attribute_exists(#s)
, then it works, but for #lat
or #long
it doesn't 🙁
What am I doing wrong? 😖
You can not directly access nested attributes. You should declare in this format
ExpressionAttributeNames: {
'#s': 'state',
'#lat': 'lat',
'#lng': 'long',
'#ts': 'timestamp'
},
and access the attributes in following way:
FilterExpression: 'attribute_exists(#s.#lat) AND attribute_exists(#s.#lng)',
Seems I was mixing item attributes with the attributes of the map value of state
.
It was confusing when I was looking at the generated result.
Sorry for the noise.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With