AWS.DynamoDB.DocumentClient を使用して DynamoDB からデータを取得する方法を紹介します。
今回は主にデータを取得する際によく使うオプションについて紹介していきます。
動作環境は AWS Lambda Node.js 10.X で確認しています。
条件に一致するデータの件数を取得
次のテーブルから”マイケルジャクソン”の曲が何個あるのか取得します。
テーブル名:Music
プライマリパーティションキー:Artist プライマリソートキー:SongTitle
コード
var AWS = require('aws-sdk'); var documentClient = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10', region: "ap-northeast-1" }); exports.handler = async(event) => { var params = { TableName: 'Music', KeyConditionExpression: 'Artist = :Artist', ExpressionAttributeValues: { ':Artist': 'マイケルジャクソン' }, Select: 'COUNT' }; var result; try { result = await documentClient.query(params).promise(); } catch (e) { result = e; } return { statusCode: 200, body: result, }; };
結果
{ "Count": 2, "ScannedCount": 2 }
「Select: 'COUNT'」パラメータを指定するとデータの件数を取得できます。
今回は"query"メソッドを使用していますが"scan"メソッドでも使用できます。
取得する項目を指定
次のテーブルから曲名と発売日を取得します。
テーブル名:Music
コード
var AWS = require('aws-sdk'); var documentClient = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10', region: "ap-northeast-1" }); exports.handler = async(event) => { var params = { TableName: 'Music', ProjectionExpression: 'SongTitle, ReleaseDate' }; var result; try { result = await documentClient.scan(params).promise(); } catch (e) { result = e; } return { statusCode: 200, body: result, }; };
結果
{ "Items": [ { "ReleaseDate": "1984/11/12", "SongTitle": "ライクアヴァージン" }, { "ReleaseDate": "2007/02/07", "SongTitle": "ガールフレンド" }, { "ReleaseDate": "1982/12/01", "SongTitle": "スリラー" }, { "ReleaseDate": "1983/02/03", "SongTitle": "ビートイット" } ], "Count": 4, "ScannedCount": 4 }
"ProjectionExpression"で取得する項目を指定します。SQLの"Select"に近い意味合いです。
取得する項目が多くなるとデータを取得するのにかかる時間が増えるどころか、
AWSのデータ転送料金もかかるため、基本的にどのパターンでも"ProjectionExpression"は指定しておくと良いと思います。
プライマリパーティションキーやプライマリソートキー以外で検索
次のテーブルから"マイケルジャクソン"の"1983年以前"に発売した歌を取得します。
テーブル名:Music
プライマリパーティションキー:Artist プライマリソートキー:SongTitle
管理コンソールから"Artist"と"ReleaseDate"にインデックスを作成します。
インデックス名:Artist-ReleaseDate-index
パーティションキー:Artist
ソートキー:ReleaseDate
コード
var AWS = require('aws-sdk'); var documentClient = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10', region: "ap-northeast-1" }); exports.handler = async(event) => { var params = { TableName: 'Music', KeyConditionExpression: 'Artist = :Artist AND ReleaseDate <= :ReleaseDate', ExpressionAttributeValues: { ':Artist': 'マイケルジャクソン', ':ReleaseDate': '1982/12/31' }, IndexName: 'Artist-ReleaseDate-index' }; var result; try { result = await documentClient.query(params).promise(); } catch (e) { result = e; } return { statusCode: 200, body: result, }; };
結果
{ "Items": [ { "Artist": "マイケルジャクソン", "SongTitle": "スリラー", "ReleaseDate": "1982/12/01" } ], "Count": 1, "ScannedCount": 1 }
インデックスを作成し"IndexName"に指定することでテーブルのキーを増やすことができます。
"scan"と"FilterExpression"で絞り込んでも同じようなことはできますが、インデックスを使った方が高速でデータ転送料金も抑えられます。
上位N個を取得
次のテーブルから"マイケルジャクソン"の曲を1つ取得します。
テーブル名:Music
プライマリパーティションキー:Artist プライマリソートキー:SongTitle
コード
var AWS = require('aws-sdk'); var documentClient = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10', region: "ap-northeast-1" }); exports.handler = async(event) => { var params = { TableName: 'Music', KeyConditionExpression: 'Artist = :Artist', ExpressionAttributeValues: { ':Artist': 'マイケルジャクソン' }, Limit: '1' }; var result; try { result = await documentClient.query(params).promise(); } catch (e) { result = e; } return { statusCode: 200, body: result, }; };
結果
{ "Items": [ { "Artist": "マイケルジャクソン", "ReleaseDate": "1982/12/01", "SongTitle": "スリラー" } ], "Count": 1, "ScannedCount": 1, "LastEvaluatedKey": { "Artist": "マイケルジャクソン", "SongTitle": "スリラー" } }
"Limit"を指定すると最大何件まで取得するかを指定できます。
取得したデータの続きがある場合は結果に"LastEvaluatedKey"が入ってくるので
この値を"ExpressionAttributeValues"に設定してもう一度実行することで続きから取得する事ができます。