DynamoDBで"The provided starting key does not match the range key predicate"とエラーが出た場合の対策(node.js)

Lambda(node.js)で、DynamoDBから超膨大なレコードを取得するプログラムを開発していました。
1分単位でクエリを実行して、レコードを小分け取得するようにしたのですが、
その際にプロパティを初期化できていなかったため、標題のエラーが発生したようです。

っていうことが、以下の記事を見てわかりました

https://qiita.com/nanananamememe/items/52293f1fece4458cc2fa

具体的な対策は `delete params["ExclusiveStartKey"];` みたいな感じで
プロパティを消せば良いです。

すっごく長いですが、備忘録を兼ねてソースコードを掲載します

```javascript

try {
  var ENV = require('dotenv').config();

  var AWS = require('aws-sdk');
  AWS.config.update({ region: process.env['AWS_DYNAMO_DB_REGION'] });
  var docClient = new AWS.DynamoDB.DocumentClient({ apiVersion : '2012-08-10' });
}
catch(ex){
  console.error(ex);
}

var globalSecondaryIndexes = [{
  key   : 'dummy',
  index : 'dummy-created_at-index',
}];

var primaryKeys = {
  partitionKey : 'log_id',
  sortKey      : 'created_at'
};

async function getBulk(runTime = null)
{
  var myRunTime = runTime ? runTime : new Date();

  var myQuery = "#partitionKey = :partitionVal AND #rangeKey BETWEEN :rangeStart and :rangeEnd";

  var params = {
    TableName: process.env['AWS_DYNAMO_DB_ACCESS_LOG_TABLE_NAME'],
    IndexName : globalSecondaryIndexes[0].index,
    ExpressionAttributeNames : {
      "#partitionKey" : globalSecondaryIndexes[0].key,
      "#rangeKey" : primaryKeys.sortKey
    },
    ExpressionAttributeValues : {
      ":partitionVal" : 1,
      ":rangeStart"   : 0,
      ":rangeEnd"     : 0
    },
    KeyConditionExpression : myQuery
  };

  var results = new Object();
  var dateRanges = [
    {
      "start" : 1586762880,
      "end"   : 1586762939,
    },
    {
      "start" : 1586762940,
      "end"   : 1586762999,
    }
  ];

  try {
    for(var i in dateRanges){
      var dateRange = dateRanges[i];

      params["ExpressionAttributeValues"][":rangeStart"] = dateRange["start"];
      params["ExpressionAttributeValues"][":rangeEnd"] = dateRange["end"];

      delete params["ExclusiveStartKey"]; // <-- ★★★★★★ これ！！ ★★★★★★

      var result = await get(params); // Array.object
      results[dateRange["start"]] = result;
    }

    return results; // Object.Array.object
  }
  catch(ex){
    console.error("Whoops, looks like something went wrong.");
    console.error(ex);
    throw new Error(ex);
  }
};

async function get(params)
{
  try {
    // 初回のクエリ発行
    var response = await queryGet(params);
    var results = response.data; // Array.object

    // 二回目以降のクエリ発行
    while(response.LastEvaluatedKey){
      params.ExclusiveStartKey = response.LastEvaluatedKey;
      response = await queryGet(params);
      // オブジェクトをマージ
      Array.prototype.push.apply(results, response.data);
    }

    // オブジェクトを返す
    return results; // Array.object
  }
  catch(ex){
    myFunc.logError("Whoops, looks like something went wrong.");
    myFunc.logError(ex);
    throw new Error(ex);
  }
};

function queryGet(parameter)
{
  return new Promise((resolve, reject) => {
    docClient.query(parameter, (err, data) => {
      if(err){
        console.error(err);
        reject(err);
      }
      else {
        if(data.LastEvaluatedKey){ // 全件取得できていない場合、最後の取得位置を通知して再帰処理を行う
          resolve({ data: data.Items, count: data.Count, LastEvaluatedKey: data.LastEvaluatedKey });
        }
        else { // 初回または最後の取得処理時
          resolve({ data: data.Items, count: data.Count });
        }
      }
    });
  });
};
```