31

从 API 文档 dynamo db 确实支持扫描和查询操作的分页。这里的问题是将ExclusiveStartIndex当前请求的值设置LastEvaluatedIndex为前一个请求的值,以获取下一组(逻辑页面)结果。

我正在尝试实现相同的功能,但我正在使用DynamoDBMapper,这似乎具有更多优势,例如与数据模型的紧密耦合。因此,如果我想执行上述操作,我假设我会执行以下操作:

// Mapping of hashkey of the last item in previous query operation
Map<String, AttributeValue> lastHashKey = .. 
DynamoDBQueryExpression expression = new DynamoDBQueryExpression();

...
expression.setExclusiveStartKey();
List<Table> nextPageResults = mapper.query(Table.class, expression);

我希望我的上述理解在使用 DynamoDBMapper 进行分页时是正确的。其次,我怎么知道我已经达到了结果的终点。如果我使用以下 api,请从文档中获取:

QueryResult result = dynamoDBClient.query((QueryRequest) request);
boolean isEndOfResults = StringUtils.isEmpty(result.getLastEvaluatedKey());

回到使用 DynamoDBMapper,在这种情况下,我如何知道我是否已达到结果的结尾。

4

1 回答 1

59

您有几个不同的选项DynamoDBMapper,具体取决于您想要的方式。

这里的部分是理解方法之间的区别,以及它们返回的对象封装了什么功能。

我会复习一下PaginatedScanListand ScanResultPage,但是这些方法/对象基本上是相互镜像的。

说以下PaginatedScanList,强调我的:

表示 AWS DynamoDB 中的扫描结果的 List 接口的实现。当用户执行需要它们的操作时,会按需加载分页结果。某些操作,例如 size(),必须获取整个列表,但结果会尽可能地逐页延迟获取。

这表示在您遍历列表时会加载结果。当您浏览第一页时,会自动获取第二页,而无需您明确提出另一个请求。延迟加载结果是默认方法,但如果您调用重载方法并为 aDynamoDBMapperConfig提供不同的DynamoDBMapperConfig.PaginationLoadingStrategy.

这与ScanResultPage. 您将获得一页结果,由您自己处理分页。

下面是一个快速代码示例,显示了我使用 DynamoDBLocal 对包含 5 个项目的表运行的两种方法的示例用法:

final DynamoDBMapper mapper = new DynamoDBMapper(client);

// Using 'PaginatedScanList'
final DynamoDBScanExpression paginatedScanListExpression = new DynamoDBScanExpression()
        .withLimit(limit);
final PaginatedScanList<MyClass> paginatedList = mapper.scan(MyClass.class, paginatedScanListExpression);
paginatedList.forEach(System.out::println);

System.out.println();
// using 'ScanResultPage'
final DynamoDBScanExpression scanPageExpression = new DynamoDBScanExpression()
        .withLimit(limit);
do {
    ScanResultPage<MyClass> scanPage = mapper.scanPage(MyClass.class, scanPageExpression);
    scanPage.getResults().forEach(System.out::println);
    System.out.println("LastEvaluatedKey=" + scanPage.getLastEvaluatedKey());
    scanPageExpression.setExclusiveStartKey(scanPage.getLastEvaluatedKey());

} while (scanPageExpression.getExclusiveStartKey() != null);

和输出:

MyClass{hash=2}
MyClass{hash=1}
MyClass{hash=3}
MyClass{hash=0}
MyClass{hash=4}

MyClass{hash=2}
MyClass{hash=1}
LastEvaluatedKey={hash={N: 1,}}
MyClass{hash=3}
MyClass{hash=0}
LastEvaluatedKey={hash={N: 0,}}
MyClass{hash=4}
LastEvaluatedKey=null
于 2015-09-26T18:04:16.960 回答