我需要在DynamoDB上进行限制和条件扫描 .
docs说:
在响应中,DynamoDB返回Limit值范围内的所有匹配结果 . 例如,如果发出限制值为6且没有过滤器表达式的查询或扫描请求,DynamoDB将返回表中与请求中指定的键条件匹配的前六项(或仅返回前六项)扫描没有过滤器的情况 . 如果还提供FilterExpression值,DynamoDB将返回前六个中与过滤器要求匹配的项目(返回的结果数将小于或等于6) .
The code (NODEJS):
var params = {
ExpressionAttributeNames: {"#user": "User"},
ExpressionAttributeValues: {":user": parseInt(user.id)},
FilterExpression: "#user = :user and attribute_not_exists(Removed)",
Limit: 2,
TableName: "XXXX"
};
DynamoDB.scan(params, function(err, data) {
if (err) {
dataToSend.message = "Unable to query. Error: " + err.message;
} else if (data.Items.length == 0) {
dataToSend.message = "No results were found.";
} else {
dataToSend.data = data.Items;
console.log(dataToSend);
}
});
Table XXXX definitions:
-
主分区键:用户(号码)
-
主要排序键:标识符(字符串)
-
索引:
-
索引名称:RemovedIndex
-
类型:GSI
-
分区键:已删除(编号)
-
排序键: -
-
属性:全部
在上面的代码中,如果我删除 Limit
参数,DynamoDB将返回符合过滤器要求的项目 . 所以,条件还可以 . 但是当我用 Limit
参数扫描时,结果为空 .
XXXX表有5个项目 . 只有2个第一个具有 Removed
属性 . 当我在没有 Limit
参数的情况下扫描时,DynamoDB返回没有 Removed
属性的3个项目 .
我做错了什么?
3 回答
您可以通过使用二级索引获得所需内容 . 使用经典的RDB示例,客户订单示例:您有一个表用于客户,一个用于订单 . Orders表有一个Key,包括Customer - HASH,Order - RANGE . 因此,如果您想获得最新的10个订单,没有扫描就无法实现
但是如果你在“Some Constant” - HASH,Date RANGE的订单上创建一个全局二级索引,并查询该索引,他们会查询你想要的东西,只收取与返回记录有关的RCU的费用 . 无需昂贵的扫描 . 注意,写入会更昂贵,但在大多数情况下,读取次数多于写入次数 .
如果你想获得一天大于1000美元的10大订单,那么现在你有了原来的问题 . 查询将返回最后10个订单,然后筛选出低于1000美元的订单 .
在这种情况下,您可以创建Date-OrderAmount的计算键,并且针对该索引的查询将返回您想要的内容 .
它不像SQL那么简单,但你也需要考虑SQL中的访问模式 . 如果您有大量数据,则需要在SQL中创建索引,否则数据库将很乐意代表您进行表扫描,这会影响性能并增加成本 .
请注意,我提出的所有内容都是标准化的,因为只有一个真实来源 . 您不是在复制数据 - 您只需重新构建它的视图以从DynamoDB获得所需内容 .
请记住,CONSTANT作为HASH的每个分区限制为10GB,因此如果您有大量活动数据,则需要围绕它进行设计 . 例如,根据您预期的访问模式,您可以使用Customer而不是常量作为HASH . 或者使用STream以其他方式组织数据(或子集) .
来自您引用的文档:
通过组合Limit和FilterExpression,您已告知DynamoDB仅查看表中的前两项,并针对这些项评估FilterExpression . DynamoDB中的限制可能会令人困惑,因为它与RDBMS中的SQL表达式中的
limit
的工作方式不同 .也遇到了这个问题,我猜你只需扫描整个表格最多1 MB
扫描扫描的结果集限制为每次调用1 MB . 您可以使用扫描响应中的
LastEvaluatedKey
来检索更多结果 .http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Limits.html