1

如何使用 aws java sdk 2 查询 dynamodb 表中匹配特定分区键的 100 多个项目?

如果匹配哈希键的行数超过 100,则需要使用 batchGetItemPaginator 方法。此方法接受BatchGetItemRequest需要 a 的 a KeysAndAttributes

当我仅使用哈希键而不是排序键构造 KeysAndAttributes 时,出现以下异常

DynamoDbException:提供的关键元素与架构不匹配

但是,如果我在 KeysAndAttributes 中提供排序键,则 batchGetItemPaginator 方法可以正常工作。

那么如何使用主键(无排序键)构造 BatchGetItemRequest 呢?

注意:我的问题不是这个问题的重复。如果行数超过 100,则其他问题不涉及所需的分页。

预先感谢您的考虑和回复。

4

1 回答 1

2

主键 >> 分区 + HashKey

GetItem用于通过主键获取一项。

BatchGetItem用于使用多个主键从多个表中获取多个项目。所以,我们需要传递 Partition 和 HashKey 的列表

我们永远不能使用部分密钥(即分区密钥)执行 getItem 或 batchGetItem。

要仅通过分区键获取项目,我们必须使用查询api,它返回最大 1 MB 的数据。要获取具有特定分区键的所有记录,我们可以通过使用 ExclusiveStartKey 多次调用查询 api 来进行分页

.exclusiveStartKey(exclusiveStartKey)帮助我们在特定记录之后开始。

.limit(10)通常设置为不超过总大小超过 1 MB 的合理数字。如果没有项目不是问题,我们可以排除它。

response.lastEvaluatedKey()从响应中捕获此内容以用于下一个查询。

public static Map<String, AttributeValue> queryTable(DynamoDbClient ddb, String tableName, String partitionKeyName,
        String partitionKeyVal, Map<String, AttributeValue> exclusiveStartKey) {

    Map<String, AttributeValue> lastEvaluatedKey = null;

    HashMap<String, AttributeValue> attrValues = new HashMap<String, AttributeValue>();
    attrValues.put(":" + partitionKeyName, AttributeValue.builder().s(partitionKeyVal).build());
    QueryRequest queryReq = QueryRequest.builder().tableName(tableName).exclusiveStartKey(exclusiveStartKey)
            .keyConditionExpression(partitionKeyName + " = :" + partitionKeyName)
            .expressionAttributeValues(attrValues).limit(10).build();

    try {
        QueryResponse response = ddb.query(queryReq);
        lastEvaluatedKey = response.lastEvaluatedKey();
    } catch (DynamoDbException e) {
        System.err.println(e.getMessage());
        System.exit(1);
    }
    return lastEvaluatedKey;
}

test表上的样本测试,pk作为值的分区键1

public static void main(String[] args) {

    Region region = Region.US_EAST_1;
    DynamoDbClient ddb = DynamoDbClient.builder().region(region).build();

    Map<String, AttributeValue> lastEvaluatedKey = null;
    // Loop until we don't get lastEvaluatedKey 
    do {
        System.out.println("---------DynamoDb Query with Exclusive Start Key------------" + lastEvaluatedKey);
        lastEvaluatedKey = queryTable(ddb, "test", "pk", "1", lastEvaluatedKey);
    } while (lastEvaluatedKey != null && !lastEvaluatedKey.isEmpty());

    ddb.close();
}
于 2021-02-15T02:01:16.757 回答