2

I have done a lot of research and the topic does not have enough source for juniors like me. Everything I could find was case specific that was making it impossible to understand. Therefore for myself and for the people who will read this in the future I will not make my question too case specific.

I have created a table record on DynamoDB with the following lambda function:

const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB({region: 'us-east-2', apiVersion: '2012-08-10'})

exports.handler = (event, context, callback) => {
    console.log(event)

    const params = {
        Item: {
            "UserId": {
                S: "global" 
            },
            "search": {
                        SS: [
                             "" + event.hashtag
                            ]
            }
        },
        TableName: "crypto-app"
    };
    dynamodb.putItem(params, function(err, data) {
        if (err) {
            callback(err)
        } else {
            callback(null, data)
        }
    });
};

this is creating a simple string set

 {
  "search": {
    "SS": [
      "london"
    ]
  },
  "UserId": {
    "S": "global"
  }
}

how can I add more strings to my string set with a lambda function to make it like this?

{
  "search": {
    "SS": [
      "london", "tokyo", "moskow" 
    ]
  },
  "UserId": {
    "S": "global"
  }
}
1
  • Thank you so much Walter, of course I will do :) Commented Feb 7, 2019 at 22:05

1 Answer 1

2

You can update the item and add additional string set values.

Here's how you would do it if you had named the attribute xxx rather than search, which is a reserved word.

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

const params = {
  Key: {
    UserId: {
      S: 'global',
    },
  },
  UpdateExpression: 'ADD xxx :avals',
  ExpressionAttributeValues: {
    ':avals': {
      SS: ['tokyo', 'moskow'],
    },
  },
  TableName: 'crypto-app',
};

dynamodb.updateItem(params, (err, data) => {
  if (err) {
    console.log(err);
  } else {
    console.log(data);
  }
});

However, because you named the attribute search, which is reserved, you need to essentially escape that reserved name using an expression attribute name, which is a placeholder that you use in an expression, as an alternative to an actual attribute name.

Here's an example of how you do that:

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

const params = {
  Key: {
    UserId: {
      S: 'global',
    },
  },
  UpdateExpression: 'ADD #a :avals',
  ExpressionAttributeValues: {
    ':avals': {
      SS: ['tokyo', 'moskow'],
    },
  },
  ExpressionAttributeNames: {
    '#a': 'search',
  },
  TableName: 'crypto-app',
};

dynamodb.updateItem(paramse, (err, data) => {
  if (err) {
    console.log(err);
  } else {
    console.log(data);
  }
});

Another, probably better, way to do this is to use the DynamoDB DocumentClient. It's a higher level client interface and it simplifies working with items by abstracting away the notion of attribute values, and instead using native JavaScript types.

With the DocumentClient, rather than explicitly writing UserId: { 'S': 'global' }, you can simply use UserId: 'global' and the string type ('S') will be inferred.

Here's an example of the item update using DocumentClient:

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

const params = {
  Key: {
    UserId: 'global',
  },
  UpdateExpression: 'ADD #a :avals',
  ExpressionAttributeValues: {
    ':avals': dc.createSet(['tokyo', 'moskow']),
  },
  ExpressionAttributeNames: {
    '#a': 'search',
  },
  TableName: 'crypto-app',
};

dc.update(params, (err, data) => {
  if (err) {
    console.log(err);
  } else {
    console.log(data);
  }
});
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot, I have been found a similar solution before you have replied but this one works better and perfect. Thank you so much

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.