使用DynamoDBMapper Java AWS SDK进行分页

时间:2015-09-25 19:01:17

标签: amazon-web-services pagination amazon-dynamodb aws-java-sdk

从API文档中,dynamo db确实支持扫描和查询操作的分页。这里的问题是将当前请求的id,column,timestamp 1,NULL,10:30 am 1,NULL,10:31 am 1,'xyz',10:32 am 1,'def',10:33 am 2,NULL,11:30 am 2,'abc',11:31 am Output(expected) :- 1,'xyz',10:30 am 1,'xyz',10:31 am 1,'xyz',10:32 am 1,'xyz',10:33 am 2,'abc',11:30 am 2,'abc',11:31 am 设置为先前请求的ExclusiveStartIndex的值,以获得结果的下一组(逻辑页)。

我正在尝试实现相同但我正在使用LastEvaluatedIndex,这似乎有很多优点,比如与数据模型紧密耦合。所以,如果我想做上述事情,我假设我会做以下事情:

DynamoDBMapper

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

// 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,我怎么知道在这种情况下我是否达到了结果。

1 个答案:

答案 0 :(得分:33)

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

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

我会越过PaginatedScanListScanResultPage,但这些方法/对象基本上互为镜像。

PaginatedScanList说明以下内容,强调我的:

  

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

这表示在遍历列表时会加载结果。当您浏览第一页时,将自动获取第二页,而您必须明确地发出另一个请求。延迟加载结果是默认方法,但如果您调用重载方法并提供DynamoDBMapperConfig不同的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