Stéphane GRILLON
Stéphane GRILLON

Reputation: 11864

read filtered data in AWS dynamoDB with AWS NodeJS Lambda

I want get element from DynamoDB to my NodeJS AWS Lambda. I want selected by "owner" column but do not work. I try same syntax for the "id" column and the result is OK. do I add an index in dynamoDB? where?

'use strict';

var AWS = require('aws-sdk');
var documentClient = new AWS.DynamoDB.DocumentClient({'region': 'eu-west-1'}); 

exports.handler = function(event, context, callback) {
  
  console.log(JSON.stringify(event));

  const claims = event.requestContext.authorizer.claims;
  const username = claims['cognito:username'];
  
  var params = {
    TableName : "tp-exam",
      Key: {
        owner: username 
      }
  };
  
    documentClient.get(params, function(err, data){
      if (err) {
      console.log("Error", err);
      const errResponse = {
        statusCode: 500,
        headers: {
          "Access-Control-Allow-Origin": "*"
        },
        body: JSON.stringify({ Error: 500, device : "DynamoDB"})
      };
      callback(null, errResponse);
    } else {
      console.log("Success", data.Item);
      const response = {
        statusCode: 200,
        headers: {
          "Access-Control-Allow-Origin": "*"
        },
        body: JSON.stringify(data.Item)
      };
        callback(null, response);
    }
        
    });

};

my error is:

ValidationException: The provided key element does not match the schema
    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:688: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:690:12)
    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18) {
  code: 'ValidationException',
  time: 2021-03-01T21:46:40.263Z,
  requestId: 'C7UHG8354A92SGP2T4FRRFU4GFVV4KQNSO5AEMVJF66Q9ASUAAJG',
  statusCode: 400,
  retryable: false,
  retryDelay: 32.73628085995177
}

Upvotes: 1

Views: 330

Answers (2)

Seth Geoghegan
Seth Geoghegan

Reputation: 5747

This error is saying that you are not providing the correct primary key to the DynamoDb#get operation.

A couple of tips:

  • Make sure you're providing the correct name of your partition key. Are you sure your partition key attribute is named owner?
  • Make sure you are providing the entire primary key. Primary keys in DynamoDB come in two forms, simple and composite. A simple primary key is made up of a partition key only. A composite primary key is made up of a partition key and a sort key. Your error suggests that you might have a composite primary but aren't specifying the sort key portion of the primary key.

If neither of those issues resolves your problem, post the details of your DynamoDB table so we can see how your keys are defined.

Alternatively, if the owner attribute is not part of your primary key and you'd like to search by that field, you have a few options.

  1. Create a new GSI using owner as the primary key or
  2. You can use the scan operation to search by a non-key attribute.

Note that the first option (creating a GSI) is the preferred method.

Upvotes: 0

Balu Vyamajala
Balu Vyamajala

Reputation: 10333

We need a Global Secondary Index to get or query on an alternate key.

enter image description here

and to query using GSI, we need to use query api.

let docClient = new AWS.DynamoDB.DocumentClient();

documentClient.query(
  {
    TableName: "tp-exam",
    IndexName: "owner-index",
    KeyConditionExpression: "#owner_attr = :ownerVal",
    ExpressionAttributeValues: {
      ":ownerVal": "John",
    },
    ExpressionAttributeNames: {
      "#owner_attr": "owner",
    },
  },
  function (err, data) {
    console.log("err", err, "data", data);
  }
);

owner is a reserved keyword, so, we need to use ExpressAttributeNames to replace with actual attribute.

Upvotes: 1

Related Questions