batchGet は params の構造が覚えづらく、UnprocessedKeys
の処理法もやや気を使うのでスニペット。
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
-
BatchGetItem - Amazon DynamoDB
- 日本語の方(BatchGetItem - Amazon DynamoDB)はバージョンが古いので注意(例えば「取得される項目の数は、1 MB のサイズ制限によって制限されます」と書かれているが、最新版では16MB)