updating a JSON array in AWS dynamoDB
Asked Answered
S

3

8

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 ?

Synthiasyntonic answered 29/10, 2016 at 8:44 Comment(2)
Have you saved the data as JSON in DynamoDB using JsonMarshaller? If yes, the API doesn't have option to update the JSON data.Gala
@Gala I have updated my question with how I inserted Json in to the array. Would like to know your thoughts!!!Synthiasyntonic
S
1

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.

Synthiasyntonic answered 11/11, 2016 at 3:35 Comment(1)
Could you please post the sample query to update nested json?How to update "attendees.2016102973634-df" json? and How to update "attendees.2016102973634-df.attendeeName" ?Demission
P
2

you can store the index of list. while updating the list we can use them. For example ,

{


"data": {
      "eventId": "20161029125458-df-d",
      "name": "first",
      "purpose": "test",
      "location": "yokohama",
      "dateArray": [],
      "attendees": [
        {  
          "index":0,  
          "attendeeId": "2016102973634-df",
          "attendeeName": "lakshman",
          "personalizedDateSelection": {}
        },
        {
           "index":1,
          "attendeeId": "2016102973634-tyyu",
          "attendeeName": "diwaakar",
          "personalizedDateSelection": {}
        }
      ]
    }
}
const params = {
  TableName: "event",
  Key: {
    "eventId": eventId 
  },
  UpdateExpression: "SET attendees[attendee.index].attendeeName = :value",
  ExpressionAttributeValues: {
    ":value" : {"S":"karthik"}
  },
  ReturnValues: "ALL_NEW"
};


dynamo.update(params, (err, data) => {
  if (err) {
    return reject(err);
  }
  console.log(data.Attributes);
});
Promisee answered 28/5, 2018 at 18:52 Comment(2)
Where did you take attendee.index from? This "attendee" doesn't seem to be part of the schema. If it was supposed to be a variable, shouldn't it be outside quotes?Distended
there is index is any default atrr I don't found about it in doc like index can we use other attributes like attendeeIdPeep
V
2

An example of an update query:

Data structure (saved in DynamoDB)

{
  tenant_id: 'tenant_1',
  users: {
    user1: {
      _id: 'user1',
      email_address: '[email protected]'
    },
    user2: {
      _id: 'user2',
      email_address: '[email protected]'
    }
  }
}

Data for update (used in the params)

var user = {
 email_address: '[email protected]'
}

Params

var params = {
    TableName: 'tenant-Master',
    Key: {
       "tenant_id": 'tenant_1'
    },
    UpdateExpression: "set #users.user1 = :value",
    ExpressionAttributeNames: {
    "#users": "users"
    },
    ExpressionAttributeValues: {
    ":value": user,
    },
 };

Explanation

By switching to a map of maps from an array of maps we can now use UpdateExpression: "set #users.user1 = :value" to update our nested object at the map of users with the id of user1.

NOTE: This method as is will REPLACE the entire map object at users.user1. Some changes will need to be made if you want to keep pre-existing data.

Volleyball answered 24/5, 2019 at 14:34 Comment(1)
If all you need is ".user1" property (using "#user.user1 = :value") to change the object content, why do you also have the property _id?Distended
S
1

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.

Synthiasyntonic answered 11/11, 2016 at 3:35 Comment(1)
Could you please post the sample query to update nested json?How to update "attendees.2016102973634-df" json? and How to update "attendees.2016102973634-df.attendeeName" ?Demission

© 2022 - 2024 — McMap. All rights reserved.