DynamoDBのドキュメントAPI、JSON対応したから簡単なサンプルで紹介する part1


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のイベントアクティビティを管理するテーブルを作成してみます。

```java
	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)
			);


```


テーブルを取る
-

こんだけ。

```java
	DynamoDB dynamo = new DynamoDB(client);
	Table table = dynamo.getTable("Game");
```


データのPUT
-

次はデータ入れてみます。
Tableに入れるデータ構造としてはItemを作ります。Itemが各レコードと思ってもらって差し支えなさそう。
最近のアップデートで、JSON、Map、Listなどを入れられるようになりました。	

```java
	//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でデータ取ってきます。

```java
		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がこんな感じだとすると、

```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
  }
}
```

こんな感じで部分的に取れます。

```json
{
  "gameName" : "shot6",
  "gameStatus" : "COMPLETE",
  "ranking" : 5
}
```




まとめ
-

今回はこれくらいにしておきますかねー。次回はもう少しQueryあたりをやろうかなと思います。