AWS

【DynamoDB】AWS SDK を使用した複数項目の取得

今回は項目の取得を行います。

getItem のような単一項目の取得ではなく、複数の項目を取得をします。
単一項目の取得については以下を参照して下さい。

クエリー

複数項目を取得するには query メソッドを使用します。
query はテーブルのパーティションキーを指定します。ソートキー のみの指定はできません。ソートキーのみを指定して実行するとエラーになります。
セカンダリインデックスへのクエリー実施も同様です。

テーブルの内容

Musicsというテーブルに対してクエリーを実行します。
テーブルの内容は以下の通りです。

artist: パーテションキー
title: ソートキー

テーブルへのクエリー

実行

パーティションキーでクエリーを実行します。artist が “YUI” である項目を取得します。

Lambda関数の内容は以下の通りです。

const DynamoDbSetter = require("./DynamoDbSetter");
 
module.exports = class DynamoDbOperator extends DynamoDbSetter{
 
    async exec(event) {
 
        let artist = event.artist;

        // 実行内容
        let params = {
            TableName : "Musics",
            KeyConditionExpression: '#artist = :artistValue',
            ExpressionAttributeNames: {
                '#artist': 'artist',
            },
            ExpressionAttributeValues: {
                ':artistValue': {'S': artist},
            }
        };
  
        // 実行
        return await this.dynamodb.query(params).promise();

    }

}

Lambda関数実行コマンドは以下の通りです。AWS CLI から実行しています。

aws lambda invoke --function-name DynamoDbFunction --payload $(echo '{ "artist": "YUI"}' | base64) outputfile.txt

実行内容の説明

KeyConditionExpression

クエリーを実行する時のキーを指定します。
“#~” は キー名のプレースホルダーになります。
“:~” は 値のプレースホルダーになります。
プレースホルダーを使用するのは、キー名、値にDynamoDBの予約語が使用される場合に正常に動作しないからです。
予約語と被らなければプレースホルダーを使用する必要はありませんが、プレースホルダーを使用する方がエラーがなく実行できるのでプレースホルダーを使いましょう。

DynamoDBの予約語については以下を参照して下さい。

ExpressionAttributeNames

“#~” で指定した実際のキー名になります。

ExpressionAttributeValues

“:~” で指定した実際の値になります。

結果

{
    "Items": [
        {
            "year": {
                "N": "2021"
            },
            "artist": {
                "S": "YUI"
            },
            "sngsCnt": {
                "N": "18"
            },
            "genre": {
                "S": "POP"
            },
            "title": {
                "S": "GREEN GARDEN POP"
            }
        },
        {
            "year": {
                "N": "2012"
            },
            "artist": {
                "S": "YUI"
            },
            "sngsCnt": {
                "N": "18"
            },
            "genre": {
                "S": "POP"
            },
            "title": {
                "S": "ORANGE GARDEN POP"
            }
        }
    ],
    "Count": 2,
    "ScannedCount": 2
}

グローバルセカンダリインデックスへのクエリー

Musicsテーブルをベーステーブルとした genre_year_index というグローバルセカンダリインデックスに対してクエリーを実行します。

セカンダリインデックスの作成

グローバルセカンダリインデックスを作成します。
グローバルセカンダリインデックスの作成については以下を参照して下さい。

以下を実行し、グローバルセカンダリインデックスを作成します。

const DynamoDbSetter = require("./DynamoDbSetter");
 
module.exports = class DynamoDbOperator extends DynamoDbSetter{
 
    async exec(event) {
 
        // 実行内容
        let params = {
            TableName : "Musics",
            AttributeDefinitions: [
                { AttributeName: "genre", AttributeType: "S" },
                { AttributeName: "year", AttributeType: "N" },
            ],
            GlobalSecondaryIndexUpdates: [
                {
                    Create: {
                        IndexName: "genre_year_index", 
                        KeySchema: [
                            { AttributeName: "genre", KeyType: "HASH"},  //Partition key
                            { AttributeName: "year", KeyType: "RANGE" }  //Sort key
                        ],
                        Projection: {
                            ProjectionType: "INCLUDE",
                            NonKeyAttributes: ["sngsCnt"]
                        },
                        ProvisionedThroughput: {
                            ReadCapacityUnits: 10, 
                            WriteCapacityUnits: 10
                        }
                    }
                },
            ],
        };
    
        // 実行
        return await this.dynamodb.updateTable(params).promise();

    }

}

