Lambda(Node.js)からDynamoDBのテーブルを検索する
Lambda(Node.js)からDynamoDBのテーブルを検索する
Lambda(Node.js)からDynamoDBのテーブルを検索するには3通りメソッドがあります。
getとqueryとscanです。getは1件、queryは複数件返ってくることを想定するため、渡す引数が異なります。
また、getしても0件だった場合、空のオブジェクト({})が返ります。
queryして0件だった場合、空の配列([])が返ります。
この違いがあるので、0件チェックするロジックが異なります。
queryの場合
if (data.length === 0)
getの場合
if (Object.Keys(data).length === 0)
以下、getの場合のパラメータです。
TableName | テーブル名 |
Key | パーティションキーとソートキーのオブジェクト型 |
AWS SDK for JavaScript v2
以下、記述例です。
var AWS = require('aws-sdk'); var dynamo = new AWS.DynamoDB.DocumentClient(); exports.handler = (event, context, callback) => { const params = { TableName: 'A_TBL', Key: {'hashkey':'1', 'sortkey':'1'} } return dynamo.get(params, function(err, data) { if (err) { context.fail(err); // エラー時 } else { context.succeed(data); // 正常時 } }); callback(null); };
結果は以下の通りになります。戻り値が1件ですが、オブジェクトで囲まれているのがわかります。
{ "Item": { "hashkey": "1", "sortkey": "1" } }
上記構成になるため、data.Itemで初めて取得したいオブジェクトが取得できます。
getは0件の場合は空オブジェクトが返りますが、その際にdata.Itemとするとundefinedになりますので注意が必要です。
次にqueryのパラメータについてです。
TableName | テーブル名 |
IndexName | インデックス名(任意) |
ExpressionAttributeNames | プレースホルダ指定 例){‘#a’: ‘year’} |
ExpressionAttributeValues | プレースホルダ指定 例){‘:value’: ‘1’} |
KeyConditionExpression | 検索条件 例)#id = :value |
以下、例です。
const AWS = require('aws-sdk'); const dynamo = new AWS.DynamoDB.DocumentClient(); const params = { TableName: 'sample', KeyConditionExpression: ' #id = :value ', ExpressionAttributeNames: { '#id': 'id' }, ExpressionAttributeValues: { ':value': '1' } }; exports.handler = (event, context, callback) => { dynamo.query(params, function(err, data) { if (err) { context.fail(err); // エラー時 } else { context.succeed(data); // 正常時 } }); };
結果は以下のようになります。
{ "Items": [ { "id": "1", "sortkey": "1", "name": "jiro" } ], "Count": 1, "ScannedCount": 1 }
queryの場合は、data.Itemsで配列にオブジェクトが入った値が取得できます。データが2件の場合はオブジェクトも2つ入った配列となります。
queryの結果が0件の場合はdata.Itemsの戻り値は[]になります。
データをソートする
getは1件なのでソートできませんが、scan,queryはデータをソートキーでソートすることができます。
ScanIndexForward: true // デフォルト(昇順)
falseにすると降順になります。
以下は降順でソートする例です。
const AWS = require("aws-sdk"); const dynamoDB = new AWS.DynamoDB.DocumentClient({ region: "us-east-1" // DynamoDBのリージョン }); exports.handler = (event, context, callback) => { const params = { TableName: 'system_log', KeyConditionExpression: '#key = :str', ExpressionAttributeNames: { '#key': 'pid' }, ExpressionAttributeValues: { ':str': '001' }, ScanIndexForward: false // これで降順でソート } dynamoDB.query(params).promise().then((data) => { console.log(data); context.succeed(data); }).catch((err) => { console.log(err); callback(err); }); }
結果は以下のように降順で取得できていることがわかります。
{ "Items": [ { "pid": "001", "pdate": "20170104" }, { "pid": "001", "pdate": "20170103" }, { "pid": "001", "pdate": "20170101" } ], "Count": 3, "ScannedCount": 3 }
Limitでデータ件数を指定する
Limit:1
と指定することでqueryやscanで件数を指定することができます。Limit:0とするとエラーとなります。
以下、昇順にソートし、1件のみ取得する例です。
const AWS = require("aws-sdk"); const dynamoDB = new AWS.DynamoDB.DocumentClient({ region: "us-east-1" // DynamoDBのリージョン }); exports.handler = (event, context, callback) => { const params = { TableName: 'system_log', KeyConditionExpression: '#key = :str', ExpressionAttributeNames: { '#key': 'pid' }, ExpressionAttributeValues: { ':str': '001' }, ScanIndexForward: true, // これで昇順でソート Limit: 1 // 1件のみ取得 } dynamoDB.query(params).promise().then((data) => { console.log(data); context.succeed(data); }).catch((err) => { console.log(err); callback(err); }); }
結果は以下のように1件取得できます。
{ "Items": [ { "pid": "001", "pdate": "20170101" } ], "Count": 1, "ScannedCount": 1, "LastEvaluatedKey": { "pid": "001", "pdate": "20170101" } }
scanする
次は全件検索するscanをしてみます。テーブル名のみ指定します。
const AWS = require("aws-sdk"); const dynamoDB = new AWS.DynamoDB.DocumentClient({ region: "us-east-2" // DynamoDBのリージョン }); exports.handler = (event, context, callback) => { const params = { TableName: 'users' } dynamoDB.scan(params).promise().then((data) => { console.log(data); context.succeed(data); }).catch((err) => { console.log(err); callback(err); }); }
AWS SDK for JavaScript v3
v3での記述方法です。
import { DynamoDBClient, ScanCommand } from '@aws-sdk/client-dynamodb' export const handler = async(event) => { const client = new DynamoDBClient({ region: 'ap-northeast-1'}) const command = new ScanCommand({'TableName': 'users'}) const data = await client.send(command) console.log(data.Items) // ログ出力 const response = { statusCode: 200, body: JSON.stringify(data.Items) } return response }
参考サイト

KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES6),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^
コメント