ねむみの極み

DynamoDBのデータをLambdaでクエリする方法(AWS SDK for JS3がバンドルされているNode.jsを使用)

こんにちは。
この記事はTechCommit Advent Calendar 2023 3日目の記事です。

別記事ではPartiQLを使用してDynamoDBのデータをクエリする方法を紹介しましたが、本記事ではLambda(Node.js)でクエリする方法を解説します。

※本記事では、DynamoDBとは何ぞや?については触れません。
初心者の方は、Amazon DynamoDBとは何かをわかりやすく図解、どう使う?テーブル設計の方法とはなどを読んでみるとよいと思います。

方法

前回と同じデータを例に説明します。

コードは以下の通りです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//必要なライブラリをインポート
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { QueryCommand, DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";

//Dynamoオブジェクトを生成
const client = new DynamoDBClient();
const docClient = DynamoDBDocumentClient.from(client);

export const handler = async () => {

  try{

    //クエリを作成
    const queryCommand = new QueryCommand({

      //テーブル名を指定
      TableName: "test",
      
      //検索値
      ExpressionAttributeValues:{
        ":prefecture":"東京都",
        ":age":30,
        ":date":"2023-01"
      },

      //検索条件(パーティションキーとソートキー)
      KeyConditionExpression:
        "prefecture = :prefecture AND age > :age",
      
      //検索条件(上記以外のカラム)
      FilterExpression:
        "begins_with(#date,:date)",
      
      //検索条件にDynamoDBの予約語が入っている場合の処理
      ExpressionAttributeNames:{
        "#date":"date"
      },
      
    });

    //クエリを実行
    const response = await client.send(command);

  }catch(e){
    console.log("エラー:" + e);
  }
  
};

上記のコードを実行すると、以下のjsonが返ってきます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
    {
      prefecture: '東京都',
      username: '鈴木',
      date: '2023-01-01 11:23:33',
      age: 31
    },
    {
      prefecture: '東京都',
      username: '芦田',
      date: '2023-01-24 14:56:34',
      age: 40
    },
    {
      prefecture: '東京都',
      username: '谷本',
      date: '2023-01-11 11:23:33',
      age: 41
    }

コードの解説

KeyConditionExpressionFilterExpressionが、SQLでいうwhere句にあたります。
Keyの方ではパーティションキー(必須)とソートキー(任意)を指定します。
Filterの方は、パーティションキーとソートキー以外のカラムを検索に使いたい時に使用します。

検索条件は、prefecture = "東京都"のように直接指定せず、プレースホルダを使用します。
prefecture = :prefectureとしておき、ExpressionAttributeValues":prefecture":"東京都"とします。

検索に使いたいカラム名がDynamoDBの予約語だった場合、検索条件の中で直接指定することができません。今回の場合、「date」の部分が該当します。

通常であればbegins_with(date,:date)で良いのですが、これではエラーになります。
そのため、検索条件内では#を付けてbegins_with(#date,:date)とし、
ExpressionAttributeNamesの中で"#date":"date"のようにカラムを指定します。

おわりに

なんたらExpression、なんたらAttributeがたくさん出てきて最初は大変ですが、最小構成から少しずつ試すと分かってくると思います。

誰かの参考になれば幸いです。

参考

JavaScript (v3) 用の SDK を使用した DynamoDB の例
QueryCommand
Filter expressions for the Query operation