Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DynamoDB Javascript – Query by primary key and array of range keys?

New to DynamoDB and need to do the above query, but not sure how. Here is what I'm trying currently, and I'm getting the error below.

Btw, I am using this javascript library w/ DynamoDB: https://github.com/awslabs/dynamodb-document-js-sdk

var ids = ['12313','12312313','12312313'];
var params = {
        TableName: 'apps',
        IndexName: 'state-app_id-index',
        KeyConditions: [
            DynamoDB.Condition("state", "EQ", "active"),
            DynamoDB.Condition("id", "IN", ids)
        ]
    };

    DynamoDB.query(params, function(error, response) {});

The error I am getting is as follows:

ValidationException: One or more parameter values were invalid: ComparisonOperator IN is not valid for L AttributeValue type

like image 299
ac360 Avatar asked Jun 02 '15 07:06

ac360


2 Answers

KeyConditions does not support the IN operator. The documentation for KeyCondition says what operators it does support:

For KeyConditions, only the following comparison operators are supported:

EQ | LE | LT | GE | GT | BEGINS_WITH | BETWEEN

The EQ operator only works for a single value as well:

  • EQ : Equal.

    AttributeValueList can contain only one AttributeValue of type String, Number, or Binary (not a set type). If an item contains an AttributeValue element of a different type than the one specified in the request, the value does not match. For example, {"S":"6"} does not equal {"N":"6"}. Also, {"N":"6"} does not equal {"NS":["6", "2", "1"]}.

The restrictions are basically the same for KeyConditionExpression, which is the newer, recommended way for filtering on keys. Here is a snippet from the documentation (emphasis mine):

The condition must perform an equality test on a single hash key value. The condition can also perform one of several comparison tests on a single range key value. Query can use KeyConditionExpression to retrieve one item with a given hash and range key value, or several items that have the same hash key value but different range key values

In your case, you could build out the FilterExpression in a similar way as described in this answer.

like image 171
mkobit Avatar answered Oct 06 '22 21:10

mkobit


The only way to use the IN statement is by using a filter Condition. However Filter expression can only contain non-primary key attributes. Thus the query you want to achieve is NOT possible with primary keys. Something like this

var params = {
    TableName: 'apps',
    ...
    FilterExpression: "#id IN (:one,:two)",: 
...

Is only possible with non-primary key attributes

The workaround you can apply is using the batch get item Therefore instead of issuing one query issue multiples in one call and each condition shall contain a value from your ids array.

When it comes to batch get items be aware of the read capacity units (batch get item in node.js).

like image 44
gkatzioura Avatar answered Oct 06 '22 22:10

gkatzioura