1

Consider the following document item / syntax in a DynamoDB table:

{
    "id": "0f00b15e-83ee-4340-99ea-6cb890830d96",
    "name": "region-1",
    "controllers": [
        {
            "id": "93014cf0-bb05-4fbb-9466-d56ff51b1d22",
            "routes": [
                {
                    "direction": "N",
                    "cars": 0,
                    "sensors": [
                        {
                            "id": "e82c45a3-d356-41e4-977e-f7ec947aad46",
                            "light": true,
                        },
                        {
                            "id": "78a6883e-1ced-4727-9c94-2154e0eb6139",
                        }
                    ]
                }
            ]
        }
    ]
}

My goal is to update a single attribute in this JSON representation, in this case cars.

My approach

I know all the sensors IDs. So, the easiest way to reach that attribute is to find, in the array, the route which has a sensor with any of the ids. Having found that sensor, Dynamo should know which object in the routes array he has to update. However, I cannot run this code without my condition being rejected.

In this case, update attribute cars, where the route has a sensor with id e82c45a3-d356-41e4-977e-f7ec947aad46 or 78a6883e-1ced-4727-9c94-2154e0eb6139.

var params = {
    TableName: table,
    Key:{
        "id": "0f00b15e-83ee-4340-99ea-6cb890830d96",
        "name": "region-1"
    },
    UpdateExpression: "set controllers.intersections.routes.cars = :c",
    ConditionExpression: ""controllers.intersections.routes.sensors.id = :s",
    ExpressionAttributeValues:{
    ":c": 1,
    ":s": "e82c45a3-d356-41e4-977e-f7ec947aad46"
    },
    ReturnValues:"UPDATED_NEW"
};

docClient.update(params, ...); 

How can I achieve this?

Pedro Lourenço
  • 605
  • 7
  • 16
  • Possible duplicate of [DynamoDB update inside an array of objects (nodejs)](https://stackoverflow.com/questions/45784042/dynamodb-update-inside-an-array-of-objects-nodejs) – Adil May 24 '18 at 09:45

2 Answers2

6

Unfortunately, you can't achieve this in DynamoDB without knowing the array index. You have very complex nested structure. The DynamoDB API doesn't have a feature to handle this scenario.

I think you need the array index for controllers, routes and sensors to get the update to work.

Your approach may work in other databases like MongoDB. However, it wouldn't work on DynamoDB. Generally, it is not recommended to have this complex structure in DynamoDB especially if your use case has update scenario.

notionquest
  • 37,595
  • 6
  • 111
  • 105
3
TableName : 'tablename',
Key : { id: id},
ReturnValues : 'ALL_NEW',
UpdateExpression : 'set someitem['+`index`+'].somevalue = :reply_content', 
ExpressionAttributeValues : { ':reply_content' : updateddata }

For updating nested array element need to fing out array index . Then you can update nested array element in dynamo db.

  • I'd also suggest to add a condition expression to avoid race conditions – Jan Gassen Aug 04 '20 at 11:43
  • I have used something like this ```'set someitem['+`index`+'].somevalue = :reply_content',``` and I get the error ```"Invalid UpdateExpression: Syntax error; token: \"'\", near: \"['+\""``` Any help Thanks – Aravind Reddy Jul 25 '21 at 07:54
  • Working case ```'set someitem['+index+'].somevalue = :reply_content' ``` – Aravind Reddy Jul 25 '21 at 08:04