arraysjsonamazon-web-servicesamazon-dynamodbdynamo-local

updating a JSON array in AWS dynamoDB


My document looks like this:

{
  "data": {
      "eventId": "20161029125458-df-d",
      "name": "first",
      "purpose": "test",
      "location": "yokohama",
      "dateArray": [],
      "attendees": [
        {
          "attendeeId": "2016102973634-df",
          "attendeeName": "lakshman",
          "personalizedDateSelection": {}
        },
        {
          "attendeeId": "2016102973634-tyyu",
          "attendeeName": "diwaakar",
          "personalizedDateSelection": {}
        }
      ]
    }
}

Say, I need to update the attendee JSON array with attendeeId: 2016102973634-df. I tried many ways ways using update and condition expression, but no success.

Here is my try:

const params = {
  TableName: "event",
  Key: {
    "eventId": eventId 
  },
  UpdateExpression: "SET attendees[???] = ",
  ConditionExpression: attendees.attendeeId = "2016102973634-df", 
  ExpressionAttributeValues: {
    ":attendee" : attendeeList
  },
  ReturnValues: "ALL_NEW"
};


dynamo.update(params, (err, data) => {
  if (err) {
    return reject(err);
  }
  console.log(data.Attributes);
});

Could not find any resources for updating an Json in a array.

After @notionquest's comment: - Have not used any JsonMarshaller. Initially I added the empty array to attendees field like this:

{
  "eventId": "20161029125458-df-d",
  "name": "first",
  "purpose": "test",
  "location": "yokohama",
  "dateArray": [],
  "attendees": []
}

and then When a new attendee comes I add it to the attendees property like this:

const attendee = {
  "attendeeName": "user1",
  "personalizedDateSelection": {"today": "free"}
}
const attendeeList = [attendee];
const eventId = "20161029125458-df-d";


const params = {
  TableName: "event",
  Key: {
    "eventId": eventId
  },
  UpdateExpression: "SET attendees = list_append(attendees, :attendee)",
  ExpressionAttributeValues: {
    ":attendee" : attendeeList
  },
  ReturnValues: "ALL_NEW"
};


dynamo.update(params, (err, data) => {
  if (err) {
    return reject(err);
  }
  console.log("in update dynamo");
  console.log(data.Attributes);
});

As you have seen in the above snippets, initially I add empty [] array and add a new attendee using the above code. Now, How do I update a specific JSON in an array. If you say that is not possible, what else can I try?

Should I try this :

  1. Get the Full JSON.
  2. Manipulate the JSOn and change the things I want in my nodeJS.
  3. And then update the new JSON to dynamoDB.
  4. But this consumes two calls to dynamoDB which seems to be inefficient.

Would like to know If there is any round way ?


Solution

  • I could not find any answer to query and update the JSON-array. I think this may be AWS profitable motive to not allow those features. If you need to query on a particular ID other than primary key, you need to make a secondary index which is cost effective. This secondary index cost is additional to the dyn amoDB table cost.

    Since, I did not want to pay extra bucks on secondary index, I changed my dynamoDB schema to the following:

    {
      "data": {
          "eventId": "20161029125458-df-d",
          "name": "first",
          "purpose": "test",
          "location": "yokohama",
          "dateArray": [],
          "attendees": {
            "2016102973634-df": {
              "attendeeId": "2016102973634-df",
              "attendeeName": "lakshman",
              "personalizedDateSelection": {}
            },
            "2016102973777-df": {
              "attendeeId": "2016102973777-df",
              "attendeeName": "ffff",
              "personalizedDateSelection": {}
            }
          }
        }
    }
    

    Changing attendees from [] to {}. This allows me the flexibility to query particular attendeeId and change the entire JSON associated with that. Even though, this is a redundant step, I do not want to spend extra bucks on my hobby project.