DynamoDBテーブルの巨大データレコード数取得方法with nodejs

  • 4
    Like
  • 0
    Comment

DynamoDBのテーブル項目数やストレージ容量については、画面上にリアルタイムでは更新されません。「これらは、およそ 6 時間ごとに定期的に更新されます。」と書いています。
DynamoDBにレコードを追加や削除などの開発をする場合、非常に不便です。テーブルの項目数の取得方法について下記の幾つかがあります。

事前準備

let aws = require('aws-sdk');
let util = require('util');
let awsConfiguration = {
    "accessKeyId": "accessKeyId",
    "secretAccessKey": "secretAccessKey",
    "region": "ap-northeast-1" //tokyo
  };
aws.config.update(awsConfiguration);

let dynamodb = new aws.DynamoDB({apiVersion: '2012-08-10'});
let params = {TableName:'scan_table'};

describe-table (テーブル詳細表示)

dynamodb.describeTable(params, function(err, data) {
    if (err) {
        console.log(err, err.stack);
    } else {
        console.log(data);
    }
});

出力

{
    "TableDescription": {
        "TableArn": "arn:aws:dynamodb:ap-northeast-1:0:table/scan_table",
        "AttributeDefinitions": [
            {
                "AttributeName": "id",
                "AttributeType": "N"
            },
            {
                "AttributeName": "name",
                "AttributeType": "S"
            }
        ],
        "ProvisionedThroughput": {
            "NumberOfDecreasesToday": 0,
            "WriteCapacityUnits": 1,
            "ReadCapacityUnits": 100,
            "LastDecreaseDateTime": 1484895396.199
        },
        "TableSizeBytes": 0,
        "TableName": "scan_table",
        "TableStatus": "ACTIVE",
        "KeySchema": [
            {
                "KeyType": "HASH",
                "AttributeName": "name"
            },
            {
                "KeyType": "RANGE",
                "AttributeName": "id"
            }
        ],
        "ItemCount": 0,
        "CreationDateTime": 1484890557.888
    }
}

"ItemCount": 0 はテーブルのレコード数。
describe-tableは画面の概要を表示するだけで、画面がリアルタイム更新されない場合、こちらの情報も更新されません。

scan (全件出力)

let params = {
    TableName: "scan_table",
    Select: "COUNT"
};
//DynamoDB scan only returns up to 1MB of data, so we need to keep scanning.
dynamodb.scan(params, function (err, res) {
    console.log(util.inspect(res, false, null));
});

出力

{ Count: 14171,
  ScannedCount: 14171,
  LastEvaluatedKey:
   { name: { S: 'testtesttestetettsetstetesse' },
     id: { N: '14171' } } }

14171のレコード数が取得されただけです。実は1億ぐらいレコードがあります。原因はDynamoDBのscanは1MBのデータの制限があるので、1MB超えたら、scan停止して結果をreturnします。LastEvaluatedKeyを使って繰り返しscanして、全レコード数をreturnできます。

実装方法

let scanTable = function(callback) {
    let params = {
        TableName: "scan_table"
    };

    //let items = []
    let records = 0;

    let scanExecute = function(callback) {

        dynamodb.scan(params,function(err,result) {

            if(err) {
                callback(err);
            } else {
                 //レコードの内容を取得場合
                //items = items.concat(result.Items); 
                records += result.Count;
                console.log('records=' + records);
                if(result.LastEvaluatedKey) {
                   params.ExclusiveStartKey = result.LastEvaluatedKey;
                    scanExecute(callback);
                } else {
                    callback(err,records);
                    //callback(err,items);
                }
            }
        });
    }
    scanExecute(callback);
};

scanTable(function(err, all) {
    console.log(err, all);
});

出力

records=14171
records=28342
records=42513
records=56684
records=70855
records=85026
records=99197
records=113368
records=127539
records=141710
records=155881
records=170052
records=184223
records=198394
records=212565
records=226736
records=240907
records=255078
records=269249
records=283420
records=297591
records=311762
records=325933
records=340104
records=354275
records=368446
records=382617
....

DynamoDBの読み込みキャパシティーが適切に設定する必要があります。

この手順で全レコード数が取得できます。