我有一个partitionKey,由2个字符串组成,例如用户名:用户名。例如,1234:John,4567:Mark等。我想查询与UserName定义的子字符串匹配的所有记录,例如:在分区键中查找包含“Mark”的所有记录。如何在Java中使用DynamoDb API执行此操作?
答案 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作为范围键是一个简单的有效的解决方案。