next.js AWS DynamoDB更新列表中的Map元素

y53ybaqx  于 8个月前  发布在  其他
关注(0)|答案(2)|浏览(91)

我在DynamoDB中有以下表格:

{
    UserId: "123456",
    Orders: [
        {
            OrderId: "ORD123",
            OrderRef: "Christmas presents",
            OrderStatus: 0,
            OrderDeliveryDate: "21/12/2023",
            OrderItems: [
                {
                    ItemId: "ORD123-ITM001",
                    ItemDescription: "Socks",
                    ItemQuantity: 2,
                    ItemDeliveryDate: "21/12/2023",
                    ItemStatus: 0
                },
                {
                    ItemId: "ORD123-ITM002",
                    ItemDescription: "Tie",
                    ItemQuantity: 1,
                    ItemDeliveryDate: "21/12/2023",
                    ItemStatus
                },
            ]
        },
        {
            OrderId: "ORD456",
            OrderRef: "Birthday presents",
            OrderStatus: 0,
            OrderDeliveryDate: "23/12/2023",
            OrderItems: [
                {
                    ItemId: "ORD456-ITM001",
                    ItemDescription: "Cheese",
                    ItemQuantity: 1,
                    ItemDeliveryDate: "23/12/2023",
                    ItemStatus: 0
                },
            ]
        }
    ]
}

字符串
我希望能够将ItemId:“ORD 123-ITM 001”的ItemStatus从0更新为2。我可以使用下表中的索引号来执行此操作:

const input = {
      TableName: tableName,
      Key: {
        UserId: user.userId,
      },
      ExpressionAttributeValues: { ":sts": 2 },
      UpdateExpression: `SET Orders[0].OrderItems[0].ItemStatus= :sts`,
      ReturnValues: "ALL_NEW",
    };
    const command = new UpdateCommand(input);
    const response = await documentClient.send(command);


这可以工作并更新值,但我更喜欢使用ID来更新,而不是使用索引。由于不同的排序选项,我的应用程序中的数据可能会发生变化,因此为了确保我获得正确的索引,我必须首先扫描DB,然后执行更新,我真的不想这样做。有没有一种方法可以编写一个表达式来使用ID而不是索引更新表?
我尝试过的另一种方法是将Orders和OrderItems列表更改为map(见下文),这对点表示法的ID很好用。然而,我遇到的问题是,当我的GetCommand从表中返回数据时,它不适用于我的NextJS应用程序中的.map,因为Orders和OrderItems不再是数组。使用这种方法,有没有办法将Orders和OrderItems转换为数组?

{
  UserId: "123456",
  Orders: {
    ORD123: {
      OrderRef: "Christmas presents",
      OrderStatus: 0,
      OrderDeliveryDate: "21/12/2023",
      OrderItems: {
        ORD123_ITM001: {
          ItemDescription: "Socks",
          ItemQuantity: 2,
          ItemDeliveryDate: "21/12/2023",
          ItemStatus: 0,
        },
        ORD123_ITM002: {
          ItemDescription: "Tie",
          ItemQuantity: 1,
          ItemDeliveryDate: "21/12/2023",
          ItemStatus,
        },
      },
    },
    ORD456: {
      OrderRef: "Birthday presents",
      OrderStatus: 0,
      OrderDeliveryDate: "23/12/2023",
      OrderItems: {
        ORD456_ITM001: {
          ItemDescription: "Cheese",
          ItemQuantity: 1,
          ItemDeliveryDate: "23/12/2023",
          ItemStatus: 0,
        },
      },
    },
  },
}


有没有其他人遇到过这种情况,如果有,你是如何克服的?

vxbzzdmp

vxbzzdmp1#

正如你所指出的,要更新列表中的一个项目,你必须首先知道列表项目的位置。在大多数情况下,使用Map更有利,因为你也正确地指出。
你的问题是,你不能再Map客户端代码中的对象,但你可以简单地使用以下代码将Map转换为数组:
编辑:
选项1:

Object.entries(map.Orders).map(order=> {
    console.log(order)
  })

字符串
选项2:

for (const orderId in map.Orders) {
  const order = map.Orders[orderId];
  console.log(`Order ID: ${orderId}`);
  console.log(`Order Reference: ${order.OrderRef}`);
  console.log(`Order Delivery Date: ${order.OrderDeliveryDate}`);

  // Loop through order items
  for (const itemId in order.OrderItems) {
    const item = order.OrderItems[itemId];
    console.log(`  Item ID: ${itemId}`);
    console.log(`  Item Description: ${item.ItemDescription}`);
    console.log(`  Item Quantity: ${item.ItemQuantity}`);
    console.log(`  Item Delivery Date: ${item.ItemDeliveryDate}`);
    console.log(`  Item Status: ${item.ItemStatus}`);
  }
}

w1e3prcc

w1e3prcc2#

您可以考虑将数据分解到表中的单独条目中。每个订单一个条目,订单中的每个项目一个条目。您可以使用查询来获取订单及其所有项目。要实现这一点,您需要有一个分区键和排序键模式,允许您在同一个表中存储不同的对象。您通常在这里将其称为单表模式。
表中通常有分区和排序键,它们都有通用名称(PKSK)。数据看起来像这样(每个对象在表中是一个单独的条目):

{
    PK: "123456",
    SK: "ORDER#ORD123",
    UserId: "123456",
    OrderId: "ORD123",
    OrderRef: "Christmas presents",
    OrderStatus: 0,
    OrderDeliveryDate: "21/12/2023"
}
{
    PK: "123456",
    SK: "ORDER#ORD123#ITEM#ORD123-ITM001",
    ItemId: "ORD123-ITM001",
    ItemDescription: "Socks",
    ItemQuantity: 2,
    ItemDeliveryDate: "21/12/2023",
    ItemStatus: 0
}
{
    PK: "123456",
    SK: "ORDER#ORD123#ITEM#ORD123-ITM001",
    ItemId: "ORD123-ITM002",
    ItemDescription: "Tie",
    ItemQuantity: 1,
    ItemDeliveryDate: "21/12/2023",
    ItemStatus
}
{
    PK: "123456",
    SK: "ORDER#ORD456",
    UserId: "123456",
    OrderId: "ORD456",
    OrderRef: "Birthday presents",
    OrderStatus: 0,
    OrderDeliveryDate: "23/12/2023"
}
{
    PK: "123456",
    SK: "ORDER#ORD456#ITEM#ORD456-ITM001",
    ItemId: "ORD456-ITM001",
    ItemDescription: "Cheese",
    ItemQuantity: 1,
    ItemDeliveryDate: "23/12/2023",
    ItemStatus: 0
}

字符串
您会注意到每条记录都有相同的PK(用户ID)和SKORDER#<OrderId>开头。项目记录也包括#ITEM#<ItemId>。这允许您通过执行 get 操作来检索没有项目的订单(PK = UserId和SK = ORDER#<OrderId>),或者您可以使用 query 来检索包含项目的订单(PK = UserId and begins_with(SK,ORDER#<OrderId>).查询将返回订单以及每个项目。然后您可以将它们放在一起形成上面的对象。
通过采用这种方法,您可以非常轻松地更新订单上的单个项目,因为每个订单项目在表中都是自己的条目。
您可能会发现您需要以不同的方式访问数据,这就是GSI的用武之地。对于您给出的有限示例,这应该可以工作,或者接近您的需要。

相关问题