updating a JSON array in AWS dynamoDB

a 夏天 提交于 2019-11-28 09:54:21

问题


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 ?


回答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.




回答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);
});



回答3:


An example of an update query:

Data structure (saved in DynamoDB)

{
  tenant_id: 'tenant_1',
  users: {
    user1: {
      _id: 'user1',
      email_address: 'test_email_1@gmail.com'
    },
    user2: {
      _id: 'user2',
      email_address: 'test_email_2@gmail.com'
    }
  }
}

Data for update (used in the params)

var user = {
 email_address: 'updated@gmail.com'
}

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.



来源:https://stackoverflow.com/questions/40317443/updating-a-json-array-in-aws-dynamodb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!