如何查询 dynamoDB 中包含特定子字符串的分区键



我有一个分区键,它由 2 个字符串组成,例如 userId:UserName。例如1234:约翰,4567:马可等。我想查询与用户名定义的子字符串匹配的所有记录,例如查找分区键中包含"Mark"的所有记录。如何在 Java 中使用 DynamoDb API 执行此操作?

希望这不是你必须经常做的事情。

DynamoDB 不支持通过部分哈希键进行查询。您必须使用表扫描来循环访问表中的所有元素,并比较每个元素的匹配项。

这是非常低效的,如果你发现自己依赖于这种类型的行为,那么你必须重新审视你的哈希键选择和你的整体设计选择。

为了完整起见,如果您使用的是文档 API,则要查找的代码将遵循以下行:

// dynamo returns results in chunks - you'll need this to get the next one
Map<String, AttributeValue> lastKeyEvaluated = null;
do {
   ScanRequest scanRequest = new ScanRequest()
       .withTableName("YourTableNameHere")
       .withExclusiveStartKey(lastKeyEvaluated);
   ScanResult result = client.scan(scanRequest);
   for (Map<String, AttributeValue> item : result.getItems()){
       // for each item in the result set, examine the partition key
       // to determine if it's a match
       string key = item.get("YourPartitionKeyAttributeNameHere").getS();
       if (key.startsWith("Mark"))
           System.out.println("Found an item that matches *:Mark:n" + item);
   }
   lastKeyEvaluated = result.getLastEvaluatedKey();
} while (lastKeyEvaluated != null);

但是,在应用程序中实现类似内容之前,请考虑选择不同的分区键策略,或为表创建二级索引,或两者兼而有之 - 如果您需要经常进行此类查询!

作为旁注,我很好奇,在分区键中包含用户 ID 和用户名有什么好处? 用户 ID 可能对您来说是唯一的,那么为什么要使用用户名呢?

您无法按照

您以经济高效的方式描述的那样执行此操作。您需要scan表,这既昂贵又耗时。

重新访问您选择的键,以便始终针对完整键值而不是子字符串运行查询。

您可能需要考虑使用范围键 - 当包含范围键时,可以仅针对哈希键(返回可能返回多个值)或哈希键/范围键的组合(必须是唯一的)有效地运行查询。

在此示例中,如果您始终查询 userId:userName 或 userName(但不是 userId 本身),则使用 userName 作为哈希键和 userId 作为范围键是一种简单有效的解决方案。

最新更新