1

I'm trying to write a Lambda function to remove an object from a list in DynamoDB. In this case I am passing in "author": "J.K. Rowling", "title": "Harry Potter", and "userid": "041c9004" as parameters. I want to delete the matching object from the books list. What is the correct syntax for the UpdateExpression statement? There may be some other errors within params{} as well.

The DynamoDB table looks like this. userid is the primary key:

{
  "books": [
    {
      "author": "J.R.R. Tolkien",
      "title": "Lord of the Rings"
    },
    {
      "author": "J.K Rowling",
      "title": "Harry Potter"
    },
    {
      "author": "George RR Martin",
      "title": "A Song of Ice and Fire"
    }
  ],
  "isactive": true,
  "ispublic": true,
  "lastupdated": 1597690265,
  "userid": "041c9004"
}

Here is the Lambda function:

const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region: 'us-east-1'});

exports.handler = function(event, context, callback){

    let params =  {
        ExpressionAttributeValues: {
            ":attrValue": [{ 
                "author": event.author,
                "title": event.title
            }]
        },
        ExpressionAttributeNames : {
            "#books" : "books"
        },
        Key: {
            userid: event.userid
        },
        TableName: 'Users',
        UpdateExpression: "REMOVE #books[:attrValue]", //this is incorrect
        ReturnValues:"ALL_NEW",
    };
 
    docClient.update(params, function(err,data){
        if(err) {
            callback(err, null)
        }else{
            callback(null, data)
        }
    });
}

2 Answers 2

2

In case anyone is wondering, here is the full solution:

const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({region: 'us-east-1'});

exports.handler = function(event, context, callback){

    var params = {
        TableName: 'Users',
        Key: {
            userid: event.userid
        }
    };

    docClient.get(params, function(err, data){
        if(err) {
            callback(err,null);
        } else {
            var indexOfAuthor = data.Item.books.findIndex(i => i.author === event.author);
            console.log('The index of the author is ' + indexOfAuthor);
            var updateExpressionString = "REMOVE #books[" + indexOfAuthor + "]"
            
            let paramsdelete =  {
                ExpressionAttributeNames : {
                    "#books" : "books"
                },
                Key: {
                    userid: event.userid
                },
                TableName: 'Users',
                UpdateExpression: updateExpressionString,
                ReturnValues:"ALL_NEW",
            };
    
            docClient.update(paramsdelete, function(err,data){
                if(err) {
                    callback(err, null);
                }else{
                    callback(null, data);
                }
            });
            
        }
    });
};
Sign up to request clarification or add additional context in comments.

Comments

1

This is a great question!

Unfortunately, the UpdateExpression will only allow you to REMOVE from the list if you specify an index (docs here).

You'll need to read the item from the DB, find the indexes you want to remove, and REMOVE that specific index.

1 Comment

Thanks! I was hoping it was possible without finding the index first, but that approach will work well

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.