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(ES20xx),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^


コメント