我在AWS Dynamodb中有一张表,具有100万条记录。是否可以在dynamodb中使用附加排序键条件查询一次查询中的主键值数组?我正在用于服务器端逻辑。
这是参数
var params = {
TableName: "client_logs",
KeyConditionExpression: "#accToken = :value AND ts between :val1 and
:val2",
ExpressionAttributeNames: {
"#accToken": "acc_token"
},
ExpressionAttributeValues: {
":value": clientAccessToken,
":val1": parseInt(fromDate),
":val2": parseInt(toDate),
":status":confirmStatus
},
FilterExpression:"apiAction = :status"
};
这里acc_token是主键,我想在一个查询中查询access_token值的数组。
最佳答案
不,不可能。单个查询只能搜索一个特定的哈希键值。 (请参见DynamoDB – Query。)
但是,您可以并行执行多个查询,这将达到您想要的效果。
编辑(2018-11-21)
因为您说过要查找200多个哈希键,所以这里有两种可能的解决方案。这些解决方案不需要对DynamoDB进行无限制的并行调用,但是它们将使您花费更多的RCU。它们可能更快或更慢,具体取决于表中数据的分布。
我不知道您的数据分布情况,所以我不能说哪个数据最适合您。在所有情况下,我们都不能使用acc_token
作为GSI的排序键,因为您不能在KeyConditionExpression中使用IN
运算符。 (请参见DynamoDB – Condition。)
解决方案1
此策略基于Global Secondary Index Write Sharding for Selective Table Queries
脚步:
向您写入表的项目添加新属性。此新属性可以是数字或字符串。我们称之为index_partition
。
当您向表中写入新项目时,为它指定一个随机值,从0
到N
。 (在这里,index_partition
是您选择的任意常数。N
可能是一个不错的值。)
用9
的哈希键和index_partition
的排序键创建一个GSI。您需要将ts
和apiAction
投影到GSI。
现在,您只需要执行acc_token
查询。使用键条件表达式N
和过滤器表达式index_partition = :n AND ts between :val1 and :val2
解决方案2
此解决方案与上一个类似,但是我们将不使用随机GSI分片,而是对GSI使用基于日期的分区。
脚步:
向您写入表的项目添加新的字符串属性。我们称之为apiAction = :status AND acc_token in :acc_token_list
。
当您向表中写入新项目时,仅使用ts_ymd
的yyyy-mm-dd
部分来设置ts
的值。 (您可以使用任何喜欢的粒度。这取决于您对ts_ymd
的典型查询范围。如果ts
和:val1
通常彼此仅相隔一个小时,则合适的GSI分区键可以是yyyy-mm -dd-hh。)
用:val2
的哈希键和ts_ymd
的排序键创建一个GSI。您需要将ts
和apiAction
投影到GSI。
假设您使用yyyy-mm-dd作为GSI分区键,则您只需每天在acc_token
和:val1
内执行一次查询。使用键条件表达式:val2
和过滤器表达式ts_ymd = :ymd AND ts between :val1 and :val2
解决方案3
我不知道apiAction = :status AND acc_token in :acc_token_list
有多少个不同的值以及这些值的分布方式,但是如果有多个以上值,并且它们具有大致相等的分布,则可以基于该值对GSI进行分区。 apiAction
的可能值越多,此解决方案越适合您。这里的限制因素是您需要具有足够的值,以免GSI的10GB分区限制。
脚步:
用apiAction
的哈希键和apiAction
的排序键创建一个GSI。您需要将ts
投影到GSI。
您只需要执行一个查询。在:acc_token_list`中使用acc_token
acc_token的关键条件表达式。
对于所有这些解决方案,您应考虑GSI分区键的平均分配方式,以及查询中apiAction = :status AND ts between :val1 and :val2" and a filter expression of
的典型范围的大小。您必须在ts
上使用过滤器表达式,因此您应该尝试选择一种解决方案,以最大程度地减少将与关键条件表达式匹配的项目总数,但是与此同时,您需要注意不能一个分区键(用于表或GSI)具有超过10GB的数据。您还需要记住,只能作为最终一致的读取来查询GSI。