web-dev-qa-db-ja.com

DynamoDBMapperによるページ分割Java AWS SDK

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の使用に戻って、この場合に結果の最後に到達したかどうかを確認するにはどうすればよいですか。

17
Adi GuN

DynamoDBMapper には、どちらの方法を使用するかによって、いくつかの異なるオプションがあります。

ここでの部分は、メソッド間の違いと、返されるオブジェクトがカプセル化する機能を理解することです。

PaginatedScanListScanResultPageについて説明しますが、これらのメソッド/オブジェクトは基本的に互いにミラーリングしています。

PaginatedScanListは次のように述べています、私のものを強調しています:

AWS DynamoDBでのスキャンの結果を表すListインターフェースの実装。 ページ付けされた結果は、ユーザーがそれらを必要とする操作を実行するときにオンデマンドでロードされます。size()などの一部の操作は、リスト全体をフェッチする必要がありますが、結果は可能な限りページごとに遅延フェッチされます。

これは、リストを反復処理するときに結果がロードされることを示しています。最初のページを通過すると、明示的に別のリクエストを行わなくても、2番目のページが自動的にフェッチされます。結果の遅延読み込みはデフォルトのメソッドですが、オーバーロードされたメソッドを呼び出して、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
38
mkobit