グローバルセカンダリインデックスのプライマリキーは以下の通りです。

genre: パーテションキー
year: ソートキー

パーテションキーのみを指定したクエリーの実行

実行

パーテションキーでクエリーを実行します。genre が “Lock” である項目を取得します。
Lambda関数の内容は以下の通りです。

const DynamoDbSetter = require("./DynamoDbSetter");
 
module.exports = class DynamoDbOperator extends DynamoDbSetter{
 
    async exec(event) {
 
        let genre = event.genre;
        
        // 実行内容
        let params = {
            TableName : "Musics",
            IndexName: 'genre_year_index',
            KeyConditionExpression: '#genre = :genreValue',
            ExpressionAttributeNames: {
                '#genre': 'genre',
            },
            ExpressionAttributeValues: {
                ':genreValue': {'S': genre},
            }
        };
  
        // 実行
        return await this.dynamodb.query(params).promise();

    }

}

Lambda関数実行コマンドは以下の通りです。AWS CLI から実行しています。

aws lambda invoke --function-name DynamoDbFunction --payload $(echo '{ "genre": "Lock"}' | base64) outputfile.txt

結果

{
    "Items": [
        {
            "year": {
                "N": "1991"
            },
            "artist": {
                "S": "B'z"
            },
            "genre": {
                "S": "Lock"
            },
            "title": {
                "S": "IN THE LIFE"
            }
        },
        {
            "year": {
                "N": "2002"
            },
            "artist": {
                "S": "B'z"
            },
            "sngsCnt": {
                "N": "12"
            },
            "genre": {
                "S": "Lock"
            },
            "title": {
                "S": "GREEN"
            }
        }
    ],
    "Count": 2,
    "ScannedCount": 2
}

パーテションキーとソートキーを指定したクエリーの実行

実行

パーテションキーとソートキーでクエリーを実行します。genre が “POP” で year が “2021” である項目を取得します。
Lambda関数の内容は以下の通りです。

const DynamoDbSetter = require("./DynamoDbSetter");
 
module.exports = class DynamoDbOperator extends DynamoDbSetter{
 
    async exec(event) {
 
        let genre = event.genre;
        let year = event.year;
        
        // 実行内容
        let params = {
            TableName : "Musics",
            IndexName: 'genre_year_index',
            KeyConditionExpression: '#genre = :genreValue AND #year = :yearValue',
            ExpressionAttributeNames: {
                '#genre': 'genre',
                '#year': 'year',
            },
            ExpressionAttributeValues: {
                ':genreValue': {'S': genre},
                ':yearValue': {'N': String(year)},
            }
        };
  
        // 実行
        return await this.dynamodb.query(params).promise();
 
    }
 
}

“year” は数値型ですが、文字列で値を指定します。

Lambda関数実行コマンドは以下の通りです。AWS CLI から実行しています。

aws lambda invoke --function-name DynamoDbFunction --payload $(echo '{ "genre": "POP", "year": 2021}' | base64) outputfile.txt

結果

{
    "Items": [
        {
            "year": {
                "N": "2021"
            },
            "artist": {
                "S": "YUI"
            },
            "sngsCnt": {
                "N": "18"
            },
            "genre": {
                "S": "POP"
            },
            "title": {
                "S": "GREEN GARDEN POP"
            }
        }
    ],
    "Count": 1,
    "ScannedCount": 1
}

最後に

次回はクエリーで項目を取得する際に条件を指定して取得できる事を確認します。

© DeNnie.Lab All Rights Reserved.