DynamoDBはAWSが提供するNoSQLサービスで、スケールして運用管理いらず、簡単に使える所がメリットです。DynamoDBは最近立て続けにアップデートしており、特に最近JSONが保存できるようになって使いやすくなった事もあるので、記念(?)と自分のおさらいもかねて、さっくりとサンプルを何回かにわけてご紹介していこうと思っています。長くなってきたら分割するくらいの感じで。
環境
JDK 1.7.0_71
Eclipse Kepler
AWS Eclipse Plugin
AWS SDK for Java 1.9.1
他の言語でも同様のことが出来るはずですが、まあひとまずJavaで。本来はGoで書きたいところですが、まあそれはおいおい。
テーブルを作成する
こんな感じのコードスニペットになります。DynamoDBの最近のJava SDKだと、Tableを中心に操作する感じになります。前よりは直感的になったように思います。超シンプルなGameのイベントアクティビティを管理するテーブルを作成してみます。
String tablename = "Game";
Table table = dynamo.createTable(tablename,
Arrays.asList(
new KeySchemaElement("gameId", KeyType.HASH),
new KeySchemaElement("time", KeyType.RANGE)),
Arrays.asList(
new AttributeDefinition("gameId", ScalarAttributeType.N),
new AttributeDefinition("time", ScalarAttributeType.S)),
new ProvisionedThroughput(5L, 5L)
);
テーブルを取る
こんだけ。
DynamoDB dynamo = new DynamoDB(client);
Table table = dynamo.getTable("Game");
データのPUT
次はデータ入れてみます。
Tableに入れるデータ構造としてはItemを作ります。Itemが各レコードと思ってもらって差し支えなさそう。
最近のアップデートで、JSON、Map、Listなどを入れられるようになりました。
//JSONつくるのめんどいので、Jacksonで適当なクラスからさくっと生成
Meta alias = new Meta();
{
alias.gameName = "shot6";
alias.ranking = 5;
alias.gameStatus = "COMPLETE";
}
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(alias);
table.putItem(new Item()
.withPrimaryKey("gameId", 111, "time", "201410210214")
.withString("playerId", "hoge1")
.withInt("score", 10012)
.withList("teamFriendId", "foo1", "foo2", "foo3")
.withMap("additionalInfo", ImmutableMap.of("aaa1", "bbb1", "aaa2", "bbb2"))
.withJSON("metadata", json));
ま、それ以外にもバルクでちょっとロードしておきます。まあこの辺はみなさん適当にやってみてくださし。
GETしてみる
データ入れたので今度はGETしてみます。Hash + Rangeでデータ取ってきます。
Item item = table.getItem("gameId", 111, "time", "201410210214");
//AttributeをMap<String, Object>でまわせるのは便利
for (Map.Entry<String, Object> attribute : item.attributes()) {
System.out
.println(attribute.getKey() + ", " + attribute.getValue());
}
//mapでとると、DynamoDB側ではNumberがBigDecimalにマップされてて若干はまった・・・
Map<String, Object> map = item.asMap();
BigDecimal score = (BigDecimal) map.get("score");
System.out.println("score from map : " + score);
//Itemから取ると、コンバートしてくれている
int scoreResult = item.getInt("score");
System.out.println("score from Item : " + scoreResult);
//JSONも取れる
String metadata = item.getJSON("metadata");
System.out.println(metadata);
//JSONから子供の部分だけ、Itemにして扱える
Item partItem = Item.fromJSON(metadata);
System.out.println(partItem.get("gameName") + ", "
+ partItem.get("ranking") + "," + partItem.get("gameStatus"));
最後の部分だけ、少しだけ捕捉すると、全体のJSONがこんな感じだとすると、
{
"teamFriendId" : [ "foo1", "foo2", "foo3" ],
"time" : "201410210214",
"playerId" : "hoge1",
"gameId" : 111,
"score" : 10012,
"additionalInfo" : {
"aaa1" : "bbb1",
"aaa2" : "bbb2"
},
"metadata" : {
"gameName" : "shot6",
"gameStatus" : "COMPLETE",
"ranking" : 5
}
}
こんな感じで部分的に取れます。
{
"gameName" : "shot6",
"gameStatus" : "COMPLETE",
"ranking" : 5
}
まとめ
今回はこれくらいにしておきますかねー。次回はもう少しQueryあたりをやろうかなと思います。