简体   繁体   English

从 DynamoDB 中的嵌套数组中删除 object - AWS JavaScript SDK

[英]Deleting an object from a nested array in DynamoDB - AWS JavaScript SDK

I'm building an app where I need to delete items stored in the database.我正在构建一个需要删除存储在数据库中的项目的应用程序。 Here's a (shortened) example of user data I have in my DynamoDB table called 'registeredUsers':这是我的 DynamoDB 表中名为“registeredUsers”的用户数据的(缩短的)示例:

{
  "userId": "f3a0f858-57b4-4420-81fa-1f0acdec979d"
  "aboutMe": "My name is Mary, and I just love jigsaw puzzles! My favourite jigsaw category is Architecture, but I also like ones with plants in them.",
  "age": 27,
  "email": "mary_smith@gmail.com",
  "favourites": {
    "imageLibrary": [
      {
        "id": "71ff8060-fcf2-4523-98e5-f48127d7d88b",
        "name": "bird.jpg",
        "rating": 5,
        "url": "https://s3.eu-west-2.amazonaws.com/jigsaw-image-library/image-library/images/bird.jpg"
      },
      {
        "id": "fea4fd2a-851b-411f-8dc2-1ae0e144188a",
        "name": "porsche.jpg",
        "rating": 3,
        "url": "https://s3.eu-west-2.amazonaws.com/jigsaw-image-library/image-library/images/porsche.jpg"
      },
      {
        "id": "328b913f-b364-47df-929d-925676156e97",
        "name": "rose.jpg",
        "rating": 0,
        "url": "https://s3.eu-west-2.amazonaws.com/jigsaw-image-library/image-library/images/rose.jpg"
      }
    ]
  }
}

I want to be able to delete the item 'rose.jpg' in the user.favourites.imageLibrary array.我希望能够删除user.favourites.imageLibrary数组中的项目“rose.jpg”。 In order to select the correct user, I can provide the userId as the primary key.为了 select 正确的用户,我可以提供 userId 作为主键。 Then, in order to select the correct image in the array, I can pass the AWS.DocumentClient the 'id' of the item in order to delete it.然后,为了 select 数组中的正确图像,我可以将项目的“id”传递给AWS.DocumentClient以将其删除。 However, I'm having trouble understanding the AWS API Reference docs.但是,我无法理解 AWS API 参考文档。 The examples given in the developer guide do not describe how to delete an item by looking at one of it's attributes.开发人员指南中给出的示例没有描述如何通过查看项目的属性来删除项目。 I know I have to provide an UpdateExpression and an ExpressionAttributeValues object.我知道我必须提供一个UpdateExpression和一个ExpressionAttributeValues object。 When I wanted to change a user setting, I found it pretty easy to do:当我想更改用户设置时,我发现很容易做到:

const params = {
    TableName: REGISTERED_USERS_TABLE,
    Key: { userId },
    UpdateExpression: "set userPreferences.difficulty.showGridOverlay = :d",
    ExpressionAttributeValues: {
      ":d": !showGridOverlay
    },
    ReturnValues: "UPDATED_NEW"
  };

To conclude, I need a suitable Key, UpdateExpression and ExpressionAttributeValues object to access the rose.jpg item in the favourites array.最后,我需要一个合适的 Key、UpdateExpression 和 ExpressionAttributeValues object 来访问收藏夹数组中的rose.jpg 项。

Unfortunately, the UpdateExpression syntax is not as powerful as you would have liked.不幸的是, UpdateExpression语法没有您希望的那么强大。 It supports entire nested documents inside the item, but not sophisticated expressions to search in them or to modify them.它支持项目内的整个嵌套文档,但不支持在其中搜索或修改它们的复杂表达式。 The only ability it gives you inside a list is to access or modify its Nth element.它在列表中为您提供的唯一功能是访问或修改其第 N 个元素。 For example:例如:

REMOVE #favorites.#imagelibrary[3]

Will remove the 3rd element of imagelibrary (note that the " #imagelibrary " will need to be defined in ExpressionAttributeNames ), and you can also have a condition on #favorites.#imagelibrary[3].#id , for example, in ConditionExpression .将删除 imagelibrary 的第三个元素(请注意,“ #imagelibrary ”需要在ExpressionAttributeNames中定义),您还可以在#favorites.#imagelibrary[3].#id上设置条件,例如,在ConditionExpression中。 But unfortunately, there is no way to specify more complex combinations of conditions and updates, such as "find me the i where #favorites.#imagelibrary[i].#id is equal something, and then REMOVE this specific element".但不幸的是,没有办法指定更复杂的条件和更新组合,例如“找到我的 i where #favorites.#imagelibrary[i].#id is equal something,然后删除这个特定元素”。

Your remaining option is to read the full value of the item (or with ProjectionExpression just the #favorties.#imagelibrary array), and then in your own code find which of the elements you want to remove (eg, discover that it is the 3rd element), and then in a separate update, remove the 3rd element.您剩下的选择是读取项目的完整值(或使用ProjectionExpression#favorties.#imagelibrary数组),然后在您自己的代码中找到要删除的元素(例如,发现它是第 3 个element),然后在单独的更新中删除第三个元素。

Note that if there's a possibility that some other parallel operation also changes the item, you must use a conditional update (both UpdateExpression and ConditionExpression ) for the element removal, to ensure the element that you are removing still has the id you expected.请注意,如果某些其他并行操作也可能更改项目,则必须使用条件更新( UpdateExpressionConditionExpression )来删除元素,以确保要删除的元素仍然具有您期望的 id。 If the condition fails, you need to repeat the whole operation again - read the modified item again, find the element again, and try to remove it again.如果条件失败,则需要再次重复整个操作——再次读取修改过的项目,再次找到该元素,然后再次尝试将其移除。 This is an example of the so-called "optimistic locking" technique which is often used with DynamoDB.这是通常与 DynamoDB 一起使用的所谓“乐观锁定”技术的一个示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM