À partir de l'API docs, la dynamo db prend en charge la pagination pour les opérations d'analyse et de requête. Le hic ici est de définir le ExclusiveStartIndex
de la demande actuelle à la valeur du LastEvaluatedIndex
de la demande précédente pour obtenir le prochain ensemble (page logique) des résultats.
J'essaie d'implémenter la même chose mais j'utilise DynamoDBMapper
, ce qui semble avoir beaucoup plus d'avantages comme un couplage étroit avec des modèles de données. Donc, si je voulais faire ce qui précède, je suppose que je ferais quelque chose comme ci-dessous:
// 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);
J'espère que ma compréhension ci-dessus est correcte pour la pagination à l'aide de DynamoDBMapper. Deuxièmement, comment saurais-je que j'ai atteint la fin des résultats. Depuis la documentation si j'utilise l'API suivante:
QueryResult result = dynamoDBClient.query((QueryRequest) request);
boolean isEndOfResults = StringUtils.isEmpty(result.getLastEvaluatedKey());
Pour en revenir à l'utilisation de DynamoDBMapper, comment savoir si j'ai atteint la fin des résultats dans ce cas.
Vous avez quelques options différentes avec le DynamoDBMapper
, selon la direction que vous souhaitez suivre.
query
- renvoie un PaginatedQueryList
queryPage
- renvoie un QueryResultPage
scan
- renvoie un PaginatedScanList
scanPage
- renvoie un ScanResultPage
La partie ici est de comprendre la différence entre les méthodes et quelles fonctionnalités leurs objets renvoyés encapsulent.
Je vais passer en revue PaginatedScanList
et ScanResultPage
, mais ces méthodes/objets se reflètent essentiellement les uns les autres.
Le PaginatedScanList
dit ce qui suit, c'est moi qui souligne:
Implémentation de l'interface List qui représente les résultats d'une analyse dans AWS DynamoDB. Les résultats paginés sont chargés à la demande lorsque l'utilisateur exécute une opération qui les requiert. Certaines opérations, telles que size (), doivent récupérer la liste entière, mais les résultats sont paresseusement récupérés page par page lorsque cela est possible.
Cela signifie que les résultats sont chargés lorsque vous parcourez la liste. Lorsque vous parcourez la première page, la deuxième page est automatiquement récupérée sans que vous ayez à faire explicitement une autre demande. Le chargement différé des résultats est la méthode par défaut, mais il peut être remplacé si vous appelez les méthodes surchargées et fournissez un DynamoDBMapperConfig
avec un autre DynamoDBMapperConfig.PaginationLoadingStrategy
.
C'est différent du ScanResultPage
. On vous donne une page de résultats, et c'est à vous de gérer la pagination vous-même.
Voici un exemple de code rapide montrant un exemple d'utilisation des deux méthodes que j'ai exécutées avec un tableau de 5 éléments à l'aide de DynamoDBLocal:
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);
Et la sortie:
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