我在dynamodb中有一个表,该表的结构如下:
PK StatusId
为String
,排序键DateTimeStamp
为Number
。
我想实现select * from InternalProductionDb order by DateTimeStamp desc limit 10;
let params = {
ExpressionAttributeValues: {
':min': {
N: '200000000000'
},
':max': {
N: '300000000000'
},
':beg':{
S:'2'
}
},
TableName: "InternalProductionDb",
ConsistentRead: true,
Limit: 10,
KeyConditionExpression:' DateTimeStamp between :min and :max and begins_with(StatusId,:beg)' ,
ScanIndexForward:true
};
let res = await ddb.query(params).promise();
console.dir(res);
return res;
实际上,因为我不需要进行任何条件判断,所以我确实不需要KeyConditionExpression
,但是API必须指定KeyConditionExpression
参数。因此,我写了两个不可避免的判断语句。
我认为这太复杂了,我得到了一个错误。
错误是Query key condition not supported
,
那么有人知道正确的解决方案吗?
非常感谢
答案 0 :(得分:2)
DynamoDB不是关系数据库!您要的是针对您的模式的非常复杂的查询。
您需要为时间序列查询优化的架构,例如“获取表中的10个最新项”。这样的架构必须在水平缩放(Dynamo提供的即装即用)和数据局部性之间做出折衷,以便组合您的响应。
一种选择是按日期对数据进行分区。例如,将日期用作分区键,将时间戳用作排序键。然后,假设您获得了足够的数据,为了回答您的查询,您只需要查看今天以及可能是前一天。
如果您每天都不总是获得足够的数据,那么事情当然会变得更加棘手,在这种情况下,弄清最近的日期是更加复杂的。您可以将分区键的粒度更改为按周/月。
您还可以使用其他类型的架构,将“最新”数据全部保留在一个分区中,然后将旧数据转出。
但是,这是另一种想法:您可以创建两个表-一个表用于存储每个项目,而另一个表则仅保存最新的表。您可以在“最新表”上使用TTL并删除早于某个阈值的记录,并且可以在此表上设置架构,以使所有项目都属于同一分区(即,它们具有相同的PK值),并且然后将时间戳记用作排序键。然后,获取最新的前10名变得很容易。
或者,您可以将关系数据库与DynamoDB结合使用以进行分析查询。