Home > Software engineering >  How to query DynamoDB table from Lambda NodeJS?
How to query DynamoDB table from Lambda NodeJS?

Time:01-07

I have a table in DynamoDB with a GSI (filteredurl-dateinseconds-index) with a partition key (filteredurl) and a sort key (dateinseconds)

enter image description here

I use AWS console to query some results from the table using the index (filteredurl-dateinseconds-index). Basically I need the items with a certain value of the partition (filteredurl) key and a sort key (dateinseconds) greater than 1.

The query works properly on the console and I'm trying to do the samething from Lambda NodeJs

              params = {
                    TableName: TableName,
                    IndexName: "filteredurl-dateinseconds-index",
                    KeyConditionExpression: "filteredurl = :url and dateinseconds > 1",
                    ExpressionAttributeValues: {":url": {"S": "somevalue"}},
                    ProjectionExpression: "id"
                };

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

When running Lambda function, I'm getting the error : Invalid KeyConditionExpression: Syntax error; token: "1", near: "> 1"

    Response
    {
      "errorType": "ValidationException",
      "errorMessage": "Invalid KeyConditionExpression: Syntax error; token: \"1\", near: \"> 1\"",
      "trace": [
        "ValidationException: Invalid KeyConditionExpression: Syntax error; token: \"1\", near: \"> 1\"",
        "    at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/protocol/json.js:52:27)",
        "    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)",
        "    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)",
        "    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:686:14)",
        "    at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)",
        "    at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)",
        "    at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10",
        "    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)",
        "    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:688:12)",
        "    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)"
      ]
    }

Does anyone know what am I doing wrong please ?

Thanks. Cheers,

enter image description here

CodePudding user response:

As you are using the low-level client you must use the DynamoDB datatype, which means you need to declare that 1 is in fact a number:

":num": {"N": "1"}

Use this:

params = {
    TableName: TableName,
    IndexName: "filteredurl-dateinseconds-index",
    KeyConditionExpression: "filteredurl = :url and dateinseconds > :num",
    ExpressionAttributeValues: {
            ":url": {"S": "somevalue"}
            ":num": {"N": "1"}
        },
    ProjectionExpression: "id"
};

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