AWS SDK for JavaScript: DynamoDB batchGet/batchWriteのサンプル

batchGet は params の構造が覚えづらく、`UnprocessedKeys`の処理法もやや気を使うのでスニペット。

```javascript
const AWS = require("aws-sdk");

async function batchPut(tableName, items) {
    const docClient = new AWS.DynamoDB.DocumentClient({ region: "ap-northeast-1" });
    let unprocessedItems = items.slice();
    while (unprocessedItems.length > 0) {
        let limit = 25;
        let batchItems = unprocessedItems.splice(0, limit);
        let params = {
            RequestItems: {
                [tableName]: batchItems.map(item => {
                    return {
                        PutRequest: {
                            Item: item,
                        },
                    };
                }),
            }
        };
        console.log("batchWrite (put)");
        let res = await docClient.batchWrite(params).promise();
        if (res.UnprocessedItems[tableName] != undefined) {
            unprocessedItems = (res.UnprocessedItems[tableName].map(item => item.PutRequest.Item)).concat(unprocessedItems);
        }
    }
}

async function batchDelete(tableName, keys) {
    const docClient = new AWS.DynamoDB.DocumentClient({ region: "ap-northeast-1" });
    let unprocessedItems = keys.slice();
    while (unprocessedItems.length > 0) {
        let limit = 25;
        let batchItems = unprocessedItems.splice(0, limit);
        let params = {
            RequestItems: {
                [tableName]: batchItems.map(key => {
                    return {
                        DeleteRequest: {
                            Key: key,
                        },
                    };
                }),
            }
        };
        console.log("batchWrite (delete)");
        let res = await docClient.batchWrite(params).promise();
        if (res.UnprocessedItems[tableName] != undefined) {
            unprocessedItems = (res.UnprocessedItems[tableName].map(item => item.DeleteRequest.Key)).concat(unprocessedItems);
        }
    }
}

async function batchGet(tableName, keys) {
    const docClient = new AWS.DynamoDB.DocumentClient({ region: "ap-northeast-1" });
    let unprocessedKeys = keys.slice();
    let items = [];
    while (unprocessedKeys.length > 0) {
        let limit = 100;
        let batchKeys = unprocessedKeys.splice(0, limit);
        let params = {
            TableName: tableName,
            RequestItems: {
                [tableName]: {
                    Keys: batchKeys,
                },
            },
        };
        console.log("batchGet");
        let res = await docClient.batchGet(params).promise();
        items = items.concat(res.Responses[tableName]);
        if (res.UnprocessedKeys[tableName] != undefined) {
            unprocessedKeys = res.UnprocessedKeys[tableName].Keys.concat(unprocessedKeys);
        }
    }
    return items;
}

async function main() {
    const TABLE_NAME = "table1";
    const COUNT = 101;

    // サンプルデータを投入。テーブルのプライマリキーはpk (string)
    let putItems = [];
    for (let i = 0; i < COUNT; i++) {
        putItems.push({ pk: i.toString(), val: "*".repeat(1024 * 300) }); // 1アイテム約300KB
    }
    await batchPut(TABLE_NAME, putItems);

    // 投入したデータを全件取得
    let keys = [];
    for (let i = 0; i < COUNT; i++) {
        keys.push({
            pk: i.toString(),
        });
    }
    let items = await batchGet(TABLE_NAME, keys);
    if (items.length == COUNT) {
        console.log("OK");
    } else {
        console.log(`items.length = ${items.length}, COUNT = ${COUNT}`);
    }

    // サンプルデータ削除
    await batchDelete(TABLE_NAME, keys);
}

main();
```

# 参考
- [Class: AWS.DynamoDB.DocumentClient — AWS SDK for JavaScript](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html#batchGet-property)
- [BatchGetItem - Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html)
    - 日本語の方（[BatchGetItem - Amazon DynamoDB](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/API_BatchGetItem_v20111205.html)）はバージョンが古いので注意（例えば「取得される項目の数は、1 MB のサイズ制限によって制限されます」と書かれているが、最新版では16MB）