iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 30
0
Software Development

從Java進入AWS部署RESTful API的心路歷程系列 第 30

Day29-實作(九)時間序列資料-操作

  • 分享至 

  • xImage
  •  

有了資料表跟Bean,我們就可以進行存取了

save

儲存資料的部分很單純,因為只有新增資料這一個行為。

所以API只建立一個

Properties:
    Path: /message/{catalog}
    Method: PUT

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等屬性如下
https://ithelp.ithome.com.tw/upload/images/20191010/20120911SzQ3bIfkIL.png
(為了方便測試圖中以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字串格式並不一樣,這些都是可以再處理的細節。


上一篇
Day29-實作(九)時間序列資料-定義
系列文
從Java進入AWS部署RESTful API的心路歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言