Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DynamoDb query ONLY by primary key

I'm pretty new to DynamoDB (NO Sql in general) and I'm having some troubles to understand how to form a simple query..

What I want to perform is a simple SELECT FROM in SQL but it seems I cannot get it done.

My table definition is basically:

Table name snsNotifications Primary partition key recipientId (Number) <--- This is a user id Primary sort key snsID (String) <--- This is the SNS message id

it follows some attributes (like readAt).

The query I want to perform is:

SELECT from snsNotifications WHERE recipientId=X and readAt=x

I even can perform this query on AWS UI: Screenshot

My lambda function uses the following :

var params = {
            TableName : "snsNotifications",
            KeyConditionExpression   : "recipientId = :recipientId and readAt = :readAt",
            ExpressionAttributeValues: {
                ":recipientId": parseInt(msg.recipientId),
                ":readAt"     : 0,
            }
        };

        docClient.query(params, function(err, data) {
            if (err) {
                console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
            } else {
                console.log("Query succeeded.");
                data.Items.forEach(function(item) { ... }

But i get the following error:

Unable to query. Error: { "message": "Query condition missed key schema element: snsID", "code": "ValidationException", "time": "2017-11-20T18:19:40.419Z", "requestId": "J73RIAE09GDRD1Q47I9OLCU7N7VV4KQNSO5AEMVJF66Q9ASUAAJG", "statusCode": 400, "retryable": false, "retryDelay": 44.175697630271316 }

So basically it is complaining of snsID (primary sort key) being not defined on the query itself.

Any lights? I bet is just some small detail.

Thanks in advance

like image 596
Manuel Rodriguez Avatar asked Dec 10 '22 09:12

Manuel Rodriguez


2 Answers

Replace the readAt in KeyConditionExpression with snsId. If you dont want to include the sort key and wanted to filter the data by non-key attribute readAt, use FilterExpression for it.

KeyConditionExpression can have only partition key or sort key. For non key attributes, you should use FilterExpression.

like image 138
notionquest Avatar answered Jan 04 '23 17:01

notionquest


Thank you @notionquest, that made the trick.

Attached answer to who may help:

var params = {
            TableName : "snsNotifications",
            KeyConditionExpression   : "recipientId = :recipientId",
            FilterExpression: "readAt = :readAt",
            ExpressionAttributeValues: {
                ":recipientId": parseInt(msg.recipientId),
                ":readAt"     : 0,
            }
        };
like image 39
Manuel Rodriguez Avatar answered Jan 04 '23 16:01

Manuel Rodriguez