How do I batch delete with DynamoDB?

Here is the batch write delete request sample. This code has been tested and working fine. If you change this code for your requirement, it should work.

Table Definition:-

Bag - Table Name

bag - Hash Key

No partition key in 'Bag' table

Batch Write Code:-

var AWS = require("aws-sdk");

AWS.config.update({
    region : "us-west-2",
    endpoint : "http://localhost:8000"
});

var documentclient = new AWS.DynamoDB.DocumentClient();

var itemsArray = [];

var item1 = {
    DeleteRequest : {
        Key : {
            'bag' : 'b1'    
        }
    }
};

itemsArray.push(item1);

var item2 = {
    DeleteRequest : {
        Key : {
            'bag' : 'b2'    
        }
    }
};

itemsArray.push(item2);

var params = {
    RequestItems : {
        'Bag' : itemsArray
    }
};
documentclient.batchWrite(params, function(err, data) {
    if (err) {
        console.log('Batch delete unsuccessful ...');
        console.log(err, err.stack); // an error occurred
    } else {
        console.log('Batch delete successful ...');
        console.log(data); // successful response
    }

});

Output:-

Batch delete successful ...
{ UnprocessedItems: {} }

This is doable with Node lambda, but there are a few things you need to consider to address concurrency while processing large databases:

  • Handle paging while querying all of the matching elements from a secondary index
  • Split into chunks of 25 requests as per BatchWrite/Delete requirements https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html
  • Above 40,000 matches you might need a 1 second delay between cycles https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Limits.html

Here a snipped that I wrote:

const AWS = require("aws-sdk");
const dynamodb = new AWS.DynamoDB.DocumentClient();
const log = console.log;

exports.handler = async (event) => {

  log(event);
  let TableName = event.tableName;
  let params = {
  let TableName,
        FilterExpression: "userId = :uid",
        ExpressionAttributeValues: {
          ":uid": event.userId,
        },
      };
  let getItems = async (lastKey, items) => {
        if (lastKey) params.ExclusiveStartKey = lastKey;
        let resp = await dynamodb.scan(params).promise();
        let items = resp.Items.length
               ? items.concat(resp.Items.map((x) => x.id))
               : items;
        if (resp.LastEvaluatedKey)
          return await getItems(resp.LastEvaluatedKey, items);
        else return items;
      };
  let ids = await getItems(null, []);
  let idGroups = [];

  for (let i = 0; i < ids.length; i += 25) {
    idGroups.push(ids.slice(i, i + 25));
  }

  for (const gs of idGroups) {
    let delReqs = [];
    for (let id of gs) {
      delReqs.push({ DeleteRequest: { Key: { id } } });
    }
    let RequestItems = {};
    RequestItems[TableName] = delReqs;
    let d = await dynamodb
      .batchWrite({ RequestItems })
      .promise().catch((e) => log(e));
  }
  log(ids.length + " items processed");
  return {};
};