Lambda(Node.js)からDynamoDBのテーブルを検索する

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
}

参考サイト

ERROR: The request could not be satisfied

コメント

タイトルとURLをコピーしました