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

DynamoDBをNode.jsで操作する

$
0
0

Node.jsでDynamoDBを触ってみたので、備忘録として残しておきます。

プライマリーキーとして、パーティションキーのみの方法と、パーティションキー+ソートキーでユニークにする方法があります。
前者を「ハッシュキーテーブル」、後者を「複合キーテーブル」と呼ぶことにします。

以下、参考にさせていただきました。(ありがとうございました)

 コンセプトから学ぶAmazon DynamoDB【インデックス俯瞰篇】
 【詳解】JavascriptでDynamoDBを操作する
 DynamoDB での Node.js の開始方法
  Class: AWS.DynamoDB.DocumentClient

準備

Node.jsのソースコードのどこかに、以下を記載しておきます。

index.js
constAWS=require("aws-sdk");AWS.config.update({region:"ap-northeast-1",});constdocClient=newAWS.DynamoDB.DocumentClient();

以降で、上記の変数docClientを使います。
それから、AWS Lambdaではなく自身のサーバ等で実行する場合は、以下と、aws configureでIAMの認証情報を設定しておきます。

npm install aws-sdk

ハッシュキーテーブル

プライマリキーがパーティションキーのみのハッシュキーテーブルを扱います。
こんな感じでテーブルを作成します。

テーブル名(tableName):Hashkey_Table
パーティションキー名:firstkey

image.png

登録

項目を登録します。SQLでいうところのInsertです。

varparams_put={TableName:tableName,Item:{firstkey:"firstvalue_1","attr":"Hello_1",},ConditionExpression:'attribute_not_exists(firstkey)',};result=awaitdocClient.put(params_put).promise();

Itemのところに、登録したい項目の値を指定します。スキーマレスなので、任意の値(attr=”Hello_1”)も指定しています。ただし、プライマリキーは必ず指定する必要があります。

以下の指定はオプションです。指定した場合は、プライマリキーが同じ項目が登録されていた場合はエラー(throwが発生)となります。指定しなかった場合は、置き換わります。
 ConditionExpression: "attribute_not_exists(firstkey)"

取得

プライマリキーを指定して、項目を取得します。
SQLと違って、1件のみ取得します。

varparams_get={TableName:tableName,Key:{firstkey:"firstvalue_1"}};result=awaitdocClient.get(params_get).promise();if(result.Item){console.log(JSON.stringify(result.Item));}else{// 見つからない場合はundefinedconsole.log('Not found');}

更新

SQLでいうところのUPDATEです。
登録時に一緒に指定したattrの値を変更します。

varparams_update={TableName:tableName,Key:{firstkey:"firstvalue_1"},ExpressionAttributeNames:{'#attr':'attr'},ExpressionAttributeValues:{':attrValue':'Hello_1_Update_1'},UpdateExpression:'SET #attr = :attrValue',ConditionExpression:"attribute_exists(firstkey)",ReturnValues:"ALL_NEW"};result=awaitdocClient.update(params_update).promise();

以下の指定はオプションです。指定した場合は、もし更新対象の項目が存在しなかった場合はエラー(throwが発生)となります。指定しなかった場合で、もし更新対象が項目が存在しなかった場合は、新規に登録されます。
 ConditionExpression: "attribute_exists(firstkey)"

以下もオプションです。指定すると、更新した項目の全体の値が返ってきます。
 ReturnValues:"ALL_NEW"

削除

指定したプライマリキーに合致する項目を削除します。

varparams_delete={TableName:tableName,Key:{firstkey:"firstvalue_1"},//      ConditionExpression: 'attribute_exists(firstkey)',};result=awaitdocClient.delete(params_delete).promise();

以下の指定はオプションです。もし指定した場合は、指定したプライマリキーに合致した項目がなかった場合にエラー(throw)となります。
 ConditionExpression: "attribute_exists(firstkey)"

一括取得

先ほどの取得は、1件のプライマリキーを指定して、合致する1件の項目を取得しました。
今度は、複数のプライマリキーを指定して、合致する複数の項目を取得します。

varparams_batchget={RequestItems:{}};params_batchget.RequestItems[tableName]={Keys:[{firstkey:"firstvalue_2"},{firstkey:"firstvalue_3"},]};result=awaitdocClient.batchGet(params_batchget).promise();if(Object.keys(result.UnprocessedKeys).length>0)console.log('in process yet');for(vari=0;i<result.Responses[tableName].length;i++){console.log(i,JSON.stringify(result.Responses[tableName][i]));}

レスポンスのresult.Responses[tableName]に合致した項目が配列で格納されています。
もし、result.UnprocessedKeysに何か値が入っていると、全部の検索は完了していないため、再度取得をしないといけないようです。

複合キーテーブル

今度は、プライマリキーがパーティションキー+ソートキーの複合キーテーブルを扱います。
こんな感じでテーブルを作成します。

テーブル名(tableName):Complexkey_Table
パーティションキー名:firstkey
ソートキー名:secondkey

こんな感じで作ります。

image.png

登録

項目を登録します。

varparams_put={TableName:tableName,Item:{firstkey:"firstvalue_1",secondkey:"secondvalue_1","attr":"Hello_1",},ConditionExpression:'attribute_not_exists(firstkey)',};result=awaitdocClient.put(params_put).promise();

ハッシュキーテーブルと同様、Itemに項目の値を指定します。
プライマリキーとソートキーでユニークとなるため、両方を指定する必要があります。

取得

項目を取得します。
1つの項目が返る前提ですので、ユニークに特定するため、プライマリキーとソートキーの両方を指定します。

varparams_get={TableName:tableName,Key:{firstkey:"firstvalue_1",secondkey:"secondvalue_1",}};result=awaitdocClient.get(params_get).promise();if(result.Item){console.log(JSON.stringify(result.Item));}else{// 見つからない場合はundefinedconsole.log('Not found');}

一括取得

複数のプライマリキーを指定して、合致する複数の項目を一度に取得します。

varparams_batchget={RequestItems:{}};params_batchget.RequestItems[tableName]={Keys:[{firstkey:'firstvalue_1',secondkey:'secondvalue_1',},{firstkey:'firstvalue_2',secondkey:"secondvalue_2",},{firstkey:"firstvalue_3",secondkey:'secondvalue_3',},],};varresult=awaitdocClient.batchGet(params_batchget).promise();if(Object.keys(result.UnprocessedKeys).length>0)console.log('in process yet');for(vari=0;i<result.Responses[tableName].length;i++){console.log(i,JSON.stringify(result.Responses[tableName][i]));}

更新

項目の値を更新します。
ハッシュキーテーブルの時とほぼ同じです。
プライマリキーとして、パーティションキーとソートキーの両方を指定しています。

varparams_update={TableName:tableName,Key:{firstkey:"firstvalue_1",secondkey:"secondvalue_1",},ExpressionAttributeNames:{'#attr':'attr'},ExpressionAttributeValues:{':attrValue':'Hello_1_Update_1'},UpdateExpression:'SET #attr = :attrValue',ConditionExpression:'attribute_exists(firstkey)',ReturnValues:"ALL_NEW"};result=awaitdocClient.update(params_update).promise();

削除

項目の削除です。
ハッシュキーテーブルの時とほぼ同じです。
プライマリキーとして、パーティションキーとソートキーの両方を指定しています。

varparams_delete={TableName:tableName,Key:{firstkey:'firstvalue_1',secondkey:'secondvalue_1',},//      ConditionExpression: 'attribute_exists(firstkey)',};result=awaitdocClient.delete(params_delete).promise();

検索

条件に合致する項目を検索します。
取得と違って、複数の項目が返ってきます。

まず最初が、パーティションキーが合致する項目の取得です。
複合キーテーブルでは、パーティションキーとソートキーでユニークとするため、同じパーティションキーで、値の異なる複数のソートキーを登録することができます。
よって、パーティションキーのみを条件に指定した場合は、同じパーティションキーの複数の項目を取得できます。

varparams_query={TableName:tableName,ExpressionAttributeNames:{'#firstkey':'firstkey',},ExpressionAttributeValues:{':firstValue':"firstvalue_1",},KeyConditionExpression:'#firstkey = :firstValue',};result=awaitdocClient.query(params_query).promise();for(vari=0;i<result.Count;i++){console.log(i,JSON.stringify(result.Items[i]));}

result.Countには取得した項目の件数、result.Itemsに取得した項目が配列で取得できます。

次は、ソートキーにさらに条件を付けて絞り込んで検索します。

varparams_query={TableName:tableName,ExpressionAttributeNames:{'#firstkey':'firstkey','#secondkey':'secondkey',},ExpressionAttributeValues:{':firstValue':'firstvalue_1',':secondValue':'secondvalue_1_',},KeyConditionExpression:'#firstkey = :firstValue AND begins_with(#secondkey, :secondValue)',};result=awaitdocClient.query(params_query).promise();for(vari=0;i<result.Count;i++){console.log(i,JSON.stringify(result.Items[i]));}

上記では1例として、以下を指定しています。
 begins_with(#secondkey, :secondValue)

これは、ソートキーが、指定した値secondvalue_1_で始まる文字列の場合に合致したとみなされます。

(参考) DynamoDB でのクエリの操作
 https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Query.html

終わりに

DynamoDBには、セカンダリインデックスという機能がありますが、また今度。

以上


Viewing all articles
Browse latest Browse all 9140

Trending Articles