0

我有一个dynamodb表,我声明使用dynamoose如下:

const schema = new dynamoose.Schema({
    "email": String,
    "name": String,
    "vehicleMotor": {
        "type": Number,
        "default": 0
    },
    "vehicleMotorId": String,
    "vehicleMotorImage1File": String,
    "vehicleMotorImage2File": String,
}, {
    "saveUnknown": true,
    "timestamps": true
});

据我了解,当我"timestamps": true声明时,它应该同时 createdAt具有和 updatedAt字段。

所以当我运行看起来像这样的代码时

if (new){
    const newSeller = new Seller({
        "email": email,
        "name": name
    })
    var saveResult = await newSeller.save();
}else{
    var updateResult = await Seller.update( { "email": email, sellerType: 1 }, {
        "name": name
    })
}

当我在 Amazon DynamoDB 管理控制台中检查插入/更新的数据时,没有createdAt,只有updatedAt. 按理说我应该也createdAt太对了吧?如果没有,如何确保createdAt永远存在?

4

1 回答 1

1

基于原始海报的评论。看起来这只发生在update通话中。

原始问题中没有足够的信息让我就我认为最好的解决方案给出具体的答案。所以我将做一些假设,并提供很多关于 Dynamoose 如何处理这种情况的高级细节。

只是一点点幕后花絮,这将有助于使我的答案更清楚。从 Dynamoose 的角度来看,它不知道文档/项目是否已经存在于数据库中。这会导致createdAt难以达到 100% 准确的情况。您遇到了其中一种情况。对于update调用,Dynamoose 假定文档已经存在,因此不设置createdAt时间戳。这是有道理的,因为与呼叫createdAt并不真正匹配。update但是,DynamoDB 和 Dynamoose 在技术上允许用于update创建新文档/项目。但是 Dynamoose 无法知道它是哪一个,所以我们使用假设的行为update意味着不为此上下文创建新文档。

至于可能的解决方案。你有一个new变量。我很好奇您是如何定义该变量的。一种选择是使用 get 调用检查表并查看文档是否已经存在。如果你把它作为你的new变量,它应该可以正常工作。因为如果它不存在它会保存,如果它已经存在,它应该已经有了createdAt变量。这样做的主要缺点是您必须始终在写入之前执行读取操作。这增加了应用程序的延迟,并减慢了速度。但它会达到你想要的。

现在。如果您的表中有没有createdAt时间戳的文档(例如,您在 Dynamoose 之外创建它,或者您在添加时间戳选项之前创建它),上述解决方案将不起作用。这是因为即使检查它是否存在,也会导致该update方法运行,而 Dynamoose 认为这是更新而不是创建。在这种情况下,任何解决方案实际上都取决于您的应用程序想要做什么。该项目已经存在于表中,因此无法知道真正 createdAt的时间戳是什么时候(除非您保留日志等)。您可以运行一次性操作来完成并将当前时间戳添加到createdAt如果每个文档都没有它的字段(但这又不是真正准确的)。或者当然你可以忽略它,而不是总是依赖那个领域。

总而言之,Dynamoose 中的时间戳功能是真正的客户端功能。Dynamoose 对数据状态的洞察力有限,而 DynamoDB 不提供内置功能。这意味着 Dynamoose 必须对如何处理这些情况做出假设。但是,如果您遵循 Dynamoose 的时间戳模式(例如,update不会添加时间戳,并且只能用于更新现有项目、在 Dynamoose 中创建所有项目等),它将完全准确,并且您不会遇到任何这些陷阱。

如果您有任何关于如何提高 Dynamoose 知识的创造性解决方案,请随时在 repo 上创建拉取请求或创建问题来讨论您的想法。

于 2020-12-13T00:19:07.043 回答