Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8892

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

$
0
0

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

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

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

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

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

try{varENV=require('dotenv').config();varAWS=require('aws-sdk');AWS.config.update({region:process.env['AWS_DYNAMO_DB_REGION']});vardocClient=newAWS.DynamoDB.DocumentClient({apiVersion:'2012-08-10'});}catch(ex){console.error(ex);}varglobalSecondaryIndexes=[{key:'dummy',index:'dummy-created_at-index',}];varprimaryKeys={partitionKey:'log_id',sortKey:'created_at'};asyncfunctiongetBulk(runTime=null){varmyRunTime=runTime?runTime:newDate();varmyQuery="#partitionKey = :partitionVal AND #rangeKey BETWEEN :rangeStart and :rangeEnd";varparams={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};varresults=newObject();vardateRanges=[{"start":1586762880,"end":1586762939,},{"start":1586762940,"end":1586762999,}];try{for(variindateRanges){vardateRange=dateRanges[i];params["ExpressionAttributeValues"][":rangeStart"]=dateRange["start"];params["ExpressionAttributeValues"][":rangeEnd"]=dateRange["end"];deleteparams["ExclusiveStartKey"];// <-- ★★★★★★ これ!! ★★★★★★varresult=awaitget(params);// Array.objectresults[dateRange["start"]]=result;}returnresults;// Object.Array.object}catch(ex){console.error("Whoops, looks like something went wrong.");console.error(ex);thrownewError(ex);}};asyncfunctionget(params){try{// 初回のクエリ発行varresponse=awaitqueryGet(params);varresults=response.data;// Array.object// 二回目以降のクエリ発行while(response.LastEvaluatedKey){params.ExclusiveStartKey=response.LastEvaluatedKey;response=awaitqueryGet(params);// オブジェクトをマージArray.prototype.push.apply(results,response.data);}// オブジェクトを返すreturnresults;// Array.object}catch(ex){myFunc.logError("Whoops, looks like something went wrong.");myFunc.logError(ex);thrownewError(ex);}};functionqueryGet(parameter){returnnewPromise((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});}}});});};

Viewing all articles
Browse latest Browse all 8892

Trending Articles