5

I have this Schema:

{
   product: S // Primary Key, // my Hash
   media: L // List of Maps
}

Each media item will be like this:

[
   { 
      id: S, // for example: id: uuid()
      type: S, // for example: "image"
      url: S // for example: id: "http://domain.com/image.jpg"
   }
]

Sample Data:

{
    product: "IPhone 6+",
    media: [
        {
            id: "1",
            type: "image",
            url: "http://www.apple.com/iphone-6-plus/a.jpg"
        },
        {
            id: "2",
            type: "image",
            url: "http://www.apple.com/iphone-6-plus/b.jpg"
        },
        {
            id: "3",
            type: "video",
            url: "http://www.apple.com/iphone-6-plus/overview.mp4"
        }
    ]
}

I want to be able to remove from media list by id. Something like: "From product: 'IPhone 6+', remove the media with id: '2'"

After the query, the Data should be like this:

{
    product: "IPhone 6+",
    media: [
        {
            id: "1",
            type: "image",
            url: "http://www.apple.com/iphone-6-plus/a.jpg"
        },
        {
            id: "3",
            type: "video",
            url: "http://www.apple.com/iphone-6-plus/overview.mp4"
        }
    ]
}

How should i express query like this? I saw a post on UpdateItem but i can't find a good example for this query type.

Thanks!

Momos Morbias
  • 535
  • 1
  • 5
  • 13
  • Could you please provide sample data? It is very clear what media contains and how it looks. – notionquest Aug 19 '16 at 10:15
  • Sure, update attached... – Momos Morbias Aug 19 '16 at 11:16
  • Does this answer your question? [How do I delete from DynamoDB List of Maps, by Map attribute value in said List?](https://stackoverflow.com/questions/34051638/how-do-i-delete-from-dynamodb-list-of-maps-by-map-attribute-value-in-said-list) – Malvineous Jan 18 '23 at 11:14

1 Answers1

5

Unfortunately, the API doesn't have this feature. The closest you can do is to delete an entry from "List" data type if you know the index.

I understand that most of the time the index mayn't be available. However, you can take a look at this alternate option if you don't have any other solution.

You also need to understand that even though DynamoDB started supporting the Document data types such as List, Map and Set, you can't perform some actions. Some features are yet to be added in the API. I believe this scenario is one of them.

I have used REMOVE to delete the item from list.

var params = {
        TableName : "Product",
        Key : {
            "product" : "IPhone 6+"
        },
        UpdateExpression : "REMOVE media[0]",       
        ReturnValues : "UPDATED_NEW"
    };

console.log("Updating the item...");
docClient.update(params, function(err, data) {
    if (err) {
        console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("UpdateItem succeeded:", JSON.stringify(data));
    }
});

This is just for your reference:-

The Delete operator can be used only on SET.

DELETE - Deletes an element from a set.

If a set of values is specified, then those values are subtracted from the old set. For example, if the attribute value was the set [a,b,c] and the DELETE action specifies [a,c], then the final attribute value is [b]. Specifying an empty set is an error.

The DELETE action only supports set data types. In addition, DELETE can only be used on top-level attributes, not nested attributes.

notionquest
  • 37,595
  • 6
  • 111
  • 105
  • Another way I can think of is you lookup again in the dynamodb list where attribute id = id params, then return that index. But I don't know how to write this in Lambda. – AllenC Dec 13 '18 at 10:17
  • 1
    I'd recommend to put a ConditionExpression:media[0].id="1" just to make sure that there isn't someone else changing data at the same time... – Fabio Ferrari Mar 26 '19 at 13:27