Home > Software design >  How to compare strings in DynamoDB using Lambda NodeJS?
How to compare strings in DynamoDB using Lambda NodeJS?

Time:12-31

I have a lambda function that make some requests on DynamoDB.

    var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
    const lookupminutes = 10;
    var LookupDate = new Date(Date.now() - 1000 * lookupminutes);

    params = {
        TableName: TableName,
        IndexName: "requestdate-index",
        KeyConditionExpression: "requestdate > :startdate",
        ExpressionAttributeValues: {":startdate": {S: LookupDate.toISOString()}
                                   },
        ProjectionExpression: "id, requestdate"
    };

    var results = await ddb.query(params).promise();

When running the lambda function, I'm getting the error : "Query key condition not supported" in the line that runs the query against DynamoDB

The field requestdate is stored in the table as a string.

Does anyone know what am I doing wrong please ?

Thanks.

CodePudding user response:

You cannot use anything other than an equals operator on a partition key:

    params = {
        TableName: TableName,
        IndexName: "requestdate-index",
        KeyConditionExpression: "requestdate = :startdate",
        ExpressionAttributeValues: {":startdate": {S: LookupDate.toISOString()}},
        ProjectionExpression: "id, requestdate"
    };

If you need all of the data back within the last 10 mins then they you have two choices, both of which are not very scalable, unless you shard your key (1a):

  1. Put all the data in your index under the same partition key with sort key being timestamp. Then use KeyConditionExpression like: gsipk=1 AND timestamp> 10mins

As all of the items are under the same partition key, the query will be efficient but at the cost of scalability as you will essentially bottleneck your throughput to 1000WCU.

1a. And probably the best option if you need scale beyond 1000 WCU is to do just as above except use a random number for the partition key (within a range). For example range = 0-9. That would give us 10 unique partition keys allowing us to scale to 10k WCU, however would require us to request 10 Query in parallel to retrieve the data.

  1. Use a Scan with FilterExpression on the base table. If you do not want to place everything under the same key on the GSI then you can just Scan and add a filter. This becomes slow and expensive as the table grows.
  • Related