10

從API文檔中,dynamo db確實支持掃描和查詢操作的分頁。這裏的要點是將當前請求的ExclusiveStartIndex設置爲先前請求的LastEvaluatedIndex的值,以獲得結果的下一組(邏輯頁面)。分頁與DynamoDBMapper Java AWS SDK

我試圖實現相同的功能,但我使用的是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,我怎麼能知道我是否已經達到在這種情況下的結果結束。

回答

22

對於DynamoDBMapper,您有幾個不同的選項,具體取決於您想要的方式。

的部分是理解的區別方法以及它們返回的對象的功能封裝。

我會去PaginatedScanListScanResultPage,但這些方法/對象基本上相互鏡像。

PaginatedScanList說下文中,重點煤礦:

表示從AWS DynamoDB掃描結果List接口的實現。 當用戶執行需要它們的操作時,按需加載分頁結果。某些操作(如size())必須獲取整個列表,但在可能的情況下會逐頁獲取結果。

這就是說,在遍歷列表時加載結果。當你通過第一頁時,第二頁會自動提取,而你不得不明確地提出另一個請求。延遲加載結果是默認方法,但如果您調用重載方法並提供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 
+0

如果'limit'是在使用'query'時設置爲2,它仍然返回所有記錄。這是爲什麼? – user7

+1

@ user7實際上,底層實現('PaginatedQueryList')正在爲您處理分頁時,它只顯示它正在返回所有記錄。查看['PaginatedQueryList']的文檔(https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/PaginatedQueryList.html)。它的行爲與我上面發佈'scan'相同。基本上,如果迭代它,它最終將獲取所有元素,因爲它會自動執行分頁調用。 – mkobit

+0

那麼'withLimit'不適用於它? – user7