相关文章推荐

handler的地方也很簡單,只要進行儲存就可以了,以下是精簡的實作

String catalog = input.getPath("catalog");
Message message = input.getBody(Message.class);
if (StringUtils.isNullOrEmpty(catalog))
    return new ResponseBean(500);
message.setCatalog(catalog);
DynamoDBMapper mapper = new DynamoDBMapper(DBClientFactory.getAmazonDynamoDB());
mapper.save(message);
return new ResponseBean(message);

query

因為資料表我們設計可以放很多種不同的時間序列,以partition key做為區分查詢。所以我們只需要用catalog查詢即可撈取最新資料。

假設我們想要撈取最新十筆資料

String catalog = input.getPath("catalog");
Message message = new Message();
message.setCatalog(catalog);
DynamoDBMapper mapper = new DynamoDBMapper(DBClientFactory.getAmazonDynamoDB());
List<?> list = mapper.query(Message.class,
    new DynamoDBQueryExpression<Message>()
        .withHashKeyValues(message)
        .withScanIndexForward(false)
        .withLimit(10));
return new ResponseBean(list.toArray());

其中ScanIndexForward預設為true,項目以Range Key字母順序或數字大小讀取,所以這邊設為false,以時間字串來說則是最新的資料為先。

queryPage

但是通常時間序列的資料很多,有時候會希望以日期時間條件及分頁方式查詢,這邊介紹分頁的處理方式。

原則上當我們想用分頁顯示資料時,都代表資料量很大,如果預先抓取全部資料後篩選分頁內容是很浪費效能的。在這方面,DynamoDB API提供LastEvaluatedKey的做法,這不論是queryPage或scanPage等都可以這樣使用。

在使用page查詢方式時回傳的ResultPage會提供results、lastEvaluatedKey、count、scannedCount等屬性如下
(為了方便測試圖中以limit(2)查詢)

在使用page查詢方法時若提供設定exclusiveStartKey,回傳的page則以該key之後繼續讀取。

所以若實作get API
Path: /message/{catalog}
Path: /message/{catalog}/{last}

當path variable last有值時則在查詢增加start key即可

String catalog = input.getPath("catalog");
Message message = new Message();
message.setCatalog(catalog);
DynamoDBMapper mapper = new DynamoDBMapper(DBClientFactory.getAmazonDynamoDB());
DynamoDBQueryExpression<Message> expr = new DynamoDBQueryExpression<Message>()
    .withHashKeyValues(message)
    .withScanIndexForward(false)
    .withLimit(10);
String last = input.getPath("last");
if (!StringUtils.isNullOrEmpty(last)) {
    Map<String, AttributeValue> lastKey = new HashMap<String, AttributeValue>();
    lastKey.put("pk", new AttributeValue().withS(catalog));
    lastKey.put("sk", new AttributeValue().withS(last));
    expr.setExclusiveStrtKey(lastKey);
QueryResultPage<Message> list = mapper.queryPage(Message.class, expr);
return new ResponseBean(list);

舉例來說上面截圖即是使用GET http://localhost:3000/message/book/2019-10-10T07:54:14.242Z
取得下一頁的資料的。

最後是,對於ResultPage建議還是自己自訂response payload呈現,避免lastEvaluatedKey直接曝露pk、sk,你也會注意到sk實際上在dynamodb儲存的時間格式跟前篇json定義的datetime字串格式並不一樣,這些都是可以再處理的細節。

 
推荐文章