不,这是不可能的。单个查询可能只搜索一个特定的哈希键值。(请参阅DynamoDB – 查询。)
但是,您可以并行执行多个查询,这将产生您想要的效果。
编辑 (2018-11-21)
由于您说您正在寻找 200 多个哈希键,因此这里有两种可能的解决方案。这些解决方案不需要对 DynamoDB 进行无限制的并行调用,但它们会花费您更多的 RCU。它们可能更快或更慢,具体取决于表中数据的分布。
我不知道你的数据分布,所以我不能说哪一个最适合你。在所有情况下,我们都不能acc_token
用作 GSI 的排序键,因为您不能IN
在 KeyConditionExpression 中使用运算符。(请参阅DynamoDB – 条件。)
解决方案 1
该策略基于Global Secondary Index Write Sharding for Selective Table Queries
脚步:
- 向您写入表的项目添加新属性。这个新属性可以是数字或字符串。让我们称之为
index_partition
。
- 当您向表中写入新项目时,请为其指定一个从
0
到N
for的随机值index_partition
。(在这里,N
是您选择的任意常数。9
可能是一个不错的值开始。)
- 创建一个 GSI,其哈希键为
index_partition
,排序键为ts
。您将需要投影apiAction
到acc_token
GSI。
- 现在,您只需要执行
N
查询。使用关键条件表达式index_partition = :n AND ts between :val1 and :val2
和过滤器表达式apiAction = :status AND acc_token in :acc_token_list
解决方案 2
此解决方案与上一个类似,但我们将使用基于日期的 GSI 分区,而不是使用随机 GSI 分片。
脚步:
- 向您写入表的项目添加新的字符串属性。让我们称之为
ts_ymd
。
- 当您向表中写入新项目时,只需使用 的
yyyy-mm-dd
一部分ts
来设置 的值ts_ymd
。(您可以使用任何您喜欢的粒度。这取决于您对 . 的典型查询范围ts
。如果:val1
并且:val2
通常彼此之间仅相隔一个小时,那么合适的 GSI 分区键可能是 yyyy-mm-dd-hh。)
- 创建一个 GSI,其哈希键为
ts_ymd
,排序键为ts
。您将需要投影apiAction
到acc_token
GSI。
- 假设您使用 yyyy-mm-dd 作为 GSI 分区键,您只需为
:val1
and内的每一天执行一个查询:val2
。使用关键条件表达式ts_ymd = :ymd AND ts between :val1 and :val2
和过滤器表达式apiAction = :status AND acc_token in :acc_token_list
解决方案 3
我不知道apiAction
有多少不同的值以及这些值是如何分布的,但如果有多个,并且它们的分布大致相等,您可以根据该值对 GSI 进行分区。您对 的可能值越多apiAction
,此解决方案就越适合您。这里的限制因素是您需要有足够的值,以免您的 GSI 遇到 10GB 分区限制。
脚步:
- 创建一个 GSI,其哈希键为
apiAction
,排序键为ts
。您将需要投影acc_token
到 GSI。
- 您只需要执行一个查询。
apiAction = :status AND ts between :val1 and :val2" and a filter expression of
在 :acc_token_list 中使用 acc_token 的键条件表达式。
对于所有这些解决方案,您应该考虑 GSI 分区键的分布有多均匀,以及ts
查询中典型范围的大小。您必须在 上使用过滤器表达式acc_token
,因此您应该尝试选择一个最小化与您的关键条件表达式匹配的项目总数的解决方案,但同时,您需要注意您不能超过10GB 数据用于一个分区键(用于表或 GSI)。您还需要记住,GSI 只能作为最终一致性读取进行查询。