Amazon dynamodb 使用哈希键更新Dynamoose模型

Amazon dynamodb 使用哈希键更新Dynamoose模型,amazon-dynamodb,dynamoose,Amazon Dynamodb,Dynamoose,我正在尝试对dynamoose模型执行更新。这是打电话的文件 Model.update(键[,updateObj[,设置],[callback]) key可以是表示hashKey的字符串,也可以是包含hashKey和rangeKey的对象 我的模式同时具有哈希键(分区键)和范围键(排序键),如下所示: //创建模型 let model=dynamoose.model( “样本状态”, { 身份证:{ 类型:字符串, 哈什基:没错, }, 日期:{ 类型:日期, 兰奇:没错, }, 状态:字符串

我正在尝试对dynamoose模型执行更新。这是打电话的文件

Model.update(键[,updateObj[,设置],[callback])
key
可以是表示hashKey的字符串,也可以是包含hashKey和rangeKey的对象

我的模式同时具有哈希键(分区键)和范围键(排序键),如下所示:

//创建模型
let model=dynamoose.model(
“样本状态”,
{
身份证:{
类型:字符串,
哈什基:没错,
},
日期:{
类型:日期,
兰奇:没错,
},
状态:字符串,
});
我创建了这样一个对象(带有固定的演示时间戳)

我希望能够通过引用
id
属性更新
status
属性,如下所示:

model.update({id:“1”},{status:“completed”})
//错误:提供的键元素与架构不匹配
model.update(“1”,{status:“completed”})
//错误:“字符串”类型的参数不能分配给“ObjectType”类型的参数
但两者都会导致显示的错误:

如果我知道时间戳,我可以传入完整的复合密钥,因此以下操作将起作用:

let timestamp=1606781220842;//日期:现在()
更新({id:“1”,日期:timestamp},{status:“completed”});
但是,这需要我保持时间戳,并与id一起保持

在我的例子中,ID字段本身应该是唯一的,因此我不需要两者都创建一个键,而是希望将日期添加为一个范围键,以便对其进行排序。我应该更新我的模式,这样只有一个散列键吗?我在想说“`key可以是表示hashkey的字符串”的文档会让我只传入ID,但这会在编译时抛出一个错误(在typescript中)


有什么建议吗?

这里的解决方案是从
date
属性中删除rangeKey

这是因为在DynamoDB中,每个文档/项目都必须具有唯一的“密钥”。这可以是hashKey或hashKey+rangeKey

既然您提到您的
id
属性是唯一的,那么您可能只想使用hashKey作为键,这应该可以解决这个问题

在您的示例中,可能有许多具有该id的文档,因此DynamoDB不知道要更新哪个


不要忘记,这会导致表发生更改,因此您可能需要删除并重新创建表。但这应该可以解决您遇到的问题。

从逻辑上讲,没有什么比在同一分区中插入多个条目(在您的情况下是唯一id)更能阻止您。如果有不同的日期,可以插入多个具有相同id的项目


因此,如果只想通过分区键(实际上是唯一ID)获取项目,则需要使用查询来检索项目(与get相反),但返回签名将是项目的集合。正如您所知,分区中只有一个项目,您可以选择第一个项目,并指定限制为1以保存RCU。

为什么需要日期作为rangeKey?嘿,Charlie,我可能可以删除它。它可能只是从其他地方复制意大利面。没有一个强大的用例。如果你有时间,帮我一个忙,在Dynamoose GitHub repo上创建一个问题,以改进围绕这个问题的错误消息。给出你的示例代码,甚至是这篇文章的链接。想在这里获得更详细的错误信息吗?谢谢@Charlie-感谢您的库和支持这只是因为有一个
hashKey
rangeKey
。因为OP提到
id
是唯一的,所以您可以删除
rangeKey
,它就可以工作了。如果出于任何原因OP需要保留
范围键
,则此答案完全正确。然而,我想不出一个用例来解释为什么这是必要的。
hashKey
rangeKey
的基本用途实际上要求只使用
hashKey
,因为它是唯一的。因此,在这里删除
rangeKey
是更好的解决方案。您是对的,但是可能有一个遗留表架构,无论出于何种原因,您都无法更改。也可能有其他LSI和GSI使用该排序键。
let timestamp = 1606781220842; // Date.Now()
model.create({
  id: "1",
  date: new Date(timestamp),
  status: "pending",
});