LoginSignup
0
1

More than 1 year has passed since last update.

dynamoDBのupdate時、配列やオブジェクトの値に対して条件をつけて書き込み(ConditionExpression)したい

Last updated at Posted at 2021-10-19

dynamoDBの条件付き書き込みで、オブジェクト内の特定要素に対して制約を付ける方法をメモする

dynamoDBのConditionExpressionについて

dynamoDBのあるレコードを更新する場合に下記のように条件をつけることができる

  • レコードに特定キーが存在する場合のみput
  • レコードの特定キー値がある値の場合のみput

例:productTable

{
 name:"apple", // hash key
 price: 300,
 isBought: false
}

実行コード(lambda)


const AWS = require('aws-sdk');
const dynamoDB = new AWS.DynamoDB.DocumentClient();

exports.handler = async(event, context) => {
     const params = {
        TableName: "productTable",
        Key:{
            name: "apple"
        },
        ExpressionAttributeNames: {
            '#isBought': 'isBought'
        },
        ExpressionAttributeValues: {
            ':isBought': true,
            ':expectIsBought': false
        },
        UpdateExpression: 'SET #isBought = :isBought',
        ConditionExpression: '#isBought = :expectIsBought' // まだ購入されていない商品である場合のみ更新する
    };
    const data = await dynamoDB.update(params).promise();
}

ConditionExpressionの条件をオブジェクトの1要素にしたい場合

例:productTable

{
 name:"apple", // hash key
 price: 300,
 info: {
  reservation: "Aさん",
  isBought: false
 }

}

実行コード(lambda)


const AWS = require('aws-sdk');
const dynamoDB = new AWS.DynamoDB.DocumentClient();

exports.handler = async(event, context) => {
     const params = {
        TableName: "productTable",
        Key:{
            name: "apple"
        },
        ExpressionAttributeNames: {
            '#info': 'info'
            '#reservation': 'reservation'
            '#isBought': 'isBought'
        },
        ExpressionAttributeValues: {
            ':isBought': true,
            ':expectReservation': 'Aさん'
            ':expectIsBought': false
        },
        UpdateExpression: 'SET #info.#isBought = :isBought',
        ConditionExpression: '#info.#reservation = :expectReservation AND #info.#isBought = :expectIsBought' // Aさんが予約し、まだ購入されていない商品である場合のみ更新する
    };
    const data = await dynamoDB.update(params).promise();
}

オブジェクトの要素参照は#key1.#key2のような形で参照できる

ConditionExpressionの条件を配列の1要素にしたい場合

例:productTable

{
 name:"apple", // hash key
 price: 300,
 stocks: [true, false]

}

実行コード(lambda)


const AWS = require('aws-sdk');
const dynamoDB = new AWS.DynamoDB.DocumentClient();

exports.handler = async(event, context) => {
     const index = 1
     const params = {
        TableName: "productTable",
        Key:{
            name: "apple"
        },
        ExpressionAttributeNames: {
            '#stocks': 'stocks'
        },
        ExpressionAttributeValues: {
            ':isBought': true,
            ':expectIsBought': false
        },
        UpdateExpression: `SET #stocks[${index}] = :isBought`, //
        ConditionExpression: `#stocks[${index}]= :expectIsBought` // 指定した配列番号のストックがまだ購入されていない場合のみ更新する
    };
    const data = await dynamoDB.update(params).promise();
}

配列要素は#key1[1]のように参照できる。conditionExpressionは文字列型なので、配列番号は文字列への埋め込みが必要

ConditionExpressionの条件を配列内オブジェクトの1要素にしたい場合

例:productTable

{
 name:"apple", // hash key
 price: 300,
 stocks: [
  {reservation: 'Aさん', isBought: true},
  {reservation: 'Bさん', isBought: false}
 ]

}

実行コード(lambda)


const AWS = require('aws-sdk');
const dynamoDB = new AWS.DynamoDB.DocumentClient();

exports.handler = async(event, context) => {
     const index = 1
     const reservation = 'Bさん'
     const params = {
        TableName: "productTable",
        Key:{
            name: "apple"
        },
        ExpressionAttributeNames: {
            '#stocks': 'stocks',
            '#isBought': 'isBought',
            '#reservation': 'reservation'
        },
        ExpressionAttributeValues: {
            ':isBought': true,
            ':expectIsBought': false,
            ':expectReservation': reservation
        },
        UpdateExpression: `SET #stocks[${index}].#isBought = :isBought`, 
        ConditionExpression: `#stocks[${index}].#isBought = :expectIsBought AND #stocks[${index}].#reservation = :expectReservation` // 指定した配列番号のストックがまだ購入されていない場合かつBさん予約の商品である場合のみ更新する
    };
    const data = await dynamoDB.update(params).promise();
}

0
1
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
0
1