使用 Java SDK 2 查询超过 100 个与分区键匹配的 DynamoDB 项目?

Query More Than 100 DynamoDB Items that match a Partition Key using Java SDK 2?

如何使用 aws java sdk 2 查询来自 dynamodb table 的超过 100 个项目,匹配特定的分区键?

如果匹配哈希键的行数exceeds 100 then the batchGetItemPaginator method needs to be used. This method accepts a BatchGetItemRequest which requires a KeysAndAttributes.

当我仅使用散列键而非排序键构造 KeysAndAttributes 时,出现以下异常

DynamoDbException: The provided key element does not match the schema

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

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

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

提前感谢您的考虑和回复。

主键>>分区+HashKey

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

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

列表

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

要仅通过分区键获取项目,我们必须使用 query api,其中 returns 最多 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;
}

在 table 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();
}