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

时间:2016-03-17 00:50:46

标签: java amazon-dynamodb

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

2 个答案:

答案 0 :(得分:4)

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

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);

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

作为旁注,我很好奇,通过在分区键中包含用户ID和用户名可以获得什么好处?用户ID可能对您来说是唯一的,为什么用户名?

答案 1 :(得分:0)

您无法以经济高效的方式描述这一点。您需要scan表,这是昂贵且耗时的。

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

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

在这个例子中,如果你总是要查询userId:userName或userName(但不是 userId本身),那么使用userName作为哈希键而userId作为范围键是一个简单的有效的解决方案。