我在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,
},
},
},
},
}
型
有没有其他人遇到过这种情况,如果有,你是如何克服的?
2条答案
按热度按时间vxbzzdmp1#
正如你所指出的,要更新列表中的一个项目,你必须首先知道列表项目的位置。在大多数情况下,使用Map更有利,因为你也正确地指出。
你的问题是,你不能再Map客户端代码中的对象,但你可以简单地使用以下代码将Map转换为数组:
编辑:
选项1:
字符串
选项2:
型
w1e3prcc2#
您可以考虑将数据分解到表中的单独条目中。每个订单一个条目,订单中的每个项目一个条目。您可以使用查询来获取订单及其所有项目。要实现这一点,您需要有一个分区键和排序键模式,允许您在同一个表中存储不同的对象。您通常在这里将其称为单表模式。
表中通常有分区和排序键,它们都有通用名称(
PK
和SK
)。数据看起来像这样(每个对象在表中是一个单独的条目):字符串
您会注意到每条记录都有相同的
PK
(用户ID)和SK
以ORDER#<OrderId>
开头。项目记录也包括#ITEM#<ItemId>
。这允许您通过执行 get 操作来检索没有项目的订单(PK = UserId和SK =ORDER#<OrderId>
),或者您可以使用 query 来检索包含项目的订单(PK = UserId and begins_with(SK,ORDER#<OrderId>
).查询将返回订单以及每个项目。然后您可以将它们放在一起形成上面的对象。通过采用这种方法,您可以非常轻松地更新订单上的单个项目,因为每个订单项目在表中都是自己的条目。
您可能会发现您需要以不同的方式访问数据,这就是GSI的用武之地。对于您给出的有限示例,这应该可以工作,或者接近您的需要。