DynamoDBのテーブルに複雑な構造のドキュメントをputItem()/put()する

# 概要
AWSのDynamoDBのNode.jsの [APIリファレンス](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB.html) には、複雑な構造のドキュメントに関する明快なサンプルが掲載されていません。

以下、書き方のサンプルです。

# 事前準備
#### ■ データ構造
WeightManagementテーブルのドキュメント構造です。
DataのMapとMealのListを格納しています。
![WeightManagement.png](https://qiita-image-store.s3.amazonaws.com/0/107056/266e14df-6416-945c-f275-5663026ee268.png)

#### ■ テーブルのスキーマを定義するLambda

```createTableLambda.js
exports.handler = (event, context, callback) => {
    "use strict";
    
    const AWS = require('aws-sdk');
    let dynamodb = new AWS.DynamoDB();
    
    let params = {
        TableName : "WeightManagement",
        KeySchema: [       
            { AttributeName: "Name", KeyType: "HASH" },  //Partition key
            { AttributeName: "Season", KeyType: "RANGE" }  //Sort key
        ],
        AttributeDefinitions: [       
            { AttributeName: "Name", AttributeType: "S" },
            { AttributeName: "Season", AttributeType: "S" }
        ],
        ProvisionedThroughput: {       
            ReadCapacityUnits: 1, 
            WriteCapacityUnits: 1
        }
    };
    
    dynamodb.createTable(params, function(err, data) {
        if (err) {
            callback(err, null);
        }
        else {
            callback(null, data);
        }
    });
};
```

#### ■ ロールを定義
＜アカウントＩＤ＞は適宜変更してください。
下記では、DynamoDBに対するすべての操作を許可していますが、必要に応じて限定してください。

```dynamodb-full-access.policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1486281528000",
            "Effect": "Allow",
            "Action": [
                "dynamodb:*"
            ],
            "Resource": [
                "arn:aws:dynamodb:ap-northeast-1:＜アカウントＩＤ＞:table/*"
            ]
        }
    ]
}
```

# DynamoDBでputItem()する方法
#### ■ Lambdaを定義

```putItem.js
exports.handler = (event, context, callback) => {
    "use strict";
    
    const AWS = require('aws-sdk');
    let dynamodb = new AWS.DynamoDB();

    let params = {
        TableName: "WeightManagement",
        Item: {
            "Name": {
                S: "Yamada Taro"
            }, 
            "Season": {
                S: "Winter"
            },
            "Data" : {
                M: {
                    "Period": {
                        S: "Morning"
                    },
                    "Weight": {
                        N: "62.3"
                    },
                    "Note": {
                        S: "Before breakfast."
                    }
                }
            },
            "Meal": {
                L: [
                    {
                        M: {
                            "Food": {
                                S: "Cookies"
                            },
                            "Drink": {
                                S: "Caffee"
                            },
                            "Calorie": {
                                N: "350"
                            }
                        }
                    },
                    {
                        M: {
                            "Food": {
                                S: "Cake"
                            },
                            "Drink": {
                                S: "Tea"
                            },
                            "Calorie": {
                                N: "520"
                            }
                        }
                    }
                ]
            }
        }, 
        ReturnConsumedCapacity: "TOTAL"
    };
     
    dynamodb.putItem(params, function(err, data) {
        if (err) {
            callback(err);
        } else {
            callback(null, data);
        }
    });
};
```

#### ■ 結果
DynamoDBのWeightManagementテーブルには、以下のようにItemが格納されました。

![ComplexSchema.png](https://qiita-image-store.s3.amazonaws.com/0/107056/64749a4d-b443-17ec-36b8-5cd60036626c.png)

# DocumentClientでput()する方法
#### ■ Lambdaを定義
こちらのほうが簡単です。

```docClientPut.js
exports.handler = (event, context, callback) => {
    "use strict";
    
    const AWS = require('aws-sdk');
    let docClient = new AWS.DynamoDB.DocumentClient();

    let params = {
        TableName: "WeightManagement",
        Item: {
            Name: "Sato Hanako", 
            Season: "Summer",
            Data : {
                Period: "Morning",
                Weight: 52.3,
                Note: "Before breakfast."
            },
            Meal: [
                {
                    Food: "Cookies",
                    Drink: "Caffee",
                    Calorie: 350
                },
                {
                    Food: "Cake",
                    Drink: "Tea",
                    Calorie: 520
                }
            ]
        }, 
        ReturnConsumedCapacity: "TOTAL"
    };
     
    docClient.put(params, function(err, data) {
        if (err) {
            callback(err);
        } else {
            callback(null, data);
        }
    });
};
```

#### ■ 結果
先ほどと同様の結果になります。
![ComplexSchema_2.png](https://qiita-image-store.s3.amazonaws.com/0/107056/465a33ec-f674-31e6-0e82-6f36d172b6af.png)

以上です。