1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DynamoDB GSIに対してLambdaからクエリを実行し特定の属性値を取得する

Last updated at Posted at 2024-11-06

はじめに

本記事ではDynamoDBのGSI(Global Secondary Index)を作成し、Lambdaからクエリを実行する処理を実装していきます。

ゴール

DynamoDBのGSIに対してLambdaからクエリを実行し、パーティションキーとソートキーの条件に一致する項目から、特定の属性値のみを取得します。
下記のようなGSIを作成し、user1user_status:activeを取得する処理を実装します。

▼GSI例

userId(パーティションキー) timestamp(ソートキー) user_status
user1 2024-11-07 active
user2 2024-11-08 active

作るもの

  • DynamoDBのテーブル:1つ
    • GSI:1つ
  • Lambda:1つ

書かない事

IAMの権限については本記事では記載しておりません。

1. DynamoDBのテーブルを作成

次の5つの属性を持つテーブルを作成します。

  • id (パーティションキー)
  • userId
  • timestamp
  • user_status
  • category

image.png

2. GSIを作成

次の3つの属性を持つインデックスを作成します。

  • userId (GSIのパーティションキー)
  • timestamp (GSIのソートキー)
  • user_status (取得したい属性、Include > 属性名で選択)

image.png

image.png

次の図のようにインデックスタブから想定通りGSIを作成できている事を確認できました。

image.png

3. Lambdaを作成

import json
import boto3
from boto3.dynamodb.conditions import Key

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('test-1107-db')

def lambda_handler(event, context):
    body = json.loads(event['body'])
    user_id = body['userId']
    specific_date = body['timestamp']
    
    # GSIを使用したクエリ
    response = table.query(
        # インデックス名
        IndexName='userId-timestamp-index',
        # クエリ条件:userIdとtimestampが一致する項目を検索
        KeyConditionExpression=Key('userId').eq(user_id) & Key('timestamp').eq(specific_date),
        # user_statusのみを取得
        ProjectionExpression='user_status'
    )
    
    return {
        'statusCode': 200,
        'body': json.dumps(response['Items'])
    }

クエリ部分についてはAmazon DynamoDB > デベロッパーガイド記載の下記の部分を参考にしています。

リソースインターフェイスを使った同じクエリ操作を短くして簡略化できます。
import boto3
from boto3.dynamodb.conditions import Key, Attr
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('YourTableName')
response = table.query(
KeyConditionExpression=Key('pk').eq('id#1') & Key('sk').begins_with('cart#'),
FilterExpression=Attr('name').eq('SomeName')
)
引用:デベロッパーガイド

属性が値と等しいことを確認するために boto3.dynamodb.conditions.Key を使用しています。今回使用したのは等価比較を行うための eq です。

4. LambdaからGSIへのクエリを実行

test eventを作成してLabmdaを実行してみます。実行するイベントの内容は次の通りです。

test event
{
  "body": "{\"userId\": \"user1\", \"timestamp\": \"2024-11-07\"}"
}

GSIに保存している次の項目の user_status を取得する想定です。

項目
id (文字列):1
timestamp:2024-11-07
user_status:active
userId:user1

Lambdaを実行すると200で正常に下記のレスポンスを取得できました。
想定通り userId:user1user_status:active のデータを取得できていることが確認できます。

response
{
  "statusCode": 200,
  "body": "[{\"user_status\": \"active\"}]"
}

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?