DynamoDB:给定一组哈希键

时间:2018-02-04 00:53:11

标签: java amazon-dynamodb batch-query

我有一个表BookbookIdlastBorrowed分别作为哈希和范围键。 让我们说每次借书都会产生新的一行。

(是的,这还不够,我可以添加一个列来跟踪计数并更新lastBorrowed日期。但是,我们只是说我被困在一起这个设计对我来说无能为力。)

给定一组bookIds(或hashKeys),我希望能够查询每本书借来的最后时间。

我尝试使用QueryRequest,但不断获得com.amazonaws.AmazonServiceException: Attempted conditional constraint is not an indexable operation

final Map<String, Condition> keyConditions =
                Collections.singletonMap(hashKeyFieldName, new Condition()
                 .withComparisonOperator(ComparisonOperator.IN)
                 .withAttributeValueList(hashKeys.stream().map(hashKey -> new AttributeValue(hashKey)).collect(Collectors.toList())));

我也尝试使用BatchGetItemRequest,但它也不起作用:

final KeysAndAttributes keysAndAttributes = new KeysAndAttributes() .withConsistentRead(areReadsConsistent);
hashKeys.forEach(hashKey -> { keysAndAttributes.addExpressionAttributeNamesEntry(hashKeyFieldName, hashKey); });

final Map<String, KeysAndAttributes> requestedItemsByTableName = newHashMap();
requestedItemsByTableName.put(tableName, keysAndAttributes);

final BatchGetItemRequest request = new BatchGetItemRequest().withRequestItems(requestedItemsByTableName);

任何建议都将不胜感激! 或者,如果有人可以告诉我目前根本不支持,那么我想我会继续前进!

1 个答案:

答案 0 :(得分:0)

你可以做到这一点,事实上它很容易。您所要做的就是为bookId执行查询,然后获取第一个结果。

顺便说一句,你的表设计听起来绝对正常,唯一的问题是该属性应该被称为借用而不是最后借用。

您可以为一个bookId获得多个结果,但由于lastBorrowed是您的范围键,因此结果将按该属性排序。

你好像在使用Legacy Functions,你在编辑旧代码吗?

如果没有,请执行以下类似的查询:

//Setting up your DynamoDB connection
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard()
.withRegion(Regions.US_WEST_2).build();
DynamoDB dynamoDB = new DynamoDB(client);
Table table = dynamoDB.getTable("YOURTABLE");

//Define the Query
QuerySpec spec = new QuerySpec()
    .withKeyConditionExpression("bookId = :book_id)
    .withValueMap(new ValueMap()
        .withString(":book_id", "12345")
    .withScanIndexForward(true);

//Execute the query
ItemCollection<QueryOutcome> items = table.query(spec);

//Print out your results - take the first item
Iterator<Item> iterator = items.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next().toJSONPretty());
}