

# DynamoDB での項目と属性の操作
<a name="WorkingWithItems"></a>

Amazon DynamoDB では、*項目*は属性の集まりです。各属性には名前と値があります。属性値はスカラー型、セット型、ドキュメント型のいずれかです。詳細については、「[Amazon DynamoDB: 仕組み](HowItWorks.md)」を参照してください。

DynamoDB では、作成、読み込み、更新、および削除 (CRUD) の 4 つの基本的な操作機能を使用できます。これらの操作はすべてアトミックです。
+ `PutItem` — 項目を作成します。
+ `GetItem` — 項目を読み込みます。
+ `UpdateItem` — 項目を更新します。
+ `DeleteItem` — 項目を削除します。

これらの各オペレーションでは、作業対象の項目のプライマリキーを指定する必要があります。たとえば、`GetItem` を使用して項目を読み込むには、その項目のパーティションキーとソートキー (該当する場合) を指定する必要があります。

4 つの基本的な CRUD オペレーションに加えて、DynamoDB は以下も提供します。
+ `BatchGetItem` — 1 つ以上のテーブルから最大 100 個の項目を読み込みます。
+ `BatchWriteItem` — 1 つ以上のテーブルから最大 25 個の項目を作成または削除します。

これらのバッチ操作は、複数の CRUD オペレーションを単一のリクエストにまとめます。さらに、応答のレイテンシーを最小限に抑えるため、バッチオペレーションは項目を並列で読み書きします。

このセクションには、これらのオペレーションを使用する方法の説明、および、条件付き更新やアトミックカウンターなどの関連するトピックが含まれています。このセクションには、AWS SDK を使用するサンプルコードも含まれています。

**Topics**
+ [DynamoDB 項目のサイズと形式](CapacityUnitCalculations.md)
+ [項目の読み込み](#WorkingWithItems.ReadingData)
+ [項目を書き込みます](#WorkingWithItems.WritingData)
+ [戻り値](#WorkingWithItems.ReturnValues)
+ [バッチオペレーション](#WorkingWithItems.BatchOperations)
+ [アトミックカウンタ](#WorkingWithItems.AtomicCounters)
+ [条件付きの書き込み](#WorkingWithItems.ConditionalUpdate)
+ [DynamoDB での式の使用](Expressions.md)
+ [DynamoDB での Time to Live (TTL) の使用](TTL.md)
+ [DynamoDB のテーブルに対するクエリの実行](Query.md)
+ [DynamoDB でのテーブルのスキャン](Scan.md)
+ [PartiQL: Amazon DynamoDB 用の SQL 互換クエリ言語](ql-reference.md)
+ [項目の操作: Java](JavaDocumentAPIItemCRUD.md)
+ [項目の操作: .NET](LowLevelDotNetItemCRUD.md)

# DynamoDB 項目のサイズと形式
<a name="CapacityUnitCalculations"></a>

DynamoDB テーブルはプライマリキーを除いてスキーマレスです。そのため、テーブルの項目の属性、サイズ、データ型はすべて異なる場合があります。

項目の合計サイズは、属性名と属性値の文字列の長さの合計、および以下に説明するように該当するオーバーヘッドが追加されます。次のガイドラインを使用して属性サイズを予測することができます。
+ 文字列は、UTF-8 バイナリエンコードの Unicode です。文字列のサイズは、**(属性名の UTF-8 でエンコードされたバイト数) \$1 (UTF-8 でエンコードされたバイト数) です。
+ 数値は、有効桁数が最大 38 の可変長です。先頭と末尾の 0 は切り捨てられます。数値のおおよそのサイズは、**(属性名の UTF-8 でエンコードされたバイト数) \$1 (有効桁数 2 あたり 1 バイト) \$1 (1 バイト) です。
+ バイナリ値を DynamoDB に送信するには base64 形式でエンコードする必要がありますが、サイズの計算には値の実際のバイト長が使用されます。バイナリ属性のサイズは、**(属性名の UTF-8 でエンコードされたバイト数) \$1 (raw バイト数) です。
+ null 属性または Boolean 属性のサイズは、**(属性名の UTF-8 でエンコードされたバイト数) \$1 (1 バイト) です。
+ `List` 型または `Map` 型の属性は、その内容にかかわらず、余分な 3 バイトが必要です。`List` または `Map` のサイズは、**(属性名の UTF-8 でエンコードされたバイト数) \$1 (入れ子要素のサイズの合計) \$1 (3 バイト) です。空の `List` または `Map` のサイズは、**(属性名の UTF-8 でエンコードされたバイト数) \$1 (3 バイト) です。
+ `List` または `Map` の各要素には、余分な 1 バイトが必要です。

**注記**  
属性名は長いものよりも短いものにすることをお勧めします。これにより、必要なストレージの量を減らすことができ、使用する RCU/WCU の量を減らすこともできます。

ストレージの請求において、各項目には、有効にした機能に応じて、項目あたりのストレージオーバーヘッドが含まれます。
+ DynamoDB のすべての項目は、インデックス作成に 100 バイトのストレージオーバーヘッドを必要とします。
+ 一部の DynamoDB 機能 (グローバルテーブル、トランザクション、DynamoDB を使用した Kinesis Data Streams の変更データキャプチャ) では、これらの機能を有効にすることでシステムが作成した属性を考慮するために、追加のストレージオーバーヘッドが必要になります。例えば、グローバルテーブルでは、48 バイトのストレージオーバーヘッドがさらに必要になります。

## 項目の読み込み
<a name="WorkingWithItems.ReadingData"></a>

DynamoDB テーブルから項目を読み込むには、`GetItem` オペレーションを使用します。必要な項目のプライマリキーと共にテーブルの名前を指定する必要があります。

**Example**  
次の AWS CLI の例は、`ProductCatalog` テーブルから項目を読み込む方法を示しています。  

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}'
```

**注記**  
`GetItem` では、プライマリキーの一部だけではなく*全体*を指定する必要があります。たとえば、テーブルに複合プライマリキー (パーティションキーおよびソートキー) がある場合、パーティションキーおよびソートキーの値を指定する必要があります。

デフォルトでは、`GetItem` リクエストは結果的に整合性のある読み込みを行います。代わりに、`ConsistentRead` パラメータを使用して、強い整合性のある読み込みをリクエストできます。(これは、追加の読み込みキャパシティーユニットを消費しますが、項目の最新バージョンを返します)。

`GetItem` は、項目のすべての属性を返します。一部の属性のみが返されるように、*プロジェクション式*を使用できます。詳細については、「[DynamoDB でのプロジェクション式の使用](Expressions.ProjectionExpressions.md)」を参照してください。

`GetItem` で消費される読み込みキャパシティーユニットの数を返すには、`ReturnConsumedCapacity` パラメータを `TOTAL` に設定します。

**Example**  
次の AWS Command Line Interface (AWS CLI) の例は、オプションの `GetItem` パラメータを示しています。  

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --consistent-read \
    --projection-expression "Description, Price, RelatedItems" \
    --return-consumed-capacity TOTAL
```

## 項目を書き込みます
<a name="WorkingWithItems.WritingData"></a>

DynamoDB テーブルの項目を作成、更新、または削除するには、次のオペレーションのいずれかを使用します。
+ `PutItem`
+ `UpdateItem`
+ `DeleteItem`

これらの各オペレーションで、プライマリキーの一部の属性ではなくすべての属性を指定する必要があります。たとえば、テーブルに複合プライマリキー (パーティションキーおよびソートキー) がある場合、パーティションキーおよびソートキーの値を提供する必要があります。

これらのオペレーションのいずれかで消費される書き込みキャパシティーユニットの数を返すには、`ReturnConsumedCapacity` パラメータを次のいずれかに設定します。
+ `TOTAL` — 消費された書き込み容量単位の総数を返します。
+ `INDEXES` — 消費された書き込み容量単位の総数とともに、テーブルおよびオペレーションに影響を受けたセカンダリインデックスの小計を返します。
+ `NONE` — 書き込み容量の詳細は返されません。(これがデフォルトです)

### PutItem
<a name="WorkingWithItems.WritingData.PutItem"></a>

`PutItem` は新しい項目を作成します。同じキーを持つ項目がテーブルにすでに存在する場合は、新しい項目に置き換えられます。

**Example**  
`Thread` テーブルに新しい項目を書き込みます。`Thread` のプライマリキーは、`ForumName` (パーティションキー) と `Subject` (ソートキー) で構成されます。  

```
aws dynamodb put-item \
    --table-name Thread \
    --item file://item.json
```
`--item` の引数は、ファイル `item.json` に保存されます。  

```
{
    "ForumName": {"S": "Amazon DynamoDB"},
    "Subject": {"S": "New discussion thread"},
    "Message": {"S": "First post in this thread"},
    "LastPostedBy": {"S": "fred@example.com"},
    "LastPostDateTime": {"S": "201603190422"}
}
```

### UpdateItem
<a name="WorkingWithItems.WritingData.UpdateItem"></a>

指定されたキーを持つ項目が存在しない場合は、`UpdateItem` により新しい項目が作成されます。または、既存の項目の属性が変更されます。

*更新式*を使用して、変更する属性と新しい値を指定します。詳細については、「[DynamoDB での更新式の使用](Expressions.UpdateExpressions.md)」を参照してください。

更新式では、実際の値にプレースホルダーとして式の属性値を使用します。詳細については、「[DynamoDB での式属性値の使用](Expressions.ExpressionAttributeValues.md)」を参照してください。

**Example**  
`Thread` 項目のさまざまな属性を変更します。オプションの `ReturnValues` パラメータは、更新後に表示されるように項目を表示します。詳細については、「[戻り値](#WorkingWithItems.ReturnValues)」を参照してください。  

```
aws dynamodb update-item \
    --table-name Thread \
    --key file://key.json \
    --update-expression "SET Answered = :zero, Replies = :zero, LastPostedBy = :lastpostedby" \
    --expression-attribute-values file://expression-attribute-values.json \
    --return-values ALL_NEW
```

`--key` の引数は、ファイル `key.json` に保存されます。

```
{
    "ForumName": {"S": "Amazon DynamoDB"},
    "Subject": {"S": "New discussion thread"}
}
```

`--expression-attribute-values` の引数は、ファイル `expression-attribute-values.json` に保存されます。

```
{
    ":zero": {"N":"0"},
    ":lastpostedby": {"S":"barney@example.com"}
}
```

### DeleteItem
<a name="WorkingWithItems.WritingData.DeleteItem"></a>

`DeleteItem` は指定されたキーを持つ項目を削除します。

**Example**  
次の AWS CLI の例で、`Thread` 項目を削除する方法について説明します。  

```
aws dynamodb delete-item \
    --table-name Thread \
    --key file://key.json
```

## 戻り値
<a name="WorkingWithItems.ReturnValues"></a>

場合によっては、ある属性値を変更する前後にその属性値が表示されるように DynamoDB で返すこともできます。`PutItem`、`UpdateItem`、および `DeleteItem` オペレーションには、`ReturnValues` パラメータがあり、これを使用することで、属性の変更前後に、その属性値を返すことができます。

`ReturnValues` のデフォルトの値は `NONE` で、DynamoDB は変更された属性の情報を返しません。

以下は、DynamoDB API オペレーションごとに整理された `ReturnValues` のその他の有効な設定です。

### PutItem
<a name="WorkingWithItems.ReturnValues.PutItem"></a>
+ `ReturnValues`: `ALL_OLD`
  + 既存の項目に上書きする場合、`ALL_OLD` は上書きの前に表示されたように、項目全体を返します。
  + 存在しない項目を書き込んだ場合は、`ALL_OLD` による影響はありません。

### UpdateItem
<a name="WorkingWithItems.ReturnValues.UpdateItem"></a>

`UpdateItem` の最も一般的な使用方法は、既存の項目の更新です。ただし、`UpdateItem` は実際には*アップサート*を実行します。つまり、項目が存在しない場合は、自動的に作成します。
+ `ReturnValues`: `ALL_OLD`
  + 既存の項目を更新する場合、`ALL_OLD` は更新前に表示されたように、項目全体を返します。
  + 存在しない項目を更新 (アップサート) すると、`ALL_OLD` による影響はありません。
+ `ReturnValues`: `ALL_NEW`
  + 既存の項目を更新する場合、`ALL_NEW` は更新後に表示されるように、項目全体が返されます。
  + 存在しない項目を更新 (アップサート) すると、`ALL_NEW` は項目全体を返します。
+ `ReturnValues`: `UPDATED_OLD`
  + 既存の項目を更新した場合、`UPDATED_OLD` は、更新前に表示されたように、更新された属性だけを返します。
  + 存在しない項目を更新 (アップサート) すると、`UPDATED_OLD` による影響はありません。
+ `ReturnValues`: `UPDATED_NEW`
  + 既存の項目を更新した場合、`UPDATED_NEW` は、更新後に表示されるように、影響のある属性だけを返します。
  + 存在しない項目を更新 (アップサート) する場合、`UPDATED_NEW` は更新後に表示される、更新された属性だけを返します。

### DeleteItem
<a name="WorkingWithItems.ReturnValues.DeleteItem"></a>
+ `ReturnValues`: `ALL_OLD`
  + 既存の項目を削除すると、`ALL_OLD` は削除の前に表示されたように、項目全体を返します。
  + 存在しない項目を削除すると、`ALL_OLD` はデータを返しません。

## バッチオペレーション
<a name="WorkingWithItems.BatchOperations"></a>

複数の項目の読み込みや書き込みを必要とするアプリケーションのために、DynamoDB は `BatchGetItem` および `BatchWriteItem` オペレーションを提供します。これらのオペレーションを使用すると、アプリケーションから DynamoDB へのネットワークラウンドトリップの数を減らすことができます。さらに、DynamoDB は個別の読み込みまたは書き込みオペレーションを並行して実行します。同時実行またはスレッディングの管理をする必要がないので、アプリケーションにはこの並列処理が役立ちます。

バッチオペレーションは、基本的に複数の読み込みまたは書き込みリクエストをまとめます。たとえば、`BatchGetItem` リクエストに 5 つの項目が含まれている場合、DynamoDB によって 5 回の `GetItem` オペレーションが実行されます。同様に、`BatchWriteItem` リクエストに 2 つの PUT リクエストと 4 つの DELETE リクエストが含まれている場合、DynamoDB によって 2 つの `PutItem` リクエストと 4 つの `DeleteItem` リクエストが実行されます。

一般的に、バッチの*すべて*のリクエストが失敗しない限り、バッチオペレーションは失敗しません。たとえば、`BatchGetItem` オペレーションを実行する際、バッチの個々の `GetItem` リクエストが失敗したとします。この場合、`BatchGetItem` は失敗した `GetItem` リクエストからキーとデータを返します。バッチのその他の `GetItem` リクエストは影響を受けません。

### BatchGetItem
<a name="WorkingWithItems.BatchOperations.BatchGetItem"></a>

1 回の `BatchGetItem` オペレーションには、最大 100 の個々の `GetItem` リクエストが含まれていて、最大 16 MB のデータを取得できます。さらに、`BatchGetItem` オペレーションで、複数のテーブルから項目を取得できます。

**Example**  
一部の属性のみが返されるようにプロジェクション式を使用して `Thread` テーブルから 2 つの項目を取得します。  

```
aws dynamodb batch-get-item \
    --request-items file://request-items.json
```
`--request-items` の引数は、ファイル `request-items.json` に保存されます。  

```
{
    "Thread": {
        "Keys": [
            {
                "ForumName":{"S": "Amazon DynamoDB"},
                "Subject":{"S": "DynamoDB Thread 1"}
            },
            {
                "ForumName":{"S": "Amazon S3"},
                "Subject":{"S": "S3 Thread 1"}
            }
        ],
        "ProjectionExpression":"ForumName, Subject, LastPostedDateTime, Replies"
    }
}
```

### BatchWriteItem
<a name="WorkingWithItems.BatchOperations.BatchWriteItem"></a>

`BatchWriteItem` オペレーションには最大 25 の個々の `PutItem` リクエストと `DeleteItem` リクエストを含むことができ、最大 16 MB のデータを書き込めます。(個々の項目の最大サイズは 400 KB です。) さらに、`BatchWriteItem` オペレーションで、複数のテーブルの項目を入力したり削除したりできます。

**注記**  
`BatchWriteItem` では `UpdateItem` リクエストはサポートされません。

**Example**  
`ProductCatalog` テーブルに 2 つの項目を書き込みます。  

```
aws dynamodb batch-write-item \
    --request-items file://request-items.json
```
`--request-items` の引数は、ファイル `request-items.json` に保存されます。  

```
{
    "ProductCatalog": [
        {
            "PutRequest": {
                "Item": {
                    "Id": { "N": "601" },
                    "Description": { "S": "Snowboard" },
                    "QuantityOnHand": { "N": "5" },
                    "Price": { "N": "100" }
                }
            }
        },
        {
            "PutRequest": {
                "Item": {
                    "Id": { "N": "602" },
                    "Description": { "S": "Snow shovel" }
                }
            }
        }
    ]
}
```

## アトミックカウンタ
<a name="WorkingWithItems.AtomicCounters"></a>

この `UpdateItem` オペレーションを使用して、*アトミックカウンター* (他の書き込みリクエストに干渉することなく無条件に増分される数値属性) を実装できます。（すべての書き込みリクエストは、受信された順に適用されます）。アトミックカウンターでは、更新はべき等ではありません。つまり、`UpdateItem` を呼び出すたびに数値はインクリメントまたはデクリメントされます。アトミックカウンタの更新に使用されるインクリメント値が正の場合、オーバーカウントが発生する可能性があります。インクリメント値が負の場合、アンダーカウントの原因となります。

ウェブサイトの訪問者数を追跡するためにアトミックカウンターを使用できます。この場合、アプリケーションでは、現在値に関係なく、数値はインクリメントされます。`UpdateItem` オペレーションが失敗した場合、アプリケーションはオペレーションを再試行します。これには、カウンターを 2 度更新する恐れがありますが、ウェブサイトの訪問者数のカウントに多少の誤差があっても許容できるでしょう。

アトミックカウンターはカウントの誤差が許容されない場合にはふさわしくありません (銀行業務用のアプリケーションなど)。この場合は、アトミックカウンターの代わりに条件付き更新を使用する方が安全です。

詳細については、「[数値属性の増減](Expressions.UpdateExpressions.md#Expressions.UpdateExpressions.SET.IncrementAndDecrement)」を参照してください。

**Example**  
次の AWS CLI の例では、商品の `Price` が 5 でインクリメントされます。この例では、カウンタが更新される前に項目が存在することがわかっていました。(`UpdateItem` は冪等性ではないので、`Price` はこのコードを実行するたびに増えていきます)。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id": { "N": "601" }}' \
    --update-expression "SET Price = Price + :incr" \
    --expression-attribute-values '{":incr":{"N":"5"}}' \
    --return-values UPDATED_NEW
```

## 条件付きの書き込み
<a name="WorkingWithItems.ConditionalUpdate"></a>

デフォルトでは、DynamoDB 書き込みオペレーション (`PutItem`、`DeleteItem`) は*無条件*です。つまり、これらの各オペレーションでは、指定されたプライマリキーを持つ既存の項目が上書きされます。

DynamoDB はオプションでこれらのオペレーションの条件付き書き込みをサポートしています。条件付き書き込みが成功するのは、項目の属性が 1 つ以上の想定条件を満たす場合のみです。それ以外の場合は、エラーが返されます。

条件付き書き込みでは、その条件について項目の最新更新バージョンと照合します。なお、項目が以前に存在しなかった場合や、その項目に対して最後に成功した操作が削除であった場合、条件付き書き込みでは以前の項目は検出されません。

 条件付き書き込みは多くの状況で役立ちます。たとえば、同じプライマリキーを持つ既存の項目がない場合にのみ、`PutItem` オペレーションが成功するようにできます。または、属性の 1 つに特定の値がある場合に `UpdateItem` オペレーションが項目を変更することを防ぐことができます。

条件付き書き込みは、複数のユーザーが同じ項目を変更しようとする場合に役立ちます。2 人のユーザー (Alice と Bob) が DynamoDB テーブルから同じ項目を処理している以下の図を考慮します。

![\[Alice と Bob は、ID 1 の項目を変更しようとし、条件付き書き込みの必要性を示します。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/update-no-condition.png)


Alice が AWS CLI を使用して `Price` 属性を 8 に更新するとします。

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --update-expression "SET Price = :newval" \
    --expression-attribute-values file://expression-attribute-values.json
```

`--expression-attribute-values` の引数は、ファイル `expression-attribute-values.json` に保存されます。

```
{
    ":newval":{"N":"8"}
}
```

次に、Bob が後で同様の `UpdateItem` リクエストを発行しますが、`Price` を 12 に変更します。Bob には、`--expression-attribute-values` パラメータは次のように見えます。

```
{
    ":newval":{"N":"12"}
}
```

Bob のリクエストは成功しますが、その前の Alice の更新は失われます。

条件付き `PutItem`、`DeleteItem`、または `UpdateItem` をリクエストするには、条件式を指定します。*条件式*は、属性名、条件付き演算子および組み込み関数を含む文字列です。式全体の評価が true になる必要があります。それ以外の場合は、このオペレーションは失敗します。

次は、条件付き書き込みにより Alice の更新が上書きされるのを防ぐ方法について、以下の図を考慮します。

![\[条件付き書き込みにより、ユーザー Bob の更新によってユーザー Alice の変更が同じ項目に上書きされるのを防ぐことができます。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/update-yes-condition.png)


Alice はまず `Price` を 8 に更新を試行しますが、現在の `Price` が 10 である場合にのみ、という条件でそうします。

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"1"}}' \
    --update-expression "SET Price = :newval" \
    --condition-expression "Price = :currval" \
    --expression-attribute-values file://expression-attribute-values.json
```

`--expression-attribute-values` の引数は、ファイル `expression-attribute-values.json` に保存されます。

```
{
    ":newval":{"N":"8"},
    ":currval":{"N":"10"}
}
```

条件が true に評価されるため、Alice の更新は成功します。

次に、Bob は、`Price` を 12 に 更新しますが、現在の `Price` が 10 である場合にのみ、という条件でそうします。Bob には、`--expression-attribute-values` パラメータは次のように見えます。

```
{
    ":newval":{"N":"12"},
    ":currval":{"N":"10"}
}
```

Alice がすでに `Price` を 8 に変更していたので、条件式は false 評価され Bob の更新は失敗します。

詳細については、「[DynamoDB 条件式 CLI の例](Expressions.ConditionExpressions.md)」を参照してください。

### 条件付き書き込みの冪等性
<a name="WorkingWithItems.ConditionalWrites.Idempotence"></a>

条件付き書き込みは、条件チェックが更新される同じ属性で行われる場合に、*べき等性*が保たれます。つまり、リクエスト時に項目の特定の属性値が想定されたものである場合にのみ、DynamoDB によって指定された書き込みリクエストが実行されます。

たとえば、`UpdateItem` リクエストを発行し、項目の `Price` を、現在の `Price` が 20 である場合のみ、3 増加させるとします。リクエストを送信した後、その結果を得る前にネットワークエラーが発生したため、リクエストが成功したかどうか不明です。この条件付き書き込みはべき等のオペレーションであるため、同じ `UpdateItem` リクエストを再試行できます。すると、DynamoDB は、現在の `Price` が 20 である場合のみ項目を更新します。

### 条件付き書き込みで消費されるキャパシティユニット
<a name="WorkingWithItems.ConditionalWrites.ReturnConsumedCapacity"></a>

条件付き書き込み中に `ConditionExpression` が false と評価された場合でも、DynamoDB はテーブルの書き込みキャパシティを消費します。消費量は、既存の項目のサイズ（または最低 1）によって異なります。例えば、既存の項目が 300 KB で、作成または更新しようとしている新しい項目が 310 KB の場合、消費される書き込みキャパシティーユニットは、条件が満たされないかったら 300、満たされたら 310 になります。これが新しい項目 (既存の項目なし) の場合、消費される書き込みキャパシティーユニットは条件が満たされれば 1、条件が満たされなかったら 310 になります。

**注記**  
書き込みオペレーションでは、*書き込み*キャパシティーユニットのみが消費されます。*読み込み*キャパシティーユニットは消費されません。

失敗した条件付き書き込みは `ConditionalCheckFailedException` を返します。これが起きると、消費された書き込みキャパシティに関する情報はレスポンスで返されません。

条件付き書き込みの際に消費された書き込みキャパシティーユニットの数を返すには、`ReturnConsumedCapacity` パラメータを使用します。
+ `TOTAL` — 消費された書き込み容量単位の総数を返します。
+ `INDEXES` — 消費された書き込み容量単位の総数とともに、テーブルおよびオペレーションに影響を受けたセカンダリインデックスの小計を返します。
+ `NONE` — 書き込み容量の詳細は返されません。(これがデフォルトです)

  

**注記**  
グローバルセカンダリインデックスとは異なり、ローカルセカンダリインデックスは、プロビジョンドスループット性能をそのテーブルと共有します。ローカルセカンダリインデックスでの読み込みと書き込みのアクティビティは、テーブルからプロビジョンドスループット性能を消費します。

# DynamoDB での式の使用
<a name="Expressions"></a>

Amazon DynamoDB では、式を使用して、項目から読み取る属性の指定、条件が満たされたときのデータの書き込み、項目の更新方法の指定、クエリの定義、クエリ結果のフィルタリングを行うことができます。**

このテーブルでは、式の基本的な文法と利用可能な式の種類について説明します。


| 式タイプ | 説明 | 
| --- | --- | 
| プロジェクション式 | プロジェクション式は、GetItem、Query、Scan などのオペレーションを使用するときに項目から取得する属性を特定します。 | 
| 条件式 | 条件式は、PutItem、UpdateItem、DeleteItem の各オペレーションを使用したときに、どの項目を変更すべきかを決定します。 | 
| 更新式 | 更新式は、UpdateItem で項目の属性を変更する方法を指定します。例えば、スカラー値を設定したり、リストまたはマップから要素を削除したりします。 | 
| キー条件式 | キー条件式は、クエリがテーブルやインデックスから読み取る項目を決定します。 | 
| フィルター式 | フィルター式は、クエリ結果のうち、どの項目を返すべきかを決定します。他のすべての結果は破棄されます。 | 

式の構文と各タイプの式の詳細については、以下のセクションを参照してください。

**Topics**
+ [DynamoDB で式を使用する場合の項目属性の参照](Expressions.Attributes.md)
+ [DynamoDB の式の属性名 (エイリアス)](Expressions.ExpressionAttributeNames.md)
+ [DynamoDB での式属性値の使用](Expressions.ExpressionAttributeValues.md)
+ [DynamoDB でのプロジェクション式の使用](Expressions.ProjectionExpressions.md)
+ [DynamoDB での更新式の使用](Expressions.UpdateExpressions.md)
+ [DynamoDB の条件式とフィルター式、演算子、関数](Expressions.OperatorsAndFunctions.md)
+ [DynamoDB 条件式 CLI の例](Expressions.ConditionExpressions.md)

**注記**  
下位互換性のために、DynamoDB は式を使用しない条件パラメータもサポートします。詳細については、「[レガシー DynamoDB 条件パラメータ](LegacyConditionalParameters.md)」を参照してください。  
新しいアプリケーションでは、レガシーパラメータではなく式を使用する必要があります。

# DynamoDB で式を使用する場合の項目属性の参照
<a name="Expressions.Attributes"></a>

このセクションでは、Amazon DynamoDB で式の項目属性を参照する方法を説明します。複数のリストやマップ内で深くネストされている場合でも、属性を使用できます。

**Topics**
+ [最上位属性](#Expressions.Attributes.TopLevelAttributes)
+ [入れ子の属性](#Expressions.Attributes.NestedAttributes)
+ [ドキュメントパス](#Expressions.Attributes.NestedElements.DocumentPathExamples)

**サンプル項目: ProductCatalog**  
このページの例では、`ProductCatalog` テーブルで次のサンプル項目を使用しています (このテーブルについては、「[DynamoDB で使用するテーブルとデータの例](AppendixSampleTables.md)」で説明されています)。

```
{
    "Id": 123,
    "Title": "Bicycle 123",
    "Description": "123 description",
    "BicycleType": "Hybrid",
    "Brand": "Brand-Company C",
    "Price": 500,
    "Color": ["Red", "Black"],
    "ProductCategory": "Bicycle",
    "InStock": true,
    "QuantityOnHand": null,
    "RelatedItems": [
        341,
        472,
        649
    ],
    "Pictures": {
        "FrontView": "http://example.com/products/123_front.jpg",
        "RearView": "http://example.com/products/123_rear.jpg",
        "SideView": "http://example.com/products/123_left_side.jpg"
    },
    "ProductReviews": {
	    "FiveStar": [
	    		"Excellent! Can't recommend it highly enough! Buy it!",
	    		"Do yourself a favor and buy this."
	    ],
	    "OneStar": [
	    		"Terrible product! Do not buy this."
	    ]
    },
    "Comment": "This product sells out quickly during the summer",
    "Safety.Warning": "Always wear a helmet"
 }
```

次の点に注意してください。
+ パーティションキー値 (`Id`) は `123` です。ソートキーはありません。
+ ほとんどの属性に、`String`、`Number`、`Boolean`、`Null` などのスカラーデータ型があります。
+ 1 つの属性 (`Color`) は `String Set` です。
+ 次の属性はドキュメントデータ型です。
  + `RelatedItems` のリスト。各要素は関連製品の `Id` です。
  + `Pictures` のマップ。各要素は対応するイメージファイルの URL と、写真の短い説明です。
  + `ProductReviews` のマップ。各要素は、レーティングと、そのレーティングに対応する評価のリストを表します。最初に、このマップには 5 つ星と 1 つ星の評価が入力されます。

## 最上位属性
<a name="Expressions.Attributes.TopLevelAttributes"></a>

属性が別の属性に組み込まれていない場合、*最上位属性*と呼ばれます。`ProductCatalog` 項目の最上位属性は次のようになります。
+ `Id`
+ `Title`
+ `Description`
+ `BicycleType`
+ `Brand`
+ `Price`
+ `Color`
+ `ProductCategory`
+ `InStock`
+ `QuantityOnHand`
+ `RelatedItems`
+ `Pictures`
+ `ProductReviews`
+ `Comment`
+ `Safety.Warning`

`Color` (リスト)、`RelatedItems` (リスト)、`Pictures` (マップ)、および `ProductReviews` (マップ) を除くすべての最上位属性はスカラーです。

## 入れ子の属性
<a name="Expressions.Attributes.NestedAttributes"></a>

属性が別の属性に組み込まれている場合、*入れ子の属性*と呼ばれます。入れ子の属性にアクセスするには、*間接参照演算子*を使用します。
+ `[n]` — リストの要素
+ `.` (ドット) — マップの要素

### リスト要素へのアクセス
<a name="Expressions.Attributes.NestedElements.AccessingListElements"></a>

リスト要素の間接参照演算子は **[*n*]** で、*n* は要素数です。リストの要素はゼロベースであるため、[0] はリスト内の最初の要素、[1] は 2 番目の要素、という順番で表されます。次に例を示します。
+ `MyList[0]`
+ `AnotherList[12]`
+ `ThisList[5][11]`

要素 `ThisList[5]` は、それ自体がネストされたリストです。したがって、`ThisList[5][11]` は、そのリストの 12 番目の要素を参照します。

角括弧内の数は、負以外の整数である必要があります。そのため、次の式は無効です。
+ `MyList[-1]`
+ `MyList[0.4]`

### マップ要素へのアクセス
<a name="Expressions.Attributes.NestedElements.AccessingMapElements"></a>

マップ要素の間接参照演算子は **.** (ドット) です。マップの要素間の区切り文字として、ドットを使用します。
+ `MyMap.nestedField`
+ `MyMap.nestedField.deeplyNestedField`

## ドキュメントパス
<a name="Expressions.Attributes.NestedElements.DocumentPathExamples"></a>

式では、*ドキュメントパス*を使用して、属性の場所を DynamoDB に伝えます。最上位属性の場合、ドキュメントパスは単純に属性名になります。ネストされた属性の場合は、間接参照演算子を使用してドキュメントパスを構築します。

ドキュメントパスのいくつかの例を次に示します。([DynamoDB で式を使用する場合の項目属性の参照](#Expressions.Attributes) に示された項目を参照してください)
+ 最上位のスカラー属性。

   `Description`
+ 最上位のリスト属性。(これはいくつかの要素だけではなく、すべてを示すリストを返します)

  `RelatedItems`
+ `RelatedItems` リストの 3 番目の要素 （このリスト要素はゼロベースであることに注意してください)。

  `RelatedItems[2]`
+ 製品の正面の写真。

  `Pictures.FrontView`
+ すべての 5 つ星の評価。

  `ProductReviews.FiveStar`
+ 最初の 5 つ星の評価。

  `ProductReviews.FiveStar[0]`

**注記**  
ドキュメントパスの最大深度は 32 です。したがって、任意のパスの間接参照演算子の数はこの制限を超えることはできません。

次の要件を満たしている限り、ドキュメントパスには任意の属性名を使用できます。
+ 最初の文字は `a-z`、`A-Z`、または `0-9`
+ 2 番目の文字 (存在する場合) は `a-z`、`A-Z`

**注記**  
属性名がこの要件を満たさない場合は、式の属性名をプレースホルダーとして定義する必要があります。

詳細については、「[DynamoDB の式の属性名 (エイリアス)](Expressions.ExpressionAttributeNames.md)」を参照してください。

# DynamoDB の式の属性名 (エイリアス)
<a name="Expressions.ExpressionAttributeNames"></a>

式の属性名は、実際の属性名の代わりとして Amazon DynamoDB の式で使用するエイリアス (またはプレースホルダー) です。**式の属性名は、シャープ記号 (`#`) で始める必要があり、1 つ以上の英数字が続きます。アンダースコア (`_`) 文字も使用できます。

このセクションでは、式の属性名を使用する必要があるいくつかの状況について説明します。

**注記**  
このセクションの例では AWS Command Line Interface (AWS CLI) を使用します。

**Topics**
+ [予約語](#Expressions.ExpressionAttributeNames.ReservedWords)
+ [特殊文字を含む属性名](#Expressions.ExpressionAttributeNames.AttributeNamesContainingSpecialCharacters)
+ [入れ子の属性](#Expressions.ExpressionAttributeNames.NestedAttributes)
+ [属性名を繰り返し参照する](#Expressions.ExpressionAttributeNames.RepeatingAttributeNames)

## 予約語
<a name="Expressions.ExpressionAttributeNames.ReservedWords"></a>

DynamoDB 予約語と競合する属性名を含む式を書く必要が生じることもあります。予約語の一覧については、「[DynamoDB の予約語](ReservedWords.md)」を参照してください。

たとえば、AWS CLI は予約語であるため、次の `COMMENT` の例は失敗します。

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "Comment"
```

この問題に対処するには、`Comment` を、`#c` などの式の属性名で置き換えることができます。`#`（シャープ記号）は必須であり、これが属性名のプレースホルダーであることを示します。AWS CLI の例は次のようになります。

```
aws dynamodb get-item \
     --table-name ProductCatalog \
     --key '{"Id":{"N":"123"}}' \
     --projection-expression "#c" \
     --expression-attribute-names '{"#c":"Comment"}'
```

**注記**  
属性名が数値で始まるか、スペースまたは予約語を含む場合、式の属性名を使用して式のその属性名を置き換える*必要があります*。

## 特殊文字を含む属性名
<a name="Expressions.ExpressionAttributeNames.AttributeNamesContainingSpecialCharacters"></a>

式では、ドット (".") はドキュメントパスの区切り文字として解釈されます。ただし、DynamoDB では属性名の一部としてドット文字や、ハイフン (「-」) などの特殊文字を使用することもできます。これは、あいまいな意味を持つことがあります。例として、`ProductCatalog` 項目から `Safety.Warning` 属性を取得するとします ([DynamoDB で式を使用する場合の項目属性の参照](Expressions.Attributes.md) を参照してください)。

プロジェクション式を使用して、`Safety.Warning` にアクセスするとします。

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "Safety.Warning"
```

DynamoDB は、予想される文字列 ("`Always wear a helmet`") ではなく空の結果を返します。これは、DynamoDB が式のドットをドキュメントパスの区切り文字として解釈するためです。この場合、`#sw` の置換として式の属性名 (`Safety.Warning` など) を定義する必要があります。その後、次のプロジェクション式を使用します。

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "#sw" \
    --expression-attribute-names '{"#sw":"Safety.Warning"}'
```

次に、DynamoDB が正しい結果を返します。

**注記**  
属性名にドット (「.」) またはハイフン (「-」) が含まれている場合は、式の属性名を使用して、式でその属性名を置き換える*必要があります*。

## 入れ子の属性
<a name="Expressions.ExpressionAttributeNames.NestedAttributes"></a>

ネストされた属性 `ProductReviews.OneStar` にアクセスするとします。式の属性名において、DynamoDB はドット (".") を属性名内の文字として扱います。ネストされた属性を参照するには、ドキュメントパス内の要素ごとに式の属性名を定義します。
+ `#pr — ProductReviews`
+ `#1star — OneStar`

その後、プロジェクション式として `#pr.#1star` を使用します。

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "#pr.#1star"  \
    --expression-attribute-names '{"#pr":"ProductReviews", "#1star":"OneStar"}'
```

次に、DynamoDB が正しい結果を返します。

## 属性名を繰り返し参照する
<a name="Expressions.ExpressionAttributeNames.RepeatingAttributeNames"></a>

式の属性名は、同じ属性名を繰り返し参照する必要がある場合に役立ちます。たとえば、`ProductCatalog` 項目からいくつかの評価を取得する次の式を考えてみます。

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "ProductReviews.FiveStar, ProductReviews.ThreeStar, ProductReviews.OneStar"
```

これをより簡潔にするために、`ProductReviews` を、`#pr` などの式の属性名で置き換えることができます。変更された式は次のようになります。
+  `#pr.FiveStar, #pr.ThreeStar, #pr.OneStar` 

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"123"}}' \
    --projection-expression "#pr.FiveStar, #pr.ThreeStar, #pr.OneStar" \
    --expression-attribute-names '{"#pr":"ProductReviews"}'
```

式属性名を定義した場合、式全体で一貫して使用する必要があります。さらに、`#` 記号を省略することはできません。

# DynamoDB での式属性値の使用
<a name="Expressions.ExpressionAttributeValues"></a>

Amazon DynamoDB の式の属性値は変数として機能します。**式の属性値は、比較する実際の値 (ランタイムまでは不明である可能性のある値) の代わりになります。式の属性値はコロン (`:`) で始まり、1 つ以上の英数字が続きます。

たとえば、`ProductCatalog` で入手でき、費用が `Black` 以下の `500` 項目のすべてを返すとします。この `Scan` (AWS Command Line Interface) の例のように AWS CLI オペレーションでフィルタ式を使用できます。

```
aws dynamodb scan \
    --table-name ProductCatalog \
    --filter-expression "contains(Color, :c) and Price <= :p" \
    --expression-attribute-values file://values.json
```

`--expression-attribute-values` の引数は、ファイル `values.json` に保存されます。

```
{
    ":c": { "S": "Black" },
    ":p": { "N": "500" }
}
```

式属性値を定義した場合、式全体で一貫して使用する必要があります。さらに、`:` 記号を省略することはできません。

式の属性値は、主な条件式、条件式、更新式、およびフィルター式で使用されます。

# DynamoDB でのプロジェクション式の使用
<a name="Expressions.ProjectionExpressions"></a>

テーブルからデータを読み込むには、次のような `GetItem`、`Query`、または `Scan` のオペレーションを使用します。Amazon DynamoDB は、デフォルトですべての項目属性を返します。すべての属性ではなく、一部の属性のみを取得するには、プロジェクション式を使用します。

*プロジェクション式*は、任意の属性を識別する文字列です。1 つの属性を取得するには、名前を指定します。複数の属性の場合、名前をカンマで区切る必要があります。

`ProductCatalog` からの [DynamoDB で式を使用する場合の項目属性の参照](Expressions.Attributes.md) 項目に基づく、プロジェクション式のいくつかの例を次に示します。
+ 1 つの最上位属性。

  `Title `
+ 3 つの最上位属性。DynamoDB は `Color` セット全体を取得します。

  `Title, Price, Color`
+ 4 つの最上位属性。DynamoDB は `RelatedItems` および `ProductReviews` のコンテンツ全体を返します。

  `Title, Description, RelatedItems, ProductReviews`

**注記**  
プロジェクション式は、プロビジョンドスループットの消費には影響しません。DynamoDB は、アプリケーションに返すデータの量ではなく、項目のサイズに基づいて、キャパシティユニットの消費数を決定します。

**予約語と特殊文字**

DynamoDB には予約語と特殊文字があります。DynamoDB では、これらの予約語と特殊文字を名前に使用できますが、お勧めしません。これらの名前を式で使用するたびに、代わりにエイリアスを使用する必要があるためです。詳細な一覧については、「[DynamoDB の予約語](ReservedWords.md)」を参照してください。

次の場合は、実際の名前の代わりに式の属性名を使用する必要があります。
+ 属性名が DynamoDB の予約語リストにある場合。
+ 最初の文字が `a-z` または `A-Z` で、2 番目の文字 (存在する場合) が `a-Z`、`A-Z`、`0-9` のいずれかでなければならないという要件を属性名が満たしていない場合。
+ 属性名に、**\$1** (ハッシュ) または **:** (コロン) が含まれている場合。

以下の AWS CLI の例に示しているのは、`GetItem` オペレーションでプロジェクション式を使用する方法です。この式は最上位スカラー射影内の属性 (`Description`)、リスト内の最初の要素 (`RelatedItems[0]`)、およびマップ内に入れ子にするリスト (`ProductReviews.FiveStar`) を取得します。

```
aws dynamodb get-item \
    --table-name ProductCatalog \
    --key '"Id": { "N": "123" } \
    --projection-expression "Description, RelatedItems[0], ProductReviews.FiveStar"
```

この例では、次の JSON が返されます。

```
{
    "Item": {
        "Description": {
            "S": "123 description"
        },
        "ProductReviews": {
            "M": {
                "FiveStar": {
                    "L": [
                        {
                            "S": "Excellent! Can't recommend it highly enough! Buy it!"
                        },
                        {
                            "S": "Do yourself a favor and buy this."
                        }
                    ]
                }
            }
        },
        "RelatedItems": {
            "L": [
                {
                    "N": "341"
                }
            ]
        }
    }
}
```

# DynamoDB での更新式の使用
<a name="Expressions.UpdateExpressions"></a>

`UpdateItem` オペレーションは、既存項目を更新します。また、存在しない場合は新しい項目をテーブルに追加します。更新する項目のキーを指定する必要があります。また、変更する属性を示す更新式と、その式に割り当てる値も指定する必要があります。

*更新式*は、`UpdateItem` が項目の属性を変更する方法を指定します。たとえば、スカラー値を設定したり、リストまたはマップから要素を削除したりします。

更新式の構文の概要を次に示します。

```
update-expression ::=
    [ SET action [, action] ... ]
    [ REMOVE action [, action] ...]
    [ ADD action [, action] ... ]
    [ DELETE action [, action] ...]
```

更新式は、1 つ以上の句で構成されます。各句は、`SET`、`REMOVE`、`ADD`、または `DELETE` キーワードで始まります。これらのいずれの句も、任意の順序で更新式に含めることができます。ただし、各アクションキーワードは 1 回のみ表示できます。

各句内には、カンマで区切った 1 つ以上のアクションがあります。各アクションはデータ変更を表します。

このセクションの例は、`ProductCatalog` の [DynamoDB でのプロジェクション式の使用](Expressions.ProjectionExpressions.md) 項目に基づいています。

以下のトピックでは、`SET` アクションのさまざまなユースケースについて説明します。

**Topics**
+ [SET — 項目属性の変更または追加](#Expressions.UpdateExpressions.SET)
+ [REMOVE — 項目から属性を削除](#Expressions.UpdateExpressions.REMOVE)
+ [ADD — 数値とセットの更新](#Expressions.UpdateExpressions.ADD)
+ [DELETE — セットから要素を削除](#Expressions.UpdateExpressions.DELETE)
+ [複数の更新式を使用する](#Expressions.UpdateExpressions.Multiple)

## SET — 項目属性の変更または追加
<a name="Expressions.UpdateExpressions.SET"></a>

1 つ以上の属性を項目に追加するには、更新式で `SET` アクションを使用します。これらのいずれかの属性が既に存在する場合、新しい値で上書きされます。既存の属性の上書きを回避するには、`SET` で `if_not_exists` 関数を使用できます。`if_not_exists` 関数は `SET` アクションに固有で、更新式でのみ使用できます。

`SET` を使用してリスト要素を更新すると、その要素のコンテンツは、指定した新しいデータで置き換えられます。要素が既に存在していない場合、`SET` はリストの末尾に新しい要素を追加します。

1 つの `SET` オペレーションに複数の要素を追加すると、要素は要素番号で順にソートされます。

`SET` を使用して、`Number` 型である属性を増減することもできます。複数の `SET` アクションを実行するには、オペレーションをカンマで区切ります。

次の構文の概要について説明します。
+ *path* 要素は、項目へのドキュメントパスです。
+ **operand** 要素は、項目へのドキュメントパスまたは関数とすることができます。

```
set-action ::=
    path = value

value ::=
    operand
    | operand '+' operand
    | operand '-' operand

operand ::=
    path | function

function ::=
    if_not_exists (path, value)
```

項目の指定したパスに属性が含まれていない場合、`if_not_exists` は `value` に評価されます。それ以外の場合は、`path` に評価されます。

次の `PutItem` オペレーションは、例で参照するサンプル項目を作成します。

```
aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json
```

`--item` の引数は、ファイル `item.json` に保存されます。(分かりやすいように、いくつかの項目属性のみが使用されます)

```
{
    "Id": {"N": "789"},
    "ProductCategory": {"S": "Home Improvement"},
    "Price": {"N": "52"},
    "InStock": {"BOOL": true},
    "Brand": {"S": "Acme"}
}
```

**Topics**
+ [属性の変更](#Expressions.UpdateExpressions.SET.ModifyingAttributes)
+ [リストおよびマップの追加](#Expressions.UpdateExpressions.SET.AddingListsAndMaps)
+ [リストに要素を追加](#Expressions.UpdateExpressions.SET.AddingListElements)
+ [ネストされたマップ属性の追加](#Expressions.UpdateExpressions.SET.AddingNestedMapAttributes)
+ [数値属性の増減](#Expressions.UpdateExpressions.SET.IncrementAndDecrement)
+ [リストに要素を追加](#Expressions.UpdateExpressions.SET.UpdatingListElements)
+ [既存の属性の上書きを防止](#Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites)

### 属性の変更
<a name="Expressions.UpdateExpressions.SET.ModifyingAttributes"></a>

**Example**  
`ProductCategory` 属性および `Price` 属性を更新します。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET ProductCategory = :c, Price = :p" \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
`--expression-attribute-values` の引数は、ファイル `values.json` に保存されます。  

```
{
    ":c": { "S": "Hardware" },
    ":p": { "N": "60" }
}
```

**注記**  
`UpdateItem` オペレーションでは、`--return-values ALL_NEW` を指定すると、DynamoDB は更新後に表示される項目を返します。

### リストおよびマップの追加
<a name="Expressions.UpdateExpressions.SET.AddingListsAndMaps"></a>

**Example**  
新しいリストおよび新しいマップを追加します。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET RelatedItems = :ri, ProductReviews = :pr" \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
`--expression-attribute-values` の引数は、ファイル `values.json` に保存されます。  

```
{
    ":ri": {
        "L": [
            { "S": "Hammer" }
        ]
    },
    ":pr": {
        "M": {
            "FiveStar": {
                "L": [
                    { "S": "Best product ever!" }
                ]
            }
        }
    }
}
```

### リストに要素を追加
<a name="Expressions.UpdateExpressions.SET.AddingListElements"></a>

**Example**  
新しい属性を `RelatedItems` リストに追加します。リストの要素はゼロベースであるため、[0] はリスト内の最初の要素、[1] は 2 番目の要素、という順番で表されることに注意してください。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET RelatedItems[1] = :ri" \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
`--expression-attribute-values` の引数は、ファイル `values.json` に保存されます。  

```
{
    ":ri": { "S": "Nails" }
}
```

**注記**  
`SET` を使用してリスト要素を更新すると、その要素のコンテンツは、指定した新しいデータで置き換えられます。要素が既に存在していない場合、`SET` はリストの末尾に新しい要素を追加します。  
1 つの `SET` オペレーションに複数の要素を追加すると、要素は要素番号で順にソートされます。

### ネストされたマップ属性の追加
<a name="Expressions.UpdateExpressions.SET.AddingNestedMapAttributes"></a>

**Example**  
ネストされたマップ属性を追加します。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET #pr.#5star[1] = :r5, #pr.#3star = :r3" \
    --expression-attribute-names file://names.json \
    --expression-attribute-values file://values.json \
    --return-values ALL_NEW
```
`--expression-attribute-names` の引数は、ファイル `names.json` に保存されます。  

```
{
    "#pr": "ProductReviews",
    "#5star": "FiveStar",
    "#3star": "ThreeStar"
}
```
`--expression-attribute-values` の引数は、ファイル `values.json` に保存されます。  

```
{
    ":r5": { "S": "Very happy with my purchase" },
    ":r3": {
        "L": [
            { "S": "Just OK - not that great" }
        ]
    }
}
```

**重要**  
親マップが存在しない場合、ネストされたマップ属性を更新することはできません。親マップ (`ProductReviews.FiveStar`) が存在しない場合にネストされた属性 (`ProductReviews` など) を更新しようとすると、DynamoDB は*「更新式で指定されたドキュメントパスは更新に無効です」*というメッセージで `ValidationException` を返します。  
ネストされたマップ属性を後で更新する項目を作成する場合は、親属性の空のマップを初期化します。例えば、次のようになります。  

```
{
    "Id": {"N": "789"},
    "ProductReviews": {"M": {}},
    "Metadata": {"M": {}}
}
```
これにより、`ProductReviews.FiveStar` のようなネストされた属性をエラーなしで更新できます。

### 数値属性の増減
<a name="Expressions.UpdateExpressions.SET.IncrementAndDecrement"></a>

既存の数値属性は増減することができます。これを行うには、`+`（プラス）および `-`（マイナス）演算子を使用します。

**Example**  
項目の `Price` を下げます。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET Price = Price - :p" \
    --expression-attribute-values '{":p": {"N":"15"}}' \
    --return-values ALL_NEW
```
`Price` を上げるために、更新式で `+` 演算子を使用します。

### リストに要素を追加
<a name="Expressions.UpdateExpressions.SET.UpdatingListElements"></a>

リストの最後に要素を追加できます。これを行うには、`SET` 関数の `list_append`を使用します。(関数名では、大文字と小文字が区別されます)。`list_append` 関数は `SET` アクションに固有で、更新式でのみ使用できます。構文は次のとおりです。
+ `list_append (list1, list2)`

この関数は、入力として 2 つのリストを受け取り、`list2` のすべての要素を ` list1` に追加します。

**Example**  
[リストに要素を追加](#Expressions.UpdateExpressions.SET.AddingListElements) で、`RelatedItems` リストを追加し `Hammer` と `Nails` の 2 つの要素を追加します。次に、`RelatedItems` の末尾にさらに 2 つの要素を追加します。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET #ri = list_append(#ri, :vals)" \
    --expression-attribute-names '{"#ri": "RelatedItems"}' \
    --expression-attribute-values file://values.json  \
    --return-values ALL_NEW
```
`--expression-attribute-values` の引数は、ファイル `values.json` に保存されます。  

```
{
    ":vals": {
        "L": [
            { "S": "Screwdriver" },
            {"S": "Hacksaw" }
        ]
    }
}
```
最後に、`RelatedItems` の*先頭*にもう 1 つの要素を追加します。これを実行するには、`list_append` 要素の順序を入れ替えます。(`list_append` は 2 つのリストを入力し、1 番目のリストに 2 番目のリストを追加することに注意してください)。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET #ri = list_append(:vals, #ri)" \
    --expression-attribute-names '{"#ri": "RelatedItems"}' \
    --expression-attribute-values '{":vals": {"L": [ { "S": "Chisel" }]}}' \
    --return-values ALL_NEW
```
生成される `RelatedItems` 属性には次の順序で 5 つの要素が含まれます。`Chisel`、`Hammer`、`Nails`、`Screwdriver`、 `Hacksaw`。

### 既存の属性の上書きを防止
<a name="Expressions.UpdateExpressions.SET.PreventingAttributeOverwrites"></a>

**Example**  
項目にすでに `Price` 属性がない場合にのみ、項目の `Price` を設定します (`Price` がすでに存在する場合は何も起こりません)。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET Price = if_not_exists(Price, :p)" \
    --expression-attribute-values '{":p": {"N": "100"}}' \
    --return-values ALL_NEW
```

## REMOVE — 項目から属性を削除
<a name="Expressions.UpdateExpressions.REMOVE"></a>

1 つ以上の属性を Amazon DynamoDB の項目から削除するには、更新式で `REMOVE` アクションを使用します。複数の `REMOVE` アクションを実行するには、オペレーションをカンマで区切ります。

更新式の `REMOVE` の構文の概要を次に示します。唯一のオペランドは、削除する属性のドキュメントパスです。

```
remove-action ::=
    path
```

**Example**  
項目から属性を削除します。(属性が存在しない場合は、何も起こりません)。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "REMOVE Brand, InStock, QuantityOnHand" \
    --return-values ALL_NEW
```

### リストから要素を削除
<a name="Expressions.UpdateExpressions.REMOVE.RemovingListElements"></a>

`REMOVE` を使用して、リストから個別要素を削除できます。

**Example**  
[リストに要素を追加](#Expressions.UpdateExpressions.SET.UpdatingListElements) で、5 つの要素を含むようにリスト属性 (`RelatedItems`) を変更します。  
+ `[0]`—`Chisel`
+ `[1]`—`Hammer`
+ `[2]`—`Nails`
+ `[3]`—`Screwdriver`
+ `[4]`—`Hacksaw`
次の AWS Command Line Interface (AWS CLI) の例では、リストから `Hammer` と `Nails` を削除します。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "REMOVE RelatedItems[1], RelatedItems[2]" \
    --return-values ALL_NEW
```
`Hammer` と `Nails` を削除すると、残りの要素は変わります。リストには以下が含まれます。  
+ `[0]`—`Chisel`
+ `[1]`—`Screwdriver`
+ `[2]`—`Hacksaw`

## ADD — 数値とセットの更新
<a name="Expressions.UpdateExpressions.ADD"></a>

**注記**  
一般的に、べき等なオペレーションを確保するために `ADD` ではなく `SET` を使用することをお勧めします。

項目に新しい属性および値を追加するには、更新式で `ADD` アクションを使用します。

属性が既に存在する場合、`ADD` の動作は属性のデータ型によって決まります。
+ 属性が数値で、追加する値も数値である場合、値は既存の属性に数学的に追加されます (値が負の数値である場合は、既存の属性から減算されます)。
+ 属性が設定され、追加する値も設定された場合、値は既存のセットに付加されます。

**注記**  
`ADD` アクションでは、数値とセットデータ型のみがサポートされます。

複数の `ADD` アクションを実行するには、オペレーションをカンマで区切ります。

次の構文の概要について説明します。
+ *path* 要素は、属性へのドキュメントパスです。属性は `Number` またはセットデータ型である必要があります。
+ *value* 要素は、属性に追加する数値 (`Number` データ型の場合)、または属性に付加するセット (セット型の場合) です。

```
add-action ::=
    path value
```

以下のトピックでは、`ADD` アクションのさまざまなユースケースについて説明します。

**Topics**
+ [数値の追加](#Expressions.UpdateExpressions.ADD.Number)
+ [セットに要素を追加](#Expressions.UpdateExpressions.ADD.Set)

### 数値の追加
<a name="Expressions.UpdateExpressions.ADD.Number"></a>

`QuantityOnHand` 属性が存在しないと想定します。次の AWS CLI の例では、`QuantityOnHand` を 5 に設定します。

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "ADD QuantityOnHand :q" \
    --expression-attribute-values '{":q": {"N": "5"}}' \
    --return-values ALL_NEW
```

これで `QuantityOnHand` が存在するようになったので、`QuantityOnHand` が毎回 5 増分するように例を再実行できます。

### セットに要素を追加
<a name="Expressions.UpdateExpressions.ADD.Set"></a>

`Color` 属性が存在しないと想定します。次の AWS CLI の例では、`Color` を 2 つの要素を持つ文字列セットに設定します。

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "ADD Color :c" \
    --expression-attribute-values '{":c": {"SS":["Orange", "Purple"]}}' \
    --return-values ALL_NEW
```

これで `Color` が存在するので、さらに要素を追加できます。

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "ADD Color :c" \
    --expression-attribute-values '{":c": {"SS":["Yellow", "Green", "Blue"]}}' \
    --return-values ALL_NEW
```

## DELETE — セットから要素を削除
<a name="Expressions.UpdateExpressions.DELETE"></a>

**重要**  
`DELETE` は `Set` データ型のみをサポートします。

1 つ以上の要素をセットから削除するには、更新式で `DELETE` アクションを使用します。複数の `DELETE` アクションを実行するには、オペレーションをカンマで区切ります。

次の構文の概要について説明します。
+ *path* 要素は、属性へのドキュメントパスです。属性はセットデータ型である必要があります。
+ *サブセット*は *path* から削除する 1 つ以上の要素です。*サブセット*はセット型として指定する必要があります。

```
delete-action ::=
    path subset
```

**Example**  
[セットに要素を追加](#Expressions.UpdateExpressions.ADD.Set) で、`Color` 文字列セットを作成します。この例では、セットから要素の一部を削除します。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "DELETE Color :p" \
    --expression-attribute-values '{":p": {"SS": ["Yellow", "Purple"]}}' \
    --return-values ALL_NEW
```

## 複数の更新式を使用する
<a name="Expressions.UpdateExpressions.Multiple"></a>

単一の更新式で複数のアクションを使用できます。すべての属性参照は、いずれかのアクションが適用される前に、項目の状態に対して解決されます。

**Example**  
項目 `{"id": "1", "a": 1, "b": 2, "c": 3}` を指定すると、次の式は `a` を削除し、`b` と `c` の値をシフトします。  

```
aws dynamodb update-item \
    --table-name test \
    --key '{"id":{"S":"1"}}' \
    --update-expression "REMOVE a SET b = a, c = b" \
    --return-values ALL_NEW
```
結果は、`{"id": "1", "b": 1, "c": 2}` です。同じ式で `a` が削除され、`b` が再割り当てされても、両方の参照は元の値に解決されます。

**Example**  
属性の値を変更して別の属性を完全に削除したい場合は、SET アクションと REMOVE アクションを 1 つのステートメントで使用できます。このオペレーションでは、`Price` 値を 15 に減らし、項目から `InStock` 属性も削除します。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET Price = Price - :p REMOVE InStock" \
    --expression-attribute-values '{":p": {"N":"15"}}' \
    --return-values ALL_NEW
```

**Example**  
リストに追加しつつ別の属性の値も変更したい場合は、1 つのステートメントで 2 つの SET アクションを使用できます。このオペレーションでは、`RelatedItems` リスト属性に「Nails」が追加され、`Price` 値も 21 に設定されます。  

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"789"}}' \
    --update-expression "SET RelatedItems[1] = :newValue, Price = :newPrice" \
    --expression-attribute-values '{":newValue": {"S":"Nails"}, ":newPrice": {"N":"21"}}'  \
    --return-values ALL_NEW
```

# DynamoDB の条件式とフィルター式、演算子、関数
<a name="Expressions.OperatorsAndFunctions"></a>

Amazon DynamoDB テーブルのデータを操作するには、`PutItem`、`UpdateItem`、`DeleteItem` の各オペレーションを使用します。これらのデータ操作オペレーションでは、どの項目を修正する必要があるかを判断するために、条件式を指定できます。条件式が true と評価される場合、オペレーションは成功します。それ以外の場合は、このオペレーションは失敗します。

このセクションでは、Amazon DynamoDB の書き込みフィルター式と条件式の組み込み関数およびキーワードについて説明します。DynamoDB で使用する関数とプログラミングの詳細については、「[DynamoDB と AWS SDK を使用したプログラミング](Programming.md)」と「[DynamoDB API リファレンス](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/)」を参照してください。

**Topics**
+ [フィルター式と条件式の構文](#Expressions.OperatorsAndFunctions.Syntax)
+ [比較の実行](#Expressions.OperatorsAndFunctions.Comparators)
+ [関数](#Expressions.OperatorsAndFunctions.Functions)
+ [論理評価](#Expressions.OperatorsAndFunctions.LogicalEvaluations)
+ [括弧](#Expressions.OperatorsAndFunctions.Parentheses)
+ [条件の優先順位](#Expressions.OperatorsAndFunctions.Precedence)

## フィルター式と条件式の構文
<a name="Expressions.OperatorsAndFunctions.Syntax"></a>

以下の構文の概要で、*operand* は次のいずれかです。
+ 最上位の属性名 (`Id`、`Title`、`Description`、`ProductCategory` など)
+ 入れ子の属性を参照するドキュメントパス

```
condition-expression ::=
      operand comparator operand
    | operand BETWEEN operand AND operand
    | operand IN ( operand (',' operand (, ...) ))
    | function
    | condition AND condition
    | condition OR condition
    | NOT condition
    | ( condition )

comparator ::=
    =
    | <>
    | <
    | <=
    | >
    | >=

function ::=
    attribute_exists (path)
    | attribute_not_exists (path)
    | attribute_type (path, type)
    | begins_with (path, substr)
    | contains (path, operand)
    | size (path)
```

## 比較の実行
<a name="Expressions.OperatorsAndFunctions.Comparators"></a>

これらのコンパレータを使用して、オペランドを単一の値と比較します。
+ `a = b` — *a* が *b* と等しい場合、True
+ `a <> b` — *a* が *b* と等しくない場合、True
+ `a < b` — *a* が *b* 未満の場合、True
+ `a <= b` — *a* が *b* 以下である場合、True
+ `a > b` — *a* が *b* より大きい場合、True
+ `a >= b` — *a* が *b* 以上である場合、True

値の範囲または値の列挙リストに対してオペランドを比較するには、`BETWEEN` および `IN` キーワードを使用します。
+ `a BETWEEN b AND c` - *a* が *b* 以上で、*c* 以下である場合、True。
+ `a IN (b, c, d) ` — *a* がリスト内の任意の値と等しい場合、True。例では、*b*、*c*、*d* のいずれかと等しい場合。リストには、コンマで区切って最大 100 個の値を指定できます。

## 関数
<a name="Expressions.OperatorsAndFunctions.Functions"></a>

以下の関数を使用して、ある属性が項目に存在するか判定したり、属性の値を評価したりします。これらの関数名では大文字と小文字が区別されます。入れ子の属性では、完全ドキュメントパスを指定する必要があります。


****  

| 関数 | 説明 | 
| --- | --- | 
|  `attribute_exists (path)`  | 項目に、`path` で指定した属性が含まれる場合、true。 例: `Product` テーブルの項目に側面図があるかどうかを確認します。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  | 
|  `attribute_not_exists (path)`  | `path` で指定した属性が項目に存在しない場合、true。 例: 項目に `Manufacturer` 属性があるかどうかを確認します。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  | 
|  `attribute_type (path, type)`  |  指定したパスの属性が、特定のデータ型のものである場合、true。`type` パラメータは次のいずれかである必要があります。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) `type` パラメータには、式の属性値を使用する必要があります。 例: `QuantityOnHand` 属性がリスト型のものであるかどうかを確認します。この例では、`:v_sub` は文字列 `L` のプレースホルダーです。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) `type` パラメータには、式の属性値を使用する必要があります。  | 
|  `begins_with (path, substr)`  |  `path` で指定された属性が特定のサブ文字列から始まる場合、true。 例: 正面図 URL の最初の数文字が `http://` かどうかを確認します。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) 式の属性値 `:v_sub` は、`http://` のプレースホルダーです。  | 
|  `contains (path, operand)`  | `path` で指定された属性が次の属性である場合、true。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) `path` で指定された属性が `String` である場合、`operand` は `String` である必要があります。`path` で指定された属性が `Set` の場合、`operand` は一連の要素タイプである必要があります。 パスとオペランドは区別する必要があります。つまり、`contains (a, a)` がエラーを返します。 例: `Brand` 属性にサブ文字列 `Company` が含まれているかどうかを確認します。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) 式の属性値 `:v_sub` は、`Company` のプレースホルダーです。 例: 製品が赤で入手可能かどうかを確認します。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html) 式の属性値 `:v_sub` は、`Red` のプレースホルダーです。 | 
|  `size (path)`  | 属性のサイズを表す数値を返します。以下は、`size` で使用できる有効なデータ型です。  属性は `String` 型で、`size` は文字列の長さを返します。 例: 文字列 `Brand` が 20 文字以下であるかどうかを確認します。式の属性値 `:v_sub` は、`20` のプレースホルダーです。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  属性が `Binary` バイナリ型の場合、`size` は属性値のバイト数を返します。 例: `ProductCatalog` 項目に `VideoClip` という名前のバイナリ属性があるとします。この属性には使用中の製品の短いビデオが含まれます。次の式は、`VideoClip` が 64,000 バイトを超えるかどうかを確認します。式の属性値 `:v_sub` は、`64000` のプレースホルダーです。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  属性が `Set` データ型の場合、`size` は設定の要素数を返します。 例: 製品が複数の色で入手可能かどうかを確認します。式の属性値 `:v_sub` は、`1` のプレースホルダーです。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  属性が `List` 型または `Map` のものである場合、`size` は子要素の数を返します。 例: `OneStar` のレビューの数が特定のしきい値を超えたかどうかを確認します。式の属性値 `:v_sub` は、`3` のプレースホルダーです。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html)  | 

## 論理評価
<a name="Expressions.OperatorsAndFunctions.LogicalEvaluations"></a>

論理評価を実行するには、`AND`、`OR`、`NOT` キーワードを使用します。以下のリストでは、*a* と *b* は評価される条件を示しています。
+ `a AND b` — *a* と *b* の両方が true である場合、True。
+ `a OR b` — *a* または *b* のどちらか (または両方) が true の場合、True。
+ `NOT a`— *a* が false の場合は True。*a* が true の場合は Falsee。

以下は、オペレーションの AND のコード例です。

`dynamodb-local (*)> select * from exprtest where a > 3 and a < 5;`

## 括弧
<a name="Expressions.OperatorsAndFunctions.Parentheses"></a>

論理評価の優先順位を変更するには括弧を使用します。たとえば、条件 *a* と *b* が true で、条件 *c* が false であるとします。次の式は true と評価されます。
+ `a OR b AND c`

しかし、条件を括弧で囲むと、それが最初に評価されます。たとえば、次の式は false と評価されます。
+  `(a OR b) AND c`

**注記**  
式では括弧を入れ子にできます。最も内側の括弧が最初に評価されます。

以下は、論理評価で括弧を付けたコード例です。

`dynamodb-local (*)> select * from exprtest where attribute_type(b, string) or ( a = 5 and c = “coffee”);`

## 条件の優先順位
<a name="Expressions.OperatorsAndFunctions.Precedence"></a>

 DynamoDB では、条件は次の優先順位ルールを使用して左から右に評価されます。
+ `= <> < <= > >=`
+ `IN`
+ `BETWEEN`
+ `attribute_exists attribute_not_exists begins_with contains`
+ 括弧
+ `NOT`
+ `AND`
+ `OR`

# DynamoDB 条件式 CLI の例
<a name="Expressions.ConditionExpressions"></a>

条件式を使用する AWS Command Line Interface (AWS CLI) の例のいくつかを次に示します。これらの例は、「`ProductCatalog`」で紹介されている [DynamoDB で式を使用する場合の項目属性の参照](Expressions.Attributes.md) テーブルに基づいています。このテーブルのパーティションキーは `Id` です。ソートキーはありません。次の `PutItem` オペレーションは、例で参照するサンプル `ProductCatalog` 項目を作成します。

```
aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json
```

`--item` の引数は、ファイル `item.json` に保存されます。(分かりやすいように、いくつかの項目属性のみが使用されます)

```
{
    "Id": {"N": "456" },
    "ProductCategory": {"S": "Sporting Goods" },
    "Price": {"N": "650" }
}
```

**Topics**
+ [条件付き配置](#Expressions.ConditionExpressions.PreventingOverwrites)
+ [条件付き削除](#Expressions.ConditionExpressions.AdvancedComparisons)
+ [条件付き更新](#Expressions.ConditionExpressions.SimpleComparisons)
+ [条件式の例](#Expressions.ConditionExpressions.ConditionalExamples)

## 条件付き配置
<a name="Expressions.ConditionExpressions.PreventingOverwrites"></a>

`PutItem` オペレーションはプライマリキーが同じ項目を上書きします (存在する場合)。これを回避するには、条件式を使用します。これにより、問題の項目が同じプライマリキーを持っていない場合にのみ書き込みが続行されます。

次の例では、`attribute_not_exists()` を使用して、書き込み操作を試みる前に、プライマリキーがテーブルに存在するかどうかを確認しています。

**注記**  
プライマリキーがパーティションキー (pk) とソートキー (sk) の両方で構成されている場合、このパラメータは、書き込みオペレーションを試みる前に `attribute_not_exists(pk)` と `attribute_not_exists(sk)` の両方がステートメント全体として true または false のどちらに評価されるのかを確認します。

```
aws dynamodb put-item \
    --table-name ProductCatalog \
    --item file://item.json \
    --condition-expression "attribute_not_exists(Id)"
```

条件式が false と評価し、DynamoDB は次のエラーメッセージを返します。条件付きリクエストが失敗しました。

**注記**  
`attribute_not_exists` および他の関数についての詳細は、「[DynamoDB の条件式とフィルター式、演算子、関数](Expressions.OperatorsAndFunctions.md)」を参照してください。

## 条件付き削除
<a name="Expressions.ConditionExpressions.AdvancedComparisons"></a>

条件付き削除を実行するには、条件式とともに `DeleteItem` オペレーションを使用します。条件式は、オペレーションが成功するためには true に評価される必要があります。それ以外の場合、オペレーションは失敗します。

上で定義した項目について考えてみます。

次の条件を満たしている場合にだけ項目を削除するとします。
+  `ProductCategory` は「Sporting Goods」または「Gardening Supplies」のどちらかです。
+  `Price` は 500～600 です。

次の例では、項目を削除しようとしています。

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id":{"N":"456"}}' \
    --condition-expression "(ProductCategory IN (:cat1, :cat2)) and (Price between :lo and :hi)" \
    --expression-attribute-values file://values.json
```

`--expression-attribute-values` の引数は、ファイル `values.json` に保存されます。

```
{
    ":cat1": {"S": "Sporting Goods"},
    ":cat2": {"S": "Gardening Supplies"},
    ":lo": {"N": "500"},
    ":hi": {"N": "600"}
}
```

**注記**  
条件式では、`:` (コロン文字) は*式の属性値* (実際の値のプレースホルダー) を示します。詳細については、「」を参照してください[DynamoDB での式属性値の使用](Expressions.ExpressionAttributeValues.md)  
`IN`、`AND` およびその他のキーワードについての詳細は、「[DynamoDB の条件式とフィルター式、演算子、関数](Expressions.OperatorsAndFunctions.md)」を参照してください。

この例では、`ProductCategory` 比較の評価結果は true になりますが、`Price` 比較は false と評価されます。これにより、条件式は false と評価され、`DeleteItem` オペレーションは失敗します。

## 条件付き更新
<a name="Expressions.ConditionExpressions.SimpleComparisons"></a>

条件付き更新を実行するには、条件式とともに `UpdateItem` オペレーションを使用します。条件式は、オペレーションが成功するためには true に評価される必要があります。それ以外の場合、オペレーションは失敗します。

**注記**  
`UpdateItem` は*更新式*もサポートします。項目に加える変更を指定する変更内容を指定します。詳細については、「[DynamoDB での更新式の使用](Expressions.UpdateExpressions.md)」を参照してください。

上で定義した項目から開始するとします。

次の例では、`UpdateItem` オペレーションを実行します。製品の `Price` を 75 減らしようとしていますが、現在の `Price` が 500 以下の場合、条件式が更新を防ぎます。

```
aws dynamodb update-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --update-expression "SET Price = Price - :discount" \
    --condition-expression "Price > :limit" \
    --expression-attribute-values file://values.json
```

`--expression-attribute-values` の引数は、ファイル `values.json` に保存されます。

```
{
    ":discount": { "N": "75"},
    ":limit": {"N": "500"}
}
```

開始 `Price` が 650 の場合、`UpdateItem` オペレーションによって `Price` は 575 に下げられます。`UpdateItem` アクションを再度実行すると、`Price` は 500 に減らされます。3 度目に実行した場合、条件式は false と評価されて、更新は失敗します。

**注記**  
条件式では、`:` (コロン文字) は*式の属性値* (実際の値のプレースホルダー) を示します。詳細については、「[DynamoDB での式属性値の使用](Expressions.ExpressionAttributeValues.md)」を参照してください。  
「*>*」およびその他の演算子についての詳細は、「[DynamoDB の条件式とフィルター式、演算子、関数](Expressions.OperatorsAndFunctions.md)」を参照してください。

## 条件式の例
<a name="Expressions.ConditionExpressions.ConditionalExamples"></a>

次の例で使用される関数の詳細については、「[DynamoDB の条件式とフィルター式、演算子、関数](Expressions.OperatorsAndFunctions.md)」を参照してください。式で異なる属性タイプを指定する方法の詳細については、「[DynamoDB で式を使用する場合の項目属性の参照](Expressions.Attributes.md)」を参照してください。

### 項目の属性を確認
<a name="Expressions.ConditionExpressions.CheckingForAttributes"></a>

属性が存在するか (または存在しないか) を確認できます。条件式が true と評価される場合、オペレーションは成功で、それ以外の場合、オペレーションは失敗です。

次の例では、`attribute_not_exists` 属性がない場合にのみ製品を削除するために `Price` を使用します。

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "attribute_not_exists(Price)"
```

DynamoDB は `attribute_exists` 関数も提供します。次の例では、悪いレビューを受け取った場合のみ製品を削除します。

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "attribute_exists(ProductReviews.OneStar)"
```

### 属性タイプの確認
<a name="Expressions.ConditionExpressions.CheckingForAttributeType"></a>

属性値のデータ型は、`attribute_type` 関数を使用して確認できます。条件式が true と評価される場合、オペレーションは成功で、それ以外の場合、オペレーションは失敗です。

次の例では、`attribute_type` を使用して、文字列セットタイプの `Color` 属性がある場合にのみ、製品を削除します。

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "attribute_type(Color, :v_sub)" \
    --expression-attribute-values file://expression-attribute-values.json
```

`--expression-attribute-values` の引数は、expression-attribute-values.json ファイルに格納されます。

```
{
    ":v_sub":{"S":"SS"}
}
```

### 文字列開始値の確認
<a name="Expressions.ConditionExpressions.CheckingBeginsWith"></a>

文字列属性値が特定のサブ文字列で始まるかどうかを確認するには、`begins_with` 関数を使用します。条件式が true と評価される場合、オペレーションは成功で、それ以外の場合、オペレーションは失敗です。

次の例では、`begins_with` マップの `FrontView` 要素が特定の値で始まる場合にのみ、`Pictures` を使用して製品を削除します。

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "begins_with(Pictures.FrontView, :v_sub)" \
    --expression-attribute-values file://expression-attribute-values.json
```

`--expression-attribute-values` の引数は、expression-attribute-values.json ファイルに格納されます。

```
{
    ":v_sub":{"S":"http://"}
}
```

### セット内の要素の確認
<a name="Expressions.ConditionExpressions.CheckingForContains"></a>

`contains` 関数を使用して、セット内の要素を確認したり、文字列内のサブ文字列を検索したりできます。条件式が true と評価される場合、オペレーションは成功で、それ以外の場合、オペレーションは失敗です。

次の例では、`contains` 文字列セットに特定の値を持つ要素がある場合にのみ、`Color` を使用して製品を削除します。

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "contains(Color, :v_sub)" \
    --expression-attribute-values file://expression-attribute-values.json
```

`--expression-attribute-values` の引数は、expression-attribute-values.json ファイルに格納されます。

```
{
    ":v_sub":{"S":"Red"}
}
```

### 属性値のサイズの確認
<a name="Expressions.ConditionExpressions.CheckingForSize"></a>

属性値のサイズを確認するには、`size` 関数を使用します。条件式が true と評価される場合、オペレーションは成功で、それ以外の場合、オペレーションは失敗です。

次の例では、`size` バイナリ属性のサイズが `VideoClip` バイトより大きい場合にのみ `64000` を使用して、製品を削除します。

```
aws dynamodb delete-item \
    --table-name ProductCatalog \
    --key '{"Id": {"N": "456"}}' \
    --condition-expression "size(VideoClip) > :v_sub" \
    --expression-attribute-values file://expression-attribute-values.json
```

`--expression-attribute-values` の引数は、expression-attribute-values.json ファイルに格納されます。

```
{
    ":v_sub":{"N":"64000"}
}
```

# DynamoDB での Time to Live (TTL) の使用
<a name="TTL"></a>

DynamoDB の Time to Live (TTL) は、不要になった項目を削除するためのコスト効率に優れた方法です。TTL では、項目がいつ不要になるかを示す有効期限タイムスタンプを項目ごとに定義できます。DynamoDB は、書き込みスループットを消費することなく、有効期限が切れてから数日以内に期限切れの項目を自動的に削除します。

TTL を使用するには、まずテーブルで TTL を有効にし、次に TTL の有効期限タイムスタンプを格納する特定の属性を定義します。タイムスタンプは、秒単位の [UNIX エポック時間形式](https://en.wikipedia.org/wiki/Unix_time)の[数値](HowItWorks.NamingRulesDataTypes.md#HowItWorks.DataTypes)データ型として保存する必要があります。数値型ではない TTL 属性を持つ項目は、TTL プロセスによって無視されます。項目が作成または更新されるたびに、有効期限を計算して TTL 属性に保存できます。

期限切れの有効な TTL 属性を持つ項目は、随時システムによって削除される可能性があります。削除は、通常は有効期限が切れてから数日以内に行われます。削除待ちの期限切れ項目は、TTL 属性の変更や削除を含め、引き続き更新できます。期限切れの項目を更新する際には、その項目がその後削除されないように条件式を使用することをおすすめします。フィルター式を使用して、期限切れの項目を [Scan](Scan.md#Scan.FilterExpression) 結果と [Query](Query.FilterExpression.md) 結果から削除します。

削除済みの項目は、通常の削除操作で削除された項目と同様に機能します。削除すると、項目はユーザーによる削除ではなくサービスによる削除として DynamoDB ストリームに入り、他の削除操作と同様にローカルセカンダリインデックスとグローバルセカンダリインデックスから削除されます。

[グローバルテーブルバージョン 2019.11.21 (現行)](GlobalTables.md) を使用しており、TTL 機能も使用している場合、DynamoDB は TTL による削除をすべてのレプリカテーブルにレプリケートします。最初の TTL による削除の場合、TTL の有効期限切れが発生したリージョンでは、書き込みキャパシティユニット (WCU) は消費されません。ただし、レプリカテーブルにレプリケートされた TTL 削除では、プロビジョンドキャパシティを使用する場合はレプリケートされた書き込みキャパシティユニットが消費され、オンデマンドのキャパシティモードを使用する場合はレプリケートされた書き込みユニットが各レプリカリージョンで消費され、該当する料金が適用されます。

TTL の詳細については、次のトピックを参照してください。

**Topics**
+ [DynamoDB での Time to Live (TTL) の有効化](time-to-live-ttl-how-to.md)
+ [DynamoDB での Time to Live (TTL) の計算](time-to-live-ttl-before-you-start.md)
+ [期限切れのアイテムと Time to Live (TTL) の使用](ttl-expired-items.md)

# DynamoDB での Time to Live (TTL) の有効化
<a name="time-to-live-ttl-how-to"></a>

**注記**  
TTL 機能の適切なオペレーションのデバッグと検証を支援するために、項目 TTL に指定した値は DynamoDB 診断ログにプレーンテキストとして記録されます。

TTL を有効にするには、Amazon DynamoDB コンソールまたは AWS Command Line Interface (AWS CLI) を使用するか、「[Amazon DynamoDB API リファレンス](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/)」の該当する AWS SDK のいずれかを使用できます。すべてのパーティションで TTL を有効にするには約 1 時間かかります。

## AWS コンソールを使用して DynamoDB TTL を有効にする
<a name="time-to-live-ttl-how-to-enable-console"></a>

1. AWS マネジメントコンソール にサインインして DynamoDB コンソール ([https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)) を開きます。

1. [**テーブル**] を選択し、変更するテーブルを選択します。

1. **[追加の設定]** タブの **[Time to Live (TTL)]** セクションで、**[オンにする]** を選択します。

1. テーブルで TTL を有効にする場合、DynamoDB では、項目が失効可能かどうかを判断するときにサービスが検索する、特定の属性名を識別する必要があります。以下に示す TTL 属性名では大文字と小文字が区別されます。また、TTL 属性名は読み取り/書き込み操作で定義された属性と一致する必要があります。不一致があると、期限切れの項目は削除されなくなります。TTL 属性の名前を変更するには、TTL を無効にした後で、新しい属性で TTL を再度有効にする必要があります。TTL は、無効化されてから約 30 分間、削除処理を続けます。TTL は復元されたテーブルで再設定する必要があります。  
![\[DynamoDB が項目の有効期間を決定するために使用する、大文字と小文字が区別される TTL 属性名。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/EnableTTL-Settings.png)

1. (オプション) 有効期限の日付と時刻をシミュレートし、いくつかの項目を照合することでテストを実行できます。これにより、項目のサンプルリストが提供され、指定した TTL 属性名と有効期限を含む項目があることが確認されます。

TTL を有効にすると、DynamoDB コンソールで項目を表示するときに TTL 属性に **TTL** のマークが付けられます。属性の上にポインターを合わせると、項目が期限切れになる日時を表示できます。

## API を使用して DynamoDB TTL を有効にする
<a name="time-to-live-ttl-how-to-enable-api"></a>

------
#### [ Python ]

コードで [UpdateTimeToLive](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/update_time_to_live.html) オペレーションを使用して TTL を有効にすることができます。

```
import boto3


def enable_ttl(table_name, ttl_attribute_name):
    """
    Enables TTL on DynamoDB table for a given attribute name
        on success, returns a status code of 200
        on error, throws an exception

    :param table_name: Name of the DynamoDB table
    :param ttl_attribute_name: The name of the TTL attribute being provided to the table.
    """
    try:
        dynamodb = boto3.client('dynamodb')

        # Enable TTL on an existing DynamoDB table
        response = dynamodb.update_time_to_live(
            TableName=table_name,
            TimeToLiveSpecification={
                'Enabled': True,
                'AttributeName': ttl_attribute_name
            }
        )

        # In the returned response, check for a successful status code.
        if response['ResponseMetadata']['HTTPStatusCode'] == 200:
            print("TTL has been enabled successfully.")
        else:
            print(f"Failed to enable TTL, status code {response['ResponseMetadata']['HTTPStatusCode']}")
    except Exception as ex:
        print("Couldn't enable TTL in table %s. Here's why: %s" % (table_name, ex))
        raise


# your values
enable_ttl('your-table-name', 'expirationDate')
```

TTL が有効になっていることを確認するには、[DescribeTimeToLive](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb/client/describe_time_to_live.html) オペレーションを使用してテーブルの TTL ステータスを記述します。`TimeToLive` ステータスは `ENABLED` または `DISABLED` です。

```
# create a DynamoDB client
dynamodb = boto3.client('dynamodb')

# set the table name
table_name = 'YourTable'

# describe TTL
response = dynamodb.describe_time_to_live(TableName=table_name)
```

------
#### [ JavaScript ]

コードで [UpdateTimeToLiveCommand](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-client-dynamodb/Class/UpdateTimeToLiveCommand/) オペレーションを使用して TTL を有効にすることができます。

```
import { DynamoDBClient, UpdateTimeToLiveCommand } from "@aws-sdk/client-dynamodb";

const enableTTL = async (tableName, ttlAttribute) => {

    const client = new DynamoDBClient({});

    const params = {
        TableName: tableName,
        TimeToLiveSpecification: {
            Enabled: true,
            AttributeName: ttlAttribute
        }
    };

    try {
        const response = await client.send(new UpdateTimeToLiveCommand(params));
        if (response.$metadata.httpStatusCode === 200) {
            console.log(`TTL enabled successfully for table ${tableName}, using attribute name ${ttlAttribute}.`);
        } else {
            console.log(`Failed to enable TTL for table ${tableName}, response object: ${response}`);
        }
        return response;
    } catch (e) {
        console.error(`Error enabling TTL: ${e}`);
        throw e;
    }
};

// call with your own values
enableTTL('ExampleTable', 'exampleTtlAttribute');
```

------

## AWS CLI を使用して Time to Live を有効にする
<a name="time-to-live-ttl-how-to-enable-cli-sdk"></a>

1. `TTLExample` テーブルで TTL を有効にします。

   ```
   aws dynamodb update-time-to-live --table-name TTLExample --time-to-live-specification "Enabled=true, AttributeName=ttl"
   ```

1. `TTLExample` テーブルで TTL を無効にします。

   ```
   aws dynamodb describe-time-to-live --table-name TTLExample
   {
       "TimeToLiveDescription": {
           "AttributeName": "ttl",
           "TimeToLiveStatus": "ENABLED"
       }
   }
   ```

1. BASH シェルおよび AWS CLI を使用して 有効期限 (TTL) 属性が設定された項目を `TTLExample` テーブルに追加するには: 

   ```
   EXP=`date -d '+5 days' +%s`
   aws dynamodb put-item --table-name "TTLExample" --item '{"id": {"N": "1"}, "ttl": {"N": "'$EXP'"}}'
   ```

この例では、現在の日付から開始し、有効期限を作成するために 5 日を追加します。次に、有効期限をエポック時間形式に変換してから、最後に項目を「`TTLExample`」テーブルに追加します。

**注記**  
 有効期限 (TTL) の有効期限切れの値を設定する 1 つの方法は、有効期限に追加する秒数を計算することです。たとえば、5 日間は 432,000 秒です。ただし、多くの場合は最初に日付で開始し、そこから作業を開始することをお勧めします。

次の例のように、現在の時間をエポック時間形式で取得するのは非常に簡単です。
+ Linux ターミナル: `date +%s`
+ Python: `import time; int(time.time())`
+ Java: `System.currentTimeMillis() / 1000L`
+ JavaScript: `Math.floor(Date.now() / 1000)`

## CloudFormation を使用して DynamoDB TTL を有効にします。
<a name="time-to-live-ttl-how-to-enable-cf"></a>

```
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  TTLExampleTable:
    Type: AWS::DynamoDB::Table
    Description: "A DynamoDB table with TTL Specification enabled"
    Properties:
      AttributeDefinitions:
        - AttributeName: "Album"
          AttributeType: "S"
        - AttributeName: "Artist"
          AttributeType: "S"
      KeySchema:
        - AttributeName: "Album"
          KeyType: "HASH"
        - AttributeName: "Artist"
          KeyType: "RANGE"
      ProvisionedThroughput:
        ReadCapacityUnits: "5"
        WriteCapacityUnits: "5"
      TimeToLiveSpecification:
        AttributeName: "TTLExampleAttribute"
        Enabled: true
```

CloudFormation テンプレート内で TTL を使用する方法の詳細については、[こちら](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dynamodb-table-timetolivespecification.html)を参照してください。

# DynamoDB での Time to Live (TTL) の計算
<a name="time-to-live-ttl-before-you-start"></a>

TTL を実装する一般的な方法は、作成日または最終更新日に基づいて項目の有効期限を設定することです。これは、`createdAt` タイムスタンプと `updatedAt` タイムスタンプに時間を追加することで実現できます。例えば、新しく作成されたアイテムの TTL を `createdAt` \$1 90 日に設定できます。項目が更新されると、TTL は `updatedAt` \$1 90 日に再計算されます。

計算された有効期限は、秒単位のエポック形式である必要があります。TTL が 5 年を超えて経過すると、有効期限と削除の対象外になります。他の形式を使用すると、TTL プロセスはその項目を無視します。項目の有効期限を未来の時点に設定した場合、その期間が過ぎると項目は期限切れになります。例えば、有効期限を 1724241326 (2024 年 8 月 21 日 (月) 11:55:26 (UTC)) に設定したとします。指定した時刻以降、項目は有効期限切れになります。最小 TTL 期間はありません。有効期限は、現在の時刻から 5 分後など、将来の任意の時刻に設定できます。ただし、DynamoDB は通常、期限切れの項目の有効期限が切れた直後ではなく、有効期限が切れてから 48 時間以内に削除します。

**Topics**
+ [項目を作成して Time to Live を設定する](#time-to-live-ttl-before-you-start-create)
+ [項目を更新して Time to Live を再計算する](#time-to-live-ttl-before-you-start-update)

## 項目を作成して Time to Live を設定する
<a name="time-to-live-ttl-before-you-start-create"></a>

次の例は、`expireAt` を TTL 属性名として使用して、新しいアイテムを作成するときに有効期限を計算する方法を示しています。代入ステートメントは、現在の時刻を変数として取得します。この例では、有効期限は現在の時刻から 90 日後として計算されます。その後、時刻はエポック形式に変換され、TTL 属性に整数データ型として保存されます。

次のコード例は、TTL を含む項目の作成方法を示しています。

------
#### [ Java ]

**SDK for Java 2.x**  

```
package com.amazon.samplelib.ttl;

import com.amazon.samplelib.CodeSampleUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.PutItemResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * Creates an item in a DynamoDB table with TTL attributes.
 * This class demonstrates how to add TTL expiration timestamps to DynamoDB items.
 */
public class CreateTTL {

    private static final String USAGE =
        """
            Usage:
                <tableName> <primaryKey> <sortKey> <region>
            Where:
                tableName - The Amazon DynamoDB table being queried.
                primaryKey - The name of the primary key. Also known as the hash or partition key.
                sortKey - The name of the sort key. Also known as the range attribute.
                region (optional) - The AWS region that the Amazon DynamoDB table is located in. (Default: us-east-1)
            """;
    private static final int DAYS_TO_EXPIRE = 90;
    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
    private static final String PRIMARY_KEY_ATTR = "primaryKey";
    private static final String SORT_KEY_ATTR = "sortKey";
    private static final String CREATION_DATE_ATTR = "creationDate";
    private static final String EXPIRE_AT_ATTR = "expireAt";
    private static final String SUCCESS_MESSAGE = "%s PutItem operation with TTL successful.";
    private static final String TABLE_NOT_FOUND_ERROR = "Error: The Amazon DynamoDB table \"%s\" can't be found.";

    private final DynamoDbClient dynamoDbClient;

    /**
     * Constructs a CreateTTL instance with the specified DynamoDB client.
     *
     * @param dynamoDbClient The DynamoDB client to use
     */
    public CreateTTL(final DynamoDbClient dynamoDbClient) {
        this.dynamoDbClient = dynamoDbClient;
    }

    /**
     * Constructs a CreateTTL with a default DynamoDB client.
     */
    public CreateTTL() {
        this.dynamoDbClient = null;
    }

    /**
     * Main method to demonstrate creating an item with TTL.
     *
     * @param args Command line arguments
     */
    public static void main(final String[] args) {
        try {
            int result = new CreateTTL().processArgs(args);
            System.exit(result);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }

    /**
     * Process command line arguments and create an item with TTL.
     *
     * @param args Command line arguments
     * @return 0 if successful, non-zero otherwise
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     * @throws IllegalArgumentException If arguments are invalid
     */
    public int processArgs(final String[] args) {
        // Argument validation (remove or replace this line when reusing this code)
        CodeSampleUtils.validateArgs(args, new int[] {3, 4}, USAGE);

        final String tableName = args[0];
        final String primaryKey = args[1];
        final String sortKey = args[2];
        final Region region = Optional.ofNullable(args.length > 3 ? args[3] : null)
            .map(Region::of)
            .orElse(Region.US_EAST_1);

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final CreateTTL createTTL = new CreateTTL(ddb);
            createTTL.createItemWithTTL(tableName, primaryKey, sortKey);
            return 0;
        } catch (Exception e) {
            throw e;
        }
    }

    /**
     * Creates an item in the specified table with TTL attributes.
     *
     * @param tableName The name of the table
     * @param primaryKeyValue The value for the primary key
     * @param sortKeyValue The value for the sort key
     * @return The response from the PutItem operation
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     */
    public PutItemResponse createItemWithTTL(
        final String tableName, final String primaryKeyValue, final String sortKeyValue) {
        // Get current time in epoch second format
        final long createDate = System.currentTimeMillis() / 1000;

        // Calculate expiration time 90 days from now in epoch second format
        final long expireDate = createDate + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        final Map<String, AttributeValue> itemMap = new HashMap<>();
        itemMap.put(
            PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKeyValue).build());
        itemMap.put(SORT_KEY_ATTR, AttributeValue.builder().s(sortKeyValue).build());
        itemMap.put(
            CREATION_DATE_ATTR,
            AttributeValue.builder().n(String.valueOf(createDate)).build());
        itemMap.put(
            EXPIRE_AT_ATTR,
            AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final PutItemRequest request =
            PutItemRequest.builder().tableName(tableName).item(itemMap).build();

        try {
            final PutItemResponse response = dynamoDbClient.putItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return response;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
}
```
+  API の詳細については、AWS SDK for Java 2.x API リファレンスの「[PutItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/PutItem)」を参照してください。**

------
#### [ JavaScript ]

**SDK for JavaScript (v3)**  

```
import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";

export function createDynamoDBItem(table_name, region, partition_key, sort_key) {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    // Get the current time in epoch second format
    const current_time = Math.floor(new Date().getTime() / 1000);

    // Calculate the expireAt time (90 days from now) in epoch second format
    const expire_at = Math.floor((new Date().getTime() + 90 * 24 * 60 * 60 * 1000) / 1000);

    // Create DynamoDB item
    const item = {
        'partitionKey': {'S': partition_key},
        'sortKey': {'S': sort_key},
        'createdAt': {'N': current_time.toString()},
        'expireAt': {'N': expire_at.toString()}
    };

    const putItemCommand = new PutItemCommand({
        TableName: table_name,
        Item: item,
        ProvisionedThroughput: {
            ReadCapacityUnits: 1,
            WriteCapacityUnits: 1,
        },
    });

    client.send(putItemCommand, function(err, data) {
        if (err) {
            console.log("Exception encountered when creating item %s, here's what happened: ", data, err);
            throw err;
        } else {
            console.log("Item created successfully: %s.", data);
            return data;
        }
    });
}

// Example usage (commented out for testing)
// createDynamoDBItem('your-table-name', 'us-east-1', 'your-partition-key-value', 'your-sort-key-value');
```
+  API の詳細については、*AWS SDK for JavaScript API リファレンス*の「[PutItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/PutItemCommand)」を参照してください。

------
#### [ Python ]

**SDK for Python (Boto3)**  

```
from datetime import datetime, timedelta

import boto3


def create_dynamodb_item(table_name, region, primary_key, sort_key):
    """
    Creates a DynamoDB item with an attached expiry attribute.

    :param table_name: Table name for the boto3 resource to target when creating an item
    :param region: string representing the AWS region. Example: `us-east-1`
    :param primary_key: one attribute known as the partition key.
    :param sort_key: Also known as a range attribute.
    :return: Void (nothing)
    """
    try:
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Get the current time in epoch second format
        current_time = int(datetime.now().timestamp())

        # Calculate the expiration time (90 days from now) in epoch second format
        expiration_time = int((datetime.now() + timedelta(days=90)).timestamp())

        item = {
            "primaryKey": primary_key,
            "sortKey": sort_key,
            "creationDate": current_time,
            "expireAt": expiration_time,
        }
        response = table.put_item(Item=item)

        print("Item created successfully.")
        return response
    except Exception as e:
        print(f"Error creating item: {e}")
        raise e


# Use your own values
create_dynamodb_item(
    "your-table-name", "us-west-2", "your-partition-key-value", "your-sort-key-value"
)
```
+  API の詳細については、「*AWS SDK for Python (Boto3) API リファレンス*」の「[PutItem](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/PutItem)」を参照してください。

------

## 項目を更新して Time to Live を再計算する
<a name="time-to-live-ttl-before-you-start-update"></a>

この例は、[前のセクション](#time-to-live-ttl-before-you-start-create)の例の続きです。項目が更新された場合、有効期限を再計算できます。次の例では、`expireAt` タイムスタンプを現在の時刻から 90 日後として再計算します。

以下のコード例は、項目の TTL の更新方法を示しています。

------
#### [ Java ]

**SDK for Java 2.x**  
テーブル内の既存の DynamoDB 項目の TTL を更新します。  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

    public UpdateItemResponse updateItemWithTTL(
        final String tableName, final String primaryKeyValue, final String sortKeyValue) {
        // Get current time in epoch second format
        final long currentTime = System.currentTimeMillis() / 1000;

        // Calculate expiration time 90 days from now in epoch second format
        final long expireDate = currentTime + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        // Create the key map for the item to update
        final Map<String, AttributeValue> keyMap = new HashMap<>();
        keyMap.put(PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKeyValue).build());
        keyMap.put(SORT_KEY_ATTR, AttributeValue.builder().s(sortKeyValue).build());

        // Create the expression attribute values
        final Map<String, AttributeValue> expressionAttributeValues = new HashMap<>();
        expressionAttributeValues.put(
            ":c", AttributeValue.builder().n(String.valueOf(currentTime)).build());
        expressionAttributeValues.put(
            ":e", AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final UpdateItemRequest request = UpdateItemRequest.builder()
            .tableName(tableName)
            .key(keyMap)
            .updateExpression(UPDATE_EXPRESSION)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try {
            final UpdateItemResponse response = dynamoDbClient.updateItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return response;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
```
+  API の詳細については、AWS SDK for Java 2.x API リファレンスの**「[UpdateItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateItem)」を参照してください。

------
#### [ JavaScript ]

**SDK for JavaScript (v3)**  

```
import { DynamoDBClient, UpdateItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const updateItem = async (tableName, partitionKey, sortKey, region = 'us-east-1') => {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    const currentTime = Math.floor(Date.now() / 1000);
    const expireAt = Math.floor((Date.now() + 90 * 24 * 60 * 60 * 1000) / 1000);

    const params = {
        TableName: tableName,
        Key: marshall({
            partitionKey: partitionKey,
            sortKey: sortKey
        }),
        UpdateExpression: "SET updatedAt = :c, expireAt = :e",
        ExpressionAttributeValues: marshall({
            ":c": currentTime,
            ":e": expireAt
        }),
    };

    try {
        const data = await client.send(new UpdateItemCommand(params));
        const responseData = unmarshall(data.Attributes);
        console.log("Item updated successfully: %s", responseData);
        return responseData;
    } catch (err) {
        console.error("Error updating item:", err);
        throw err;
    }
}

// Example usage (commented out for testing)
// updateItem('your-table-name', 'your-partition-key-value', 'your-sort-key-value');
```
+  API の詳細については、*AWS SDK for JavaScript API リファレンス*の「[UpdateItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/UpdateItemCommand)」を参照してください。

------
#### [ Python ]

**SDK for Python (Boto3)**  

```
from datetime import datetime, timedelta

import boto3


def update_dynamodb_item(table_name, region, primary_key, sort_key):
    """
    Update an existing DynamoDB item with a TTL.
    :param table_name: Name of the DynamoDB table
    :param region: AWS Region of the table - example `us-east-1`
    :param primary_key: one attribute known as the partition key.
    :param sort_key: Also known as a range attribute.
    :return: Void (nothing)
    """
    try:
        # Create the DynamoDB resource.
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Get the current time in epoch second format
        current_time = int(datetime.now().timestamp())

        # Calculate the expireAt time (90 days from now) in epoch second format
        expire_at = int((datetime.now() + timedelta(days=90)).timestamp())

        table.update_item(
            Key={"partitionKey": primary_key, "sortKey": sort_key},
            UpdateExpression="set updatedAt=:c, expireAt=:e",
            ExpressionAttributeValues={":c": current_time, ":e": expire_at},
        )

        print("Item updated successfully.")
    except Exception as e:
        print(f"Error updating item: {e}")


# Replace with your own values
update_dynamodb_item(
    "your-table-name", "us-west-2", "your-partition-key-value", "your-sort-key-value"
)
```
+  API の詳細については、[AWS SDK for Python (Boto3) API リファレンス](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/UpdateItem)の「*UpdateItem*」を参照してください。

------

この概要で説明した TTL の例は、最近更新された項目だけをテーブルに保持する方法を示しています。更新された項目は有効期限が延びますが、作成後に更新されなかった項目は有効期限が切れて無料で削除されるため、ストレージが削減され、テーブルが整理されます。

# 期限切れのアイテムと Time to Live (TTL) の使用
<a name="ttl-expired-items"></a>

削除が保留になっている期限切れのアイテムは、読み取り操作と書き込み操作の対象から除外できます。これは、期限切れのデータが無効になり、使用すべきではなくなった場合に役に立ちます。フィルターが適用されていないと、バックグラウンドプロセスによって削除されるまで、読み取り/書き込み操作で引き続き表示されます。

**注記**  
これらのアイテムは、削除されるまではストレージコストと読み取りコストにカウントされます。

TTL 削除は DynamoDB ストリームで確認できますが、削除が行われたリージョンでのみ確認できます。グローバルテーブルリージョンにレプリケートされた TTL 削除は、削除がレプリケートされたリージョンの DynamoDB ストリームでは確認できません。

## 期限切れの項目を読み取り操作から除外する
<a name="ttl-expired-items-filter"></a>

[Scan](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html) や [Query](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html) などの読み取り操作では、フィルター式を使用して削除待ちの期限切れアイテムを除外できます。次のコードスニペットに示すように、フィルター式は TTL 時間が現在の時刻と同等または未満の項目を除外できます。例えば、Python SDK コードには、現在の時刻を変数 (`now`) として取得し、それをエポック時間形式の `int` に変換する代入ステートメントが含まれています。

以下のコード例は、TTL 項目のクエリの開始方法を示しています。

------
#### [ Java ]

**SDK for Java 2.x**  
AWS SDK for Java 2.x を使用しフィルタリングされた式をクエリして、DynamoDB テーブル内の TTL 項目を収集します。  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
import software.amazon.awssdk.services.dynamodb.model.QueryResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;

import java.util.Map;
import java.util.Optional;

        final QueryRequest request = QueryRequest.builder()
            .tableName(tableName)
            .keyConditionExpression(KEY_CONDITION_EXPRESSION)
            .filterExpression(FILTER_EXPRESSION)
            .expressionAttributeNames(expressionAttributeNames)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final QueryResponse response = ddb.query(request);
            System.out.println("Query successful. Found " + response.count() + " items that have not expired yet.");

            // Print each item
            response.items().forEach(item -> {
                System.out.println("Item: " + item);
            });

            return 0;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
```
+  API の詳細については、*AWS SDK for Java 2.x API リファレンス*の「[Query](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/Query)」を参照してください。

------
#### [ JavaScript ]

**SDK for JavaScript (v3)**  
AWS SDK for JavaScript を使用しフィルタリングされた式をクエリして、DynamoDB テーブル内の TTL 項目を収集します。  

```
import { DynamoDBClient, QueryCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const queryFiltered = async (tableName, primaryKey, region = 'us-east-1') => {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    const currentTime = Math.floor(Date.now() / 1000);

    const params = {
        TableName: tableName,
        KeyConditionExpression: "#pk = :pk",
        FilterExpression: "#ea > :ea",
        ExpressionAttributeNames: {
            "#pk": "primaryKey",
            "#ea": "expireAt"
        },
        ExpressionAttributeValues: marshall({
            ":pk": primaryKey,
            ":ea": currentTime
        })
    };

    try {
        const { Items } = await client.send(new QueryCommand(params));
        Items.forEach(item => {
            console.log(unmarshall(item))
        });
        return Items;
    } catch (err) {
        console.error(`Error querying items: ${err}`);
        throw err;
    }
}

// Example usage (commented out for testing)
// queryFiltered('your-table-name', 'your-partition-key-value');
```
+  API の詳細については、*AWS SDK for JavaScript API リファレンス*の「[Query](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/QueryCommand)」を参照してください。

------
#### [ Python ]

**SDK for Python (Boto3)**  
AWS SDK for Python (Boto3) を使用しフィルタリングされた式をクエリして、DynamoDB テーブル内の TTL 項目を収集します。  

```
from datetime import datetime

import boto3


def query_dynamodb_items(table_name, partition_key):
    """

    :param table_name: Name of the DynamoDB table
    :param partition_key:
    :return:
    """
    try:
        # Initialize a DynamoDB resource
        dynamodb = boto3.resource("dynamodb", region_name="us-east-1")

        # Specify your table
        table = dynamodb.Table(table_name)

        # Get the current time in epoch format
        current_time = int(datetime.now().timestamp())

        # Perform the query operation with a filter expression to exclude expired items
        # response = table.query(
        #    KeyConditionExpression=boto3.dynamodb.conditions.Key('partitionKey').eq(partition_key),
        #    FilterExpression=boto3.dynamodb.conditions.Attr('expireAt').gt(current_time)
        # )
        response = table.query(
            KeyConditionExpression=dynamodb.conditions.Key("partitionKey").eq(partition_key),
            FilterExpression=dynamodb.conditions.Attr("expireAt").gt(current_time),
        )

        # Print the items that are not expired
        for item in response["Items"]:
            print(item)

    except Exception as e:
        print(f"Error querying items: {e}")


# Call the function with your values
query_dynamodb_items("Music", "your-partition-key-value")
```
+  API の詳細については、「*AWS SDK for Python (Boto3) API リファレンス*」の「[Query](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/Query)」を参照してください。

------

## 期限切れのアイテムに条件付きで書き込む
<a name="ttl-expired-items-conditional-write"></a>

条件式を使用すると、期限切れのアイテムに対する書き込みを回避できます。以下のコードスニペットは、有効期限が現在の時間よりも大きいかどうかをチェックする条件付き更新です。true の場合、書き込みオペレーションは続行されます。

以下のコード例は、項目の TTL を条件付きで更新する方法を示しています。

------
#### [ Java ]

**SDK for Java 2.x**  
条件を指定して、テーブル内の既存の DynamoDB 項目の TTL を更新します。  

```
package com.amazon.samplelib.ttl;

import com.amazon.samplelib.CodeSampleUtils;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse;

import java.util.Map;
import java.util.Optional;

/**
 * Updates an item in a DynamoDB table with TTL attributes using a conditional expression.
 * This class demonstrates how to conditionally update TTL expiration timestamps.
 */
public class UpdateTTLConditional {

    private static final String USAGE =
        """
            Usage:
                <tableName> <primaryKey> <sortKey> <region>
            Where:
                tableName - The Amazon DynamoDB table being queried.
                primaryKey - The name of the primary key. Also known as the hash or partition key.
                sortKey - The name of the sort key. Also known as the range attribute.
                region (optional) - The AWS region that the Amazon DynamoDB table is located in. (Default: us-east-1)
            """;
    private static final int DAYS_TO_EXPIRE = 90;
    private static final int SECONDS_PER_DAY = 24 * 60 * 60;
    private static final String PRIMARY_KEY_ATTR = "primaryKey";
    private static final String SORT_KEY_ATTR = "sortKey";
    private static final String UPDATED_AT_ATTR = "updatedAt";
    private static final String EXPIRE_AT_ATTR = "expireAt";
    private static final String UPDATE_EXPRESSION = "SET " + UPDATED_AT_ATTR + "=:c, " + EXPIRE_AT_ATTR + "=:e";
    private static final String CONDITION_EXPRESSION = "attribute_exists(" + PRIMARY_KEY_ATTR + ")";
    private static final String SUCCESS_MESSAGE = "%s UpdateItem operation with TTL successful.";
    private static final String CONDITION_FAILED_MESSAGE = "Condition check failed. Item does not exist.";
    private static final String TABLE_NOT_FOUND_ERROR = "Error: The Amazon DynamoDB table \"%s\" can't be found.";

    private final DynamoDbClient dynamoDbClient;

    /**
     * Constructs an UpdateTTLConditional with a default DynamoDB client.
     */
    public UpdateTTLConditional() {
        this.dynamoDbClient = null;
    }

    /**
     * Constructs an UpdateTTLConditional with the specified DynamoDB client.
     *
     * @param dynamoDbClient The DynamoDB client to use
     */
    public UpdateTTLConditional(final DynamoDbClient dynamoDbClient) {
        this.dynamoDbClient = dynamoDbClient;
    }

    /**
     * Main method to demonstrate conditionally updating an item with TTL.
     *
     * @param args Command line arguments
     */
    public static void main(final String[] args) {
        try {
            int result = new UpdateTTLConditional().processArgs(args);
            System.exit(result);
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }

    /**
     * Process command line arguments and conditionally update an item with TTL.
     *
     * @param args Command line arguments
     * @return 0 if successful, non-zero otherwise
     * @throws ResourceNotFoundException If the table doesn't exist
     * @throws DynamoDbException If an error occurs during the operation
     * @throws IllegalArgumentException If arguments are invalid
     */
    public int processArgs(final String[] args) {
        // Argument validation (remove or replace this line when reusing this code)
        CodeSampleUtils.validateArgs(args, new int[] {3, 4}, USAGE);

        final String tableName = args[0];
        final String primaryKey = args[1];
        final String sortKey = args[2];
        final Region region = Optional.ofNullable(args.length > 3 ? args[3] : null)
            .map(Region::of)
            .orElse(Region.US_EAST_1);

        // Get current time in epoch second format
        final long currentTime = System.currentTimeMillis() / 1000;

        // Calculate expiration time 90 days from now in epoch second format
        final long expireDate = currentTime + (DAYS_TO_EXPIRE * SECONDS_PER_DAY);

        // Create the key map for the item to update
        final Map<String, AttributeValue> keyMap = Map.of(
            PRIMARY_KEY_ATTR, AttributeValue.builder().s(primaryKey).build(),
            SORT_KEY_ATTR, AttributeValue.builder().s(sortKey).build());

        // Create the expression attribute values
        final Map<String, AttributeValue> expressionAttributeValues = Map.of(
            ":c", AttributeValue.builder().n(String.valueOf(currentTime)).build(),
            ":e", AttributeValue.builder().n(String.valueOf(expireDate)).build());

        final UpdateItemRequest request = UpdateItemRequest.builder()
            .tableName(tableName)
            .key(keyMap)
            .updateExpression(UPDATE_EXPRESSION)
            .conditionExpression(CONDITION_EXPRESSION)
            .expressionAttributeValues(expressionAttributeValues)
            .build();

        try (DynamoDbClient ddb = dynamoDbClient != null
            ? dynamoDbClient
            : DynamoDbClient.builder().region(region).build()) {
            final UpdateItemResponse response = ddb.updateItem(request);
            System.out.println(String.format(SUCCESS_MESSAGE, tableName));
            return 0;
        } catch (ConditionalCheckFailedException e) {
            System.err.println(CONDITION_FAILED_MESSAGE);
            throw e;
        } catch (ResourceNotFoundException e) {
            System.err.format(TABLE_NOT_FOUND_ERROR, tableName);
            throw e;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            throw e;
        }
    }
}
```
+  API の詳細については、*AWS SDK for Java 2.x API リファレンス*の「[UpdateItem](https://docs.aws.amazon.com/goto/SdkForJavaV2/dynamodb-2012-08-10/UpdateItem)」を参照してください。

------
#### [ JavaScript ]

**SDK for JavaScript (v3)**  
条件を指定して、テーブル内の既存の DynamoDB 項目の TTL を更新します。  

```
import { DynamoDBClient, UpdateItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";

export const updateItemConditional = async (tableName, partitionKey, sortKey, region = 'us-east-1', newAttribute = 'default-value') => {
    const client = new DynamoDBClient({
        region: region,
        endpoint: `https://dynamodb.${region}.amazonaws.com`
    });

    const currentTime = Math.floor(Date.now() / 1000);

    const params = {
        TableName: tableName,
        Key: marshall({
            artist: partitionKey,
            album: sortKey
        }),
        UpdateExpression: "SET newAttribute = :newAttribute",
        ConditionExpression: "expireAt > :expiration",
        ExpressionAttributeValues: marshall({
            ':newAttribute': newAttribute,
            ':expiration': currentTime
        }),
        ReturnValues: "ALL_NEW"
    };

    try {
        const response = await client.send(new UpdateItemCommand(params));
        const responseData = unmarshall(response.Attributes);
        console.log("Item updated successfully: ", responseData);
        return responseData;
    } catch (error) {
        if (error.name === "ConditionalCheckFailedException") {
            console.log("Condition check failed: Item's 'expireAt' is expired.");
        } else {
            console.error("Error updating item: ", error);
        }
        throw error;
    }
};

// Example usage (commented out for testing)
// updateItemConditional('your-table-name', 'your-partition-key-value', 'your-sort-key-value');
```
+  API の詳細については、*AWS SDK for JavaScript API リファレンス*の「[UpdateItem](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/dynamodb/command/UpdateItemCommand)」を参照してください。

------
#### [ Python ]

**SDK for Python (Boto3)**  
条件を指定して、テーブル内の既存の DynamoDB 項目の TTL を更新します。  

```
from datetime import datetime, timedelta

import boto3
from botocore.exceptions import ClientError


def update_dynamodb_item_ttl(table_name, region, primary_key, sort_key, ttl_attribute):
    """
    Updates an existing record in a DynamoDB table with a new or updated TTL attribute.

    :param table_name: Name of the DynamoDB table
    :param region: AWS Region of the table - example `us-east-1`
    :param primary_key: one attribute known as the partition key.
    :param sort_key: Also known as a range attribute.
    :param ttl_attribute: name of the TTL attribute in the target DynamoDB table
    :return:
    """
    try:
        dynamodb = boto3.resource("dynamodb", region_name=region)
        table = dynamodb.Table(table_name)

        # Generate updated TTL in epoch second format
        updated_expiration_time = int((datetime.now() + timedelta(days=90)).timestamp())

        # Define the update expression for adding/updating a new attribute
        update_expression = "SET newAttribute = :val1"

        # Define the condition expression for checking if 'expireAt' is not expired
        condition_expression = "expireAt > :val2"

        # Define the expression attribute values
        expression_attribute_values = {":val1": ttl_attribute, ":val2": updated_expiration_time}

        response = table.update_item(
            Key={"primaryKey": primary_key, "sortKey": sort_key},
            UpdateExpression=update_expression,
            ConditionExpression=condition_expression,
            ExpressionAttributeValues=expression_attribute_values,
        )

        print("Item updated successfully.")
        return response["ResponseMetadata"]["HTTPStatusCode"]  # Ideally a 200 OK
    except ClientError as e:
        if e.response["Error"]["Code"] == "ConditionalCheckFailedException":
            print("Condition check failed: Item's 'expireAt' is expired.")
        else:
            print(f"Error updating item: {e}")
    except Exception as e:
        print(f"Error updating item: {e}")


# replace with your values
update_dynamodb_item_ttl(
    "your-table-name",
    "us-east-1",
    "your-partition-key-value",
    "your-sort-key-value",
    "your-ttl-attribute-value",
)
```
+  API の詳細については、[AWS SDK for Python (Boto3) API リファレンス](https://docs.aws.amazon.com/goto/boto3/dynamodb-2012-08-10/UpdateItem)の「*UpdateItem*」を参照してください。

------

## DynamoDB ストリーム内の削除済みアイテムの特定
<a name="ttl-expired-items-identifying"></a>

ストリームレコードにはユーザー ID フィールド `Records[<index>].userIdentity` が含まれます。TTL プロセスによって削除された項目には、次のフィールドが含まれています。

```
Records[<index>].userIdentity.type
"Service"

Records[<index>].userIdentity.principalId
"dynamodb.amazonaws.com"
```

次の JSON は 1 つのストリームレコードの関連する部分を示しています。

```
"Records": [ 
  { 
	... 
		"userIdentity": {
		"type": "Service", 
      	"principalId": "dynamodb.amazonaws.com" 
   	} 
   ... 
	} 
]
```

# DynamoDB のテーブルに対するクエリの実行
<a name="Query"></a>

Amazon DynamoDB の `Query` オペレーションを使用して、プライマリキーの値に基づいて項目を探すことができます。

パーティションキーの属性名、および属性の単一値を指定する必要があります。`Query` はそのパーティションキー値を持つすべての項目を返します。必要に応じて、ソートキーの属性を指定し、比較演算子を使用して、検索結果をさらに絞り込むことができます。

リクエストの構文、レスポンスパラメータ、その他の例など、`Query` の使用方法の詳細については、*Amazon DynamoDB API リファレンス*の「[クエリ](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html)」を参照してください。

**Topics**
+ [DynamoDB でのクエリオペレーションのキー条件式](Query.KeyConditionExpressions.md)
+ [DynamoDB でのクエリオペレーションのフィルター式](Query.FilterExpression.md)
+ [DynamoDB でテーブルクエリ結果をページ分割する](Query.Pagination.md)
+ [DynamoDB でクエリオペレーションを使用する際のその他の側面](Query.Other.md)

# DynamoDB でのクエリオペレーションのキー条件式
<a name="Query.KeyConditionExpressions"></a>

最初の文字が `a-z` または `A-Z` であり、残りの文字 (ある場合、2 番目以降の文字) が `a-z`、`A-Z`、または `0-9` である場合は、キー条件式で任意の属性値を使用できます。さらに、属性名は DynamoDB の予約語であってはいけません。（詳細リストについては、「[DynamoDB の予約語](ReservedWords.md)」を参照してください） 属性名がこれらの要件を満たさない場合は、式の属性名をプレースホルダーとして定義する必要があります。詳細については、「[DynamoDB の式の属性名 (エイリアス)](Expressions.ExpressionAttributeNames.md)」を参照してください。

特定のパーティションキー値を持つ項目は、DynamoDB によってソートキーの値で並べ替えられた順序で近くに配置されて保存されます。`Query` オペレーションでは、並べ替えられた順序でDynamoDB によって項目が取得され、`KeyConditionExpression` や存在する任意の `FilterExpression` を使用して処理されます。その時初めて、`Query` の結果がクライアントに返されます。

`Query` オペレーションは常に結果セットを返します。一致する項目がない場合、結果セットは空になります。

`Query` の結果は常にソートキーの値によってソートされます。ソートキーのデータ型が `Number` である場合は、結果が番号順で返されます。その他の場合は、UTF-8 バイトの順序で結果が返されます。デフォルトの並べ替え順序は昇順です。順序を反転させるには、`ScanIndexForward` パラメータを `false` に設定します。

1 回の `Query` オペレーションで、最大 1 MB のデータを取得できます。この制限は、`FilterExpression` または `ProjectionExpression` が結果に適用される前に適用されます。レスポンスに `LastEvaluatedKey` が存在し、Null 以外の場合、結果セットをページ分割する必要があります ([DynamoDB でテーブルクエリ結果をページ分割する](Query.Pagination.md) を参照)。

## キー条件式の例
<a name="Query.KeyConditionExpressions-example"></a>

検索条件を指定するには、*キー条件式* (テーブルまたはインデックスから読み取る項目を決定する文字列) を使用します。

等価条件としてパーティションキーの名前と値を指定する必要があります。キー条件式では、非キー属性を使用することはできません。

オプションで、ソートキーに 2 番目の条件を指定できます (存在する場合)。ソートキーの条件では、次の比較演算子を 1 つ使用する必要があります。
+ `a = b` — 属性 *a* が値 *b* と等しい場合、true
+ `a < b` — *a* が *b* 未満の場合、true
+ `a <= b` — *a* が *b* 以下である場合、true
+ `a > b` — *a* が *b* より大きい場合、true
+ `a >= b` — *a* が *b* 以上である場合、true
+ `a BETWEEN b AND c` — *a* が *b* 以上で、*c* 以下である場合、true。

次の関数もサポートされます。
+ `begins_with (a, substr)` — 属性の値 `a` が特定のサブ文字列から始まる場合、true。

キー条件式の使用方法を示す AWS Command Line Interface (AWS CLI) の例を次に示します。これらの式では、実際の値の代わりにプレースホルダー (`:name` や `:sub` など) を使用しています。詳細については、「[DynamoDB の式の属性名 (エイリアス)](Expressions.ExpressionAttributeNames.md)」および「[DynamoDB での式属性値の使用](Expressions.ExpressionAttributeValues.md)」を参照してください。

**Example**  
`Thread` テーブルに対して、特定の `ForumName` (パーティションキー) についてのクエリを実行します。その `ForumName` の値を持つすべての項目はクエリによって読み込まれます。これはソートキー (`Subject`) が `KeyConditionExpression` に含まれないためです。  

```
aws dynamodb query \
    --table-name Thread \
    --key-condition-expression "ForumName = :name" \
    --expression-attribute-values  '{":name":{"S":"Amazon DynamoDB"}}'
```

**Example**  
`Thread` テーブルに対して、特定の `ForumName` (パーティションキー) についてのクエリを実行しますが、今回は指定の `Subject` (ソートキー) を持つ項目のみを返します。  

```
aws dynamodb query \
    --table-name Thread \
    --key-condition-expression "ForumName = :name and Subject = :sub" \
    --expression-attribute-values  file://values.json
```
`--expression-attribute-values` の引数は、`values.json` のファイルに保存されます。  

```
{
    ":name":{"S":"Amazon DynamoDB"},
    ":sub":{"S":"DynamoDB Thread 1"}
}
```

**Example**  
`Reply` テーブルに対して、特定の `Id` (パーティションキー) についてのクエリを実行しますが、`ReplyDateTime` (ソートキー) が特定の文字で始まる項目のみを返します。  

```
aws dynamodb query \
    --table-name Reply \
    --key-condition-expression "Id = :id and begins_with(ReplyDateTime, :dt)" \
    --expression-attribute-values  file://values.json
```
`--expression-attribute-values` の引数は、`values.json` のファイルに保存されます。  

```
{
    ":id":{"S":"Amazon DynamoDB#DynamoDB Thread 1"},
    ":dt":{"S":"2015-09"}
}
```

# DynamoDB でのクエリオペレーションのフィルター式
<a name="Query.FilterExpression"></a>

`Query` 結果の絞り込みが必要な場合は、オプションでフィルタ式を指定できます。*フィルタ式*によって、`Query` 結果の内、どの項目を返すべきか確定します。他のすべての結果は破棄されます。

フィルタ式は、`Query` の完了後、結果が返される前に適用されます。そのため、`Query` は、フィルタ式があるかどうかにかかわらず、同じ量の読み込みキャパシティーを消費します。

1 回の `Query` オペレーションで、最大 1 MB のデータを取得できます。この制限は、フィルタ式を評価する前に適用されます。

フィルタ式には、パーティションキーまたはソートキーの属性を含めることはできません。フィルタ式ではなく、キー条件式でこれらの属性を指定する必要があります。

フィルター式の構文は、キー条件式の構文と似ています。フィルター式は、キー条件式と同じコンパレータ、関数および論理演算子を使用できます。さらに、フィルター式では、非等号演算子 (`<>`)、`OR` 演算子、`CONTAINS` 演算子、`IN` 演算子、`BEGINS_WITH` 演算子、`BETWEEN` 演算子、`EXISTS` 演算子、および `SIZE` 演算子を使用できます。詳細については、「[DynamoDB でのクエリオペレーションのキー条件式](Query.KeyConditionExpressions.md)」および「[フィルター式と条件式の構文](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.Syntax)」を参照してください。

**Example**  
以下の AWS CLI の例では、`Thread` テーブルに対して、特定の `ForumName` (パーティションキー) および `Subject` (ソートキー) についてのクエリを実行します。見つかった項目のうち、最も一般的なディスカッションスレッド (つまり、一定数以上の `Views` があるスレッド) のみが返されます。  

```
aws dynamodb query \
    --table-name Thread \
    --key-condition-expression "ForumName = :fn and Subject begins_with :sub" \
    --filter-expression "#v >= :num" \
    --expression-attribute-names '{"#v": "Views"}' \
    --expression-attribute-values file://values.json
```
`--expression-attribute-values` の引数は、`values.json` のファイルに保存されます。  

```
{
    ":fn":{"S":"Amazon DynamoDB"},
    ":sub":{"S":"DynamoDB Thread 1"},
    ":num":{"N":"3"}
}
```
`Views` は DynamoDB で予約語であるため ([DynamoDB の予約語](ReservedWords.md) を参照)、この例では `#v` をプレースホルダーとして使用することにご注意ください。詳細については、「[DynamoDB の式の属性名 (エイリアス)](Expressions.ExpressionAttributeNames.md)」を参照してください。

**注記**  
フィルタ式は、`Query` 結果セットから項目を削除します。可能であれば、大量の項目を取得してもそのほとんどを破棄する必要がある場合、 `Query` の使用は避けてください。

# DynamoDB でテーブルクエリ結果をページ分割する
<a name="Query.Pagination"></a>

DynamoDB では、`Query` オペレーションの結果を*ページ割り*します。ページ分割を行うことで `Query` 結果が 1 MB サイズ (またはそれ以下) のデータの「ページ」に分割されます。アプリケーションは結果の最初のページ、次に 2 ページと処理できます。

1 つの `Query` は、サイズの制限である1 MB 以内の結果セットだけを返します。さらに結果があるかどうかを確認して、一度に 1 ページずつ結果を取り出すには、アプリケーションで次の操作を行う必要があります。

1. 低レベルの `Query` 結果を確認します。
   + 結果に `LastEvaluatedKey` 要素が含まれており、それが Null 以外の場合、ステップ 2 に進みます。
   + 結果に `LastEvaluatedKey` が*ない*場合、これ以上取得する項目はありません。

1. 同じ `KeyConditionExpression` を使用して `Query` を構築します。ただし、今回は、ステップ 1 から `LastEvaluatedKey` 値を取得して、新しい `Query` リクエストの `ExclusiveStartKey` パラメータとして使用します。

1. 新しい `Query` リクエストを実行します。

1. ステップ 1 に進んでください。

言い換えると、`Query` レスポンスからの `LastEvaluatedKey` を次の `Query` リクエストの `ExclusiveStartKey` として使用する必要があります。`Query` レスポンスに `LastEvaluatedKey` の要素がない場合、結果の最後のページを取得します。`LastEvaluatedKey` が空ではない場合でも、必ずしも結果セットにまだ値があることを意味するわけではありません。結果セットの最後まで到達したことを確認できるのは、`LastEvaluatedKey` が空になったときだけです。

AWS CLI を使用してこの動作を表示できます。AWS CLI は、`LastEvaluatedKey` が結果に表示されなくなるまで、低レベルの `Query` リクエストを DynamoDB に繰り返し送信します。特定の年の映画タイトルを取得する次の AWS CLI の例を考えてみます。

```
aws dynamodb query --table-name Movies \
    --projection-expression "title" \
    --key-condition-expression "#y = :yyyy" \
    --expression-attribute-names '{"#y":"year"}' \
    --expression-attribute-values '{":yyyy":{"N":"1993"}}' \
    --page-size 5 \
    --debug
```

通常、AWS CLI はページ分割を自動的に処理します。ただし、この例では、AWS CLI `--page-size` パラメータによりページごとの項目数が制限されています。`--debug` パラメータは、リクエストとレスポンスについての低レベルの情報を表示します。

この例を実行した場合、DynamoDB からの最初のレスポンスは次のようになります。

```
2017-07-07 11:13:15,603 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":5,"Items":[{"title":{"S":"A Bronx Tale"}},
{"title":{"S":"A Perfect World"}},{"title":{"S":"Addams Family Values"}},
{"title":{"S":"Alive"}},{"title":{"S":"Benny & Joon"}}],
"LastEvaluatedKey":{"year":{"N":"1993"},"title":{"S":"Benny & Joon"}},
"ScannedCount":5}'
```

レスポンスの `LastEvaluatedKey` は、すべての項目が取得されたわけではないことを示します。その後、AWS CLI は DynamoDB に別の `Query` リクエストを送信します。このリクエストとレスポンスのパターンが、最終レスポンスまで繰り返されます。

```
2017-07-07 11:13:16,291 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":1,"Items":[{"title":{"S":"What\'s Eating Gilbert Grape"}}],"ScannedCount":1}'
```

`LastEvaluatedKey` がない場合、これ以上取得する項目がないことを示します。

**注記**  
AWS SDK は低レベルの DynamoDB レスポンス (`LastEvaluatedKey` の有無を含む) を処理し、ページ割りした `Query` 結果のさまざまな抽象化を提供します。たとえば、SDK for Java のドキュメントインターフェイスでは、`java.util.Iterator` サポートが利用可能なため、結果を一度に 1 つずつ確認できます。  
各種のプログラミング言語のコード例については、「[Amazon DynamoDB 利用開始ガイド](https://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/)」と、該当言語の「AWS SDK ドキュメント」を参照してください。

`Query` オペレーションの `Limit` パラメータを使用して結果セット内の項目数を制限することで、ページサイズを小さくすることもできます。

DynamoDB でのクエリ実行の詳細については、「[DynamoDB のテーブルに対するクエリの実行](Query.md)」を参照してください。

# DynamoDB でクエリオペレーションを使用する際のその他の側面
<a name="Query.Other"></a>

このセクションでは、DynamoDB クエリオペレーションのその他の側面について説明します。これには、結果サイズの制限、スキャンされた項目と返された項目のカウント、読み取り容量の消費のモニタリング、読み取り整合性の制御が含まれます。

## 結果セットの項目数の制限
<a name="Query.Limit"></a>

`Query` オペレーションを使用すると、読み取られる項目数を制限することができます。これを行うには、`Limit` パラメータに項目の最大数を設定します。

たとえば、フィルタ式を使用せず、`Limit` 値を `6` として、テーブルを `Query` するとします。`Query` 結果には、リクエストのキー条件式に一致するテーブルからの最初 6 つの項目が含まれます。

ここで、`Query` にフィルタ式を追加するとします。この場合、DynamoDB は最大 6 つの項目を読み込み、フィルタ式と一致する項目だけを返します。DynamoDB が項目の読み込みを続けた場合、さらに多くの項目がフィルタ式にマッチしても、最終的な `Query` 結果に含まれる項目数は 6 つ以下です。

## 結果での項目のカウント
<a name="Query.Count"></a>

`Query` レスポンスには、条件に一致する項目に加えて次の要素が含まれます。
+ `ScannedCount` — フィルター式 (存在する場合) が適用される*前に*、キー条件式に一致した項目数。
+ `Count` — フィルター式 (存在する場合) が適用された*後に*残っている項目数。

**注記**  
フィルタ式を使用しない場合、`ScannedCount` と `Count` は同じ値を持ちます。

`Query` 結果セットのサイズが 1 MB より大きい場合、`ScannedCount` および `Count` では、合計項目数の一部のみが示されます。すべての結果を取得するためには、複数の `Query` オペレーションを実行する必要があります ([DynamoDB でテーブルクエリ結果をページ分割する](Query.Pagination.md) を参照してください)。

各 `Query` レスポンスには、特定の `Query` リクエストによって処理された項目の `ScannedCount` および `Count` が含まれます。すべての `Query` リクエストの合計を取得するには、`ScannedCount` および `Count` の実行中の集計を維持することができます。

## クエリで消費されるキャパシティユニット
<a name="Query.CapacityUnits"></a>

パーティションキーの属性名、およびその属性の単一値を指定する限り、いずれのテーブルまたはセカンダリインデックスにも、`Query` を実行できます。`Query` により、そのパーティションのキー値を持つすべての項目が返されます。必要に応じて、ソートキーの属性を指定し、比較演算子を使用して、検索結果をさらに絞り込むことができます。`Query`API オペレーションでは、次のように読み込みキャパシティーユニットを消費します。


****  

| ...を `Query` する場合 | DynamoDB は ... からの読み込み容量ユニットを消費します。 | 
| --- | --- | 
| テーブル | テーブルのプロビジョニングされた読み込みキャパシティー。 | 
| グローバルセカンダリインデックス | インデックスのプロビジョニングされた読み込みキャパシティー。 | 
| ローカルセカンダリインデックス | ベーステーブルのプロビジョニングされた読み込みキャパシティー。 | 

デフォルトでは、`Query`オペレーションはどのくらいの読み込みキャパシティーを消費するかについてのデータを返しません。ただし、この情報を取得するために `Query` リクエストで `ReturnConsumedCapacity` パラメータを指定できます。`ReturnConsumedCapacity` の有効な設定を以下に示します。
+ `NONE` — 消費された容量データは返されません。(これがデフォルトです)
+ `TOTAL` — レスポンスには消費された読み込み容量単位の合計値が含まれます。
+ `INDEXES` — レスポンスは、アクセスする各テーブルとインデックスの消費される容量とともに、消費される読み込み容量単位の合計値を示します。

DynamoDB はアプリケーションに返されるデータ量ではなく、項目の数と項目のサイズに基づいて、消費される読み込みキャパシティユニットの数を計算します。このため、消費される容量ユニットの数は、(デフォルトの動作で) 属性のすべてをリクエストしても、(プロジェクション式を使用して) 一部をリクエストしても、同じになります。この数は、フィルター式を使用していてもいなくても同じです。`Query` は最小読み込みキャパシティユニットを消費して、最大 4 KB の項目について強力な整合性のある読み込みを 1 秒あたり 1 回、または結果整合性のある読み込みを 1 秒あたり 2 回実行します。4 KB より大きい項目を読み込む必要がある場合、DynamoDB には追加の読み込みリクエストユニットが必要です。空のテーブルや、パーティションキーの数が少ない非常に大きなテーブルでは、クエリされたデータの量を超えて追加の RCU が課金される場合があります。これにより、データが存在しない場合でも、`Query` リクエストを処理するためのコストがカバーされます。

## クエリの読み込み整合性
<a name="Query.ReadConsistency"></a>

`Query` オペレーションは、結果的に整合性のある読み込みをデフォルトで行います。つまり、`Query` 結果が、最近完了した `PutItem` または `UpdateItem` オペレーションによる変更を反映しない場合があります。詳細については、「[DynamoDB の読み取り整合性](HowItWorks.ReadConsistency.md)」を参照してください。

強力な整合性のある読み込みが必要な場合は、`Query` リクエストで `ConsistentRead` パラメータを `true` に設定します。

# DynamoDB でのテーブルのスキャン
<a name="Scan"></a>

Amazon DynamoDB の `Scan` オペレーションでは、テーブルまたはセカンダリインデックスのすべての項目を読み込みます。デフォルトでは、`Scan` オペレーションはテーブルまたはインデックスのすべての項目のデータ属性を返します。`ProjectionExpression` パラメータを使用し、`Scan` がすべての属性ではなく一部のみを返すようにできます。

`Scan` は常に結果セットを返します。一致する項目がない場合、結果セットは空になります。

1 回の `Scan` リクエストで、最大 1 MB のデータを取得できます。DynamoDB では、必要に応じてこのデータにフィルター式を適用して、結果をユーザーに返す前に絞り込むことができます。

**Topics**
+ [Scan のフィルタ式](#Scan.FilterExpression)
+ [結果セットの項目数の制限](#Scan.Limit)
+ [結果のページ分割](#Scan.Pagination)
+ [結果での項目のカウント](#Scan.Count)
+ [Scan で消費されるキャパシティユニット](#Scan.CapacityUnits)
+ [スキャンの読み込み整合性](#Scan.ReadConsistency)
+ [並列スキャン](#Scan.ParallelScan)

## Scan のフィルタ式
<a name="Scan.FilterExpression"></a>

`Scan` 結果の絞り込みが必要な場合は、オプションでフィルタ式を指定できます。*フィルタ式*によって、`Scan` 結果の内、どの項目を返すべきか確定します。他のすべての結果は破棄されます。

フィルタ式は、`Scan` の完了後、結果が返される前に適用されます。そのため、`Scan` は、フィルタ式があるかどうかにかかわらず、同じ量の読み込みキャパシティーを消費します。

1 回の `Scan` オペレーションで、最大 1 MB のデータを取得できます。この制限は、フィルタ式を評価する前に適用されます。

`Scan` では、パーティションキー属性やソートキー属性など、フィルター式で任意の属性を指定できます。

フィルタ式の構文は、条件式の構文と同じです。フィルタ式は、条件式と同じコンパレータ、関数および論理演算子を使用できます。論理演算子の詳細については、「[DynamoDB の条件式とフィルター式、演算子、関数](Expressions.OperatorsAndFunctions.md)」を参照してください。

**Example**  
次の AWS Command Line Interface (AWS CLI) の例では `Thread` テーブルをスキャンして、特定のユーザーによって最後に投稿された項目のみを返します。  

```
aws dynamodb scan \
     --table-name Thread \
     --filter-expression "LastPostedBy = :name" \
     --expression-attribute-values '{":name":{"S":"User A"}}'
```

## 結果セットの項目数の制限
<a name="Scan.Limit"></a>

`Scan` オペレーションは、結果で返される項目数を制限することができます。​これを行うには、フィルタ式を評価する前に、`Limit` パラメータに、`Scan` オペレーションが返す項目の最大数を設定します。

たとえば、フィルタ式を使用せず、`Scan` 値を `Limit` として、テーブルを `6` するとします。`Scan` 結果には、テーブルの最初の 6 つの項目が含まれます。

ここで、`Scan` にフィルタ式を追加するとします。この場合、DynamoDB は返される 6 つの項目にフィルター式を適用し、一致しない項目を廃棄します。最終的な `Scan` 結果はフィルタリングされる項目の数に応じて、6 つ以下の項目を含みます。

## 結果のページ分割
<a name="Scan.Pagination"></a>

DynamoDB では、`Scan` オペレーションの結果を*ページ割り*します。ページ分割を行うことで `Scan` 結果が 1 MB サイズ (またはそれ以下) のデータの「ページ」に分割されます。アプリケーションは結果の最初のページ、次に 2 ページと処理できます。

1 つの `Scan` は、サイズの制限である1 MB 以内の結果セットだけを返します。

さらに結果があるかどうかを確認して、一度に 1 ページずつ結果を取り出すには、アプリケーションで次の操作を行う必要があります。

1. 低レベルの `Scan` 結果を確認します。
   + 結果に `LastEvaluatedKey` 要素が含まれる場合、ステップ 2 に進みます。
   + 結果に `LastEvaluatedKey` が*ない*場合、これ以上取得する項目はありません。

1. 以前のものと同じパラメータを使用して新しい `Scan` リクエストを作成します。ただし、今回は、ステップ 1 から `LastEvaluatedKey` 値を取得して、新しい `Scan` リクエストの `ExclusiveStartKey` パラメータとして使用します。

1. 新しい `Scan` リクエストを実行します。

1. ステップ 1 に進んでください。

言い換えると、`LastEvaluatedKey` レスポンスからの `Scan` を次の `ExclusiveStartKey` リクエストの `Scan` として使用する必要があります。`LastEvaluatedKey` レスポンスに `Scan` 要素がない場合、結果の最後のページを取得します。(結果セットの最後まで到達したことを確認できるのは、`LastEvaluatedKey` がないときだけです)

AWS CLI を使用してこの動作を表示できます。AWS CLI は低レベル `Scan` リクエストを DynamoDB に送信し、`LastEvaluatedKey` が結果に表示されなくなるまで送信を繰り返します。次の AWS CLI の例を見てください。この例は、`Movies` テーブル全体をスキャンしますが、特定のジャンルの映画のみを返します。

```
aws dynamodb scan \
    --table-name Movies \
    --projection-expression "title" \
    --filter-expression 'contains(info.genres,:gen)' \
    --expression-attribute-values '{":gen":{"S":"Sci-Fi"}}' \
    --page-size 100  \
    --debug
```

通常、AWS CLI はページ分割を自動的に処理します。ただし、この例では、AWS CLI `--page-size` パラメータによりページごとの項目数が制限されています。`--debug` パラメータは、リクエストとレスポンスについての低レベルの情報を表示します。

**注記**  
ページ分割の結果は、渡した入力パラメータによっても異なります。  
`aws dynamodb scan --table-name Prices --max-items 1` を使用すると `NextToken` が返されます
`aws dynamodb scan --table-name Prices --limit 1` を使用すると `LastEvaluatedKey` が返されます。
また、特に `--starting-token` を使用するには、`NextToken` 値が必要であることに注意してください。

この例を実行した場合、DynamoDB からの最初のレスポンスは次のようになります。

```
2017-07-07 12:19:14,389 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":7,"Items":[{"title":{"S":"Monster on the Campus"}},{"title":{"S":"+1"}},
{"title":{"S":"100 Degrees Below Zero"}},{"title":{"S":"About Time"}},{"title":{"S":"After Earth"}},
{"title":{"S":"Age of Dinosaurs"}},{"title":{"S":"Cloudy with a Chance of Meatballs 2"}}],
"LastEvaluatedKey":{"year":{"N":"2013"},"title":{"S":"Curse of Chucky"}},"ScannedCount":100}'
```

レスポンスの `LastEvaluatedKey` は、すべての項目が取得されたわけではないことを示します。その後、AWS CLI は DynamoDB に別の `Scan` リクエストを送信します。このリクエストとレスポンスのパターンが、最終レスポンスまで繰り返されます。

```
2017-07-07 12:19:17,830 - MainThread - botocore.parsers - DEBUG - Response body:
b'{"Count":1,"Items":[{"title":{"S":"WarGames"}}],"ScannedCount":6}'
```

`LastEvaluatedKey` がない場合、これ以上取得する項目がないことを示します。

**注記**  
AWS SDK は低レベルの DynamoDB レスポンス (`LastEvaluatedKey` の有無を含む) を処理し、ページ割りした `Scan` 結果のさまざまな抽象化を提供します。たとえば、SDK for Java のドキュメントインターフェイスでは、`java.util.Iterator` サポートが利用可能なため、結果を一度に 1 つずつ確認できます。  
各種のプログラミング言語のコード例については、[Amazon DynamoDB 利用開始ガイド](https://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/)と、該当言語の AWS SDK ドキュメントを参照してください。

## 結果での項目のカウント
<a name="Scan.Count"></a>

`Scan` レスポンスには、条件に一致する項目に加えて次の要素が含まれます。
+ `ScannedCount` — `ScanFilter` が適用される前に評価される項目数。`ScannedCount` 値が大きく、`Count` 結果が小さいまたはない場合は、`Scan` オペレーションが不十分であることを示しています。リクエストでフィルタを使用していない場合、`ScannedCount` は `Count` と同じです。
+ `Count` — フィルター式 (存在する場合) が適用された*後*に残っている項目数。

**注記**  
フィルタ式を使用しない場合、`ScannedCount` と `Count` は同じ値を持ちます。

`Scan` 結果セットのサイズが 1 MB より大きい場合、`ScannedCount` および `Count` では、合計項目数の一部のみが示されます。すべての結果を取得するためには、複数の `Scan` オペレーションを実行する必要があります ([結果のページ分割](#Scan.Pagination) を参照してください)。

各 `Scan` レスポンスには、特定の `ScannedCount` によって処理された項目の `Count` および `Scan` が含まれます。すべての `Scan` リクエストの合計を取得するには、`ScannedCount` および `Count` の実行中の集計を維持することができます。

## Scan で消費されるキャパシティユニット
<a name="Scan.CapacityUnits"></a>

任意のテーブルまたはセカンダリインデックスで `Scan` できます。`Scan` オペレーションでは、次のように読み込み容量単位を消費します。


****  

| ...を `Scan` する場合 | DynamoDB は ... からの読み込み容量ユニットを消費します。 | 
| --- | --- | 
| テーブル | テーブルのプロビジョニングされた読み込みキャパシティー。 | 
| グローバルセカンダリインデックス | インデックスのプロビジョニングされた読み込みキャパシティー。 | 
| ローカルセカンダリインデックス | ベーステーブルのプロビジョニングされた読み込みキャパシティー。 | 

**注記**  
セカンダリインデックススキャンオペレーションのクロスアカウントアクセスは、現在、[リソースベースのポリシー](access-control-resource-based.md)ではサポートされていません。

デフォルトでは、`Scan`オペレーションはどのくらいの読み込みキャパシティーを消費するかについてのデータを返しません。ただし、この情報を取得するために `Scan` リクエストで `ReturnConsumedCapacity` パラメータを指定できます。`ReturnConsumedCapacity` の有効な設定を以下に示します。
+ `NONE` — 消費された容量データは返されません。(これがデフォルトです)
+ `TOTAL` — レスポンスには消費された読み込み容量単位の合計値が含まれます。
+ `INDEXES` — レスポンスは、アクセスする各テーブルとインデックスの消費される容量とともに、消費される読み込み容量単位の合計値を示します。

DynamoDB はアプリケーションに返されるデータ量ではなく、項目の数と項目のサイズに基づいて、消費される読み込みキャパシティユニットの数を計算します。このため、消費される容量ユニットの数は、(デフォルトの動作で) 属性のすべてをリクエストしても、(プロジェクション式を使用して) 一部をリクエストしても、同じになります。この数は、フィルター式を使用していてもいなくても同じです。`Scan` は最小読み込みキャパシティユニットを消費して、最大 4 KB の項目について強力な整合性のある読み込みを 1 秒あたり 1 回、または結果整合性のある読み込みを 1 秒あたり 2 回実行します。4 KB より大きい項目を読み込む必要がある場合、DynamoDB には追加の読み込みリクエストユニットが必要です。空のテーブルや、パーティションキーの数が少ない非常に大きなテーブルでは、スキャンされたデータ量を超える追加の RCU が課金される場合があります。これにより、データが存在しない場合でも、`Scan` リクエストを処理するためのコストがカバーされます。

## スキャンの読み込み整合性
<a name="Scan.ReadConsistency"></a>

`Scan` オペレーションは、結果的に整合性のある読み込みをデフォルトで行います。つまり、`Scan` 結果が、最近完了した `PutItem` または `UpdateItem` オペレーションによる変更を反映しない場合があります。詳細については、「[DynamoDB の読み取り整合性](HowItWorks.ReadConsistency.md)」を参照してください。

強力な整合性のある読み込みが必要な場合は、`Scan` が開始する時に `ConsistentRead` パラメータを `true` リクエストで `Scan` に設定できます。これにより、`Scan` が開始する前に完了した書き込みオペレーションがすべて `Scan` 応答に含められます。

`ConsistentRead` を `true` に設定し、[DynamoDB Streams](./Streams.html) と同時に使用すると、テーブルのバックアップまたはレプリケーションシナリオで役立ちます。最初に、テーブル内のデータの整合性のあるコピーを取得するため、`Scan` を true に設定して `ConsistentRead` を使用します。`Scan` の実行中、DynamoDB Streams はテーブルで発生した追加の書き込みアクティビティをすべて記録します。`Scan` が完了したら、ストリームからテーブルへの書き込みアクティビティを適用できます。

**注記**  
`Scan` を `ConsistentRead` に設定した `true` オペレーションでは、`ConsistentRead` をデフォルト値 (`false`) のままにした場合と比較して、2 倍の読み込みキャパシティーユニットが使用されます。

## 並列スキャン
<a name="Scan.ParallelScan"></a>

デフォルトでは、`Scan` オペレーションは、データを順次処理します。Amazon DynamoDB はアプリケーションに 1 MB 単位でデータを返し、アプリケーションは追加の `Scan` オペレーションを使用して、次の 1 MB のデータを取得できます。

スキャンするテーブルまたはインデックスが大きいほど、`Scan` を完了するのに時間がかかります。さらに、シーケンシャル `Scan` は、プロビジョンされた読み込みスループットキャパシティを常に完全に使用できるとは限りません。DynamoDB は大きなテーブルのデータを複数の物理パーティションに分散しますが、`Scan` オペレーションでは、一度に 1 つのパーティションしか読み込むことができません。このため、`Scan` のスループットは、単一のパーティションの最大スループットによって制約されます。

これらの問題に対処するために、`Scan` オペレーションでは、テーブルまたはセカンダリインデックスを論理的に複数の*セグメント*に分割し、複数のアプリケーションワーカーがセグメントを並行してスキャンします。各ワーカーは、スレッド (マルチスレッドをサポートするプログラミング言語) またはオペレーティングシステムプロセスにすることができます。並列スキャンを実行するには、各ワーカーが独自の `Scan` リクエストを以下のパラメータで送信します。
+ `Segment` — 特定のワーカーによってスキャンされるセグメント。各ワーカーは、`Segment` に異なる値を使用する必要があります。
+ `TotalSegments` — 並列スキャンのセグメントの合計数。この値は、アプリケーションが使用するワーカーの数と同じでなければなりません。

次の図表は、マルチスレッドアプリケーションが 3 度の並列処理で並列 `Scan` を実行する方法を示しています。

![\[テーブルを 3 つのセグメントに分割して並列スキャンを実行するマルチスレッドアプリケーション。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/ParallelScan.png)




この図では、アプリケーションは 3 つのスレッドを生成し、各スレッドに番号を割り当てます。(セグメントはゼロベースであるため、最初の数値は常に 0 です。) 各スレッドは `Scan` リクエストを公開し、設定 `Segment` をその指定された番号に設定し、`TotalSegments` を 3 に設定します。各スレッドは、指定されたセグメントをスキャンし、一度に 1 MB のデータを取得し、アプリケーションのメインスレッドにデータを返します。

DynamoDB は、各項目のパーティションキーにハッシュ関数を適用して、項目を*セグメント*に割り当てます。指定された `TotalSegments` 値の場合、同じパーティションキーを持つすべての項目が常に同じ `Segment` に割り当てられます。つまり、*項目 1*、*項目 2*、*項目 3* すべてが `pk="account#123"` を共有するテーブルでは (ソートキーは異なる)、ソートキーの値や*項目コレクション*のサイズに関係なく、これらの項目は同じワーカーによって処理されます。

*セグメント*割り当てはパーティションキーハッシュのみに基づいているため、セグメントは不均等に分散される可能性があります。一部のセグメントには項目が含まれていない場合がありますが、他のセグメントには大きな項目コレクションを持つパーティションキーが多く含まれている場合があります。その結果、セグメントの合計数を増やしても、特にパーティションキーがキースペース全体に均一に分散されていない場合、スキャンパフォーマンスが速くなることは保証されません。

`Segment` および `TotalSegments` の値は、個々の `Scan` リクエストに適用されるため、いつでも異なる値を使用できます。アプリケーションが最高のパフォーマンスを達成するまで、これらの値および使用するワーカーの数を試さなければならない場合があります。

**注記**  
多数のワーカーを使用した並列スキャンでは、スキャン対象のテーブルまたはインデックスに対してプロビジョンされたスループットをすべて簡単に使用できます。テーブルまたはインデックスが他のアプリケーションから大量の読み込みまたは書き込みアクティビティが発生している場合は、このようなスキャンを避けることをお勧めします。  
リクエストごとに返されるデータの量を制御するには、`Limit` パラメータを使用します。これにより、1 人のワーカーがプロビジョンされたスループットをすべて消費し、他のすべてのワーカーが犠牲になる状況を防ぐことができます。

# PartiQL: Amazon DynamoDB 用の SQL 互換クエリ言語
<a name="ql-reference"></a>

Amazon DynamoDB は SQL 互換のクエリ言語である [PartiQL](https://partiql.org/) をサポートしており、Amazon DynamoDB でデータの選択、挿入、更新、および削除を行うことができます。PartiQL を使用すると、AWS マネジメントコンソール、NoSQL Workbench、AWS Command Line Interface、および PartiQL 用の DynamoDB API を使用して、DynamoDB テーブルと簡単にやり取りを行い、アドホッククエリを実行できます。

PartiQL オペレーションは、他の DynamoDB データプレーンオペレーションと同様の可用性、レイテンシー、パフォーマンスを提供します。

次のセクションでは、PartiQL の DynamoDB 実装について説明します。

**Topics**
+ [PartiQL とは何ですか?](#ql-reference.what-is)
+ [Amazon DynamoDB での PartiQL](#ql-reference.what-is)
+ [開始方法](ql-gettingstarted.md)
+ [データ型](ql-reference.data-types.md)
+ [ステートメント](ql-reference.statements.md)
+ [関数](ql-functions.md)
+ [演算子](ql-operators.md)
+ [トランザクション](ql-reference.multiplestatements.transactions.md)
+ [バッチオペレーション](ql-reference.multiplestatements.batching.md)
+ [IAM ポリシー](ql-iam.md)

## PartiQL とは何ですか?
<a name="ql-reference.what-is"></a>

*PartiQL* は、構造化データ、半構造化データ、ネストされたデータを含む複数のデータストア間で、SQL 互換のクエリアクセスを提供します。PartiQL は、Amazon 内で広く使用されており、現在、DynamoDB を含む多くの AWS のサービスの一部として利用できます。

PartiQL の仕様とコアクエリ言語のチュートリアルについては、[PartiQL ドキュメント](https://partiql.org/docs.html)を参照してください。

**注記**  
Amazon DynamoDB は、[PartiQL](https://partiql.org/) クエリ言語の*サブセット*をサポートしています。
Amazon DynamoDB では、[Amazon ion](http://amzn.github.io/ion-docs/) データ形式または Amazon Ion リテラルはサポートしていません。

## Amazon DynamoDB での PartiQL
<a name="ql-reference.what-is"></a>

DynamoDB で PartiQL クエリを実行するには、次を使用します。
+ DynamoDB コンソール
+ NoSQL Workbench
+ AWS Command Line Interface (AWS CLI)
+ DynamoDB API

これらの方法を使用して DynamoDB にアクセスする方法については、「[DynamoDB へのアクセス](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AccessingDynamoDB.html)」を参照してください。

# DynamoDB 用の PartiQL の開始方法
<a name="ql-gettingstarted"></a>

このセクションでは、Amazon DynamoDB コンソール、AWS Command Line Interface (AWS CLI)、および DynamoDB API から DynamoDB 用の PartiQL を使用する方法について説明します。

次の例では、「[DynamoDB の開始方法](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html)」チュートリアルで、DynamoDB テーブルを定義していることが前提です。

DynamoDB コンソール、AWS Command Line Interface、または DynamoDB API を使用して DynamoDB にアクセスする方法については、「[DynamoDB へのアクセス](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AccessingDynamoDB.html)」を参照してください。

[NoSQL Workbench](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.html) を[ダウンロード](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.settingup.html)して、[DynamoDB 用の PartiQL](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.html) ステートメントを構築するには、DynamoDB [Operation Builder](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.querybuilder.operationbuilder.html) 用の NoSQL Workbench の右上にある **[PartiQL operations]** (PartiQL オペレーション) を選択します。

------
#### [ Console ]

![\[Music テーブルに対してクエリオペレーションを実行した結果を示す PartiQL エディタインターフェイス。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/partiqlgettingstarted.png)


1. AWS マネジメントコンソール にサインインして DynamoDB コンソール ([https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)) を開きます。

1. コンソール左側のナビゲーションペインで、[**PartiQL エディター**] を選択します。

1. [**Music**] テーブルを選択します。

1. **[Query table]** (クエリテーブル) を選択します。このアクションで生成したクエリは、完全なテーブルスキャンを実行しません。

1. `partitionKeyValue` を文字列型の値である `Acme Band` に置換します。`sortKeyValue` を文字列型の値である `Happy Day` に置換します。

1. [**実行**] ボタンを選択します。

1. **[Table view]** (テーブルビュー) または **[JSON view]** (JSON ビュー) ボタンを選択すると、クエリの結果を確認できます。

------
#### [ NoSQL workbench ]

![\[NoSQL Workbench インターフェイス。Music テーブルに対して実行できる PartiQL SELECT ステートメントを示します。\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/images/workbench/partiql.single.png)


1. [**PartiQL ステートメント**] を選択します。

1. 次の PartiQL [[SELECT statement]](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.select.html) (SELECT ステートメント) を入力します。

   ```
   SELECT *                                         
   FROM Music  
   WHERE Artist=? and SongTitle=?
   ```

1. `Artist` および `SongTitle` パラメータの値を指定するには

   1. [**オプションのリクエストパラメータ**] を選択します。

   1. [**新しいパラメータの追加**] を選択します。

   1. 属性タイプとして **[string]** (文字列型) を選択し、値に `Acme Band` を選択します。

   1. ステップ b とステップ c を繰り返し、**[string]** (文字列型) のタイプと `PartiQL Rocks` の値を選択します。

1. コードを生成する場合は、[**Generate code (コードの生成)**] を選択します。

   表示されたタブから目的の言語を選択します。これで、このコードをコピーしてアプリケーションで使用できるようになります。

1. オペレーションをすぐに実行する場合は、[**実行**] をクリックします。

------
#### [ AWS CLI ]

1. INSERT PartiQL ステートメントを使用して、`Music` テーブルに項目を作成します。

   ```
   aws dynamodb execute-statement --statement "INSERT INTO Music  \
   					    VALUE  \
   					    {'Artist':'Acme Band','SongTitle':'PartiQL Rocks'}"
   ```

1. SELECT PartiQL ステートメントを使用して、Music テーブルから項目を取得します。

   ```
   aws dynamodb execute-statement --statement "SELECT * FROM Music   \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

1. UPDATE PartiQL ステートメントを使用して、`Music` テーブルの項目を更新します。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardsWon=1  \
                                               SET AwardDetail={'Grammys':[2020, 2018]}  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   `Music` テーブルに、項目のリスト値を追加します。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardDetail.Grammys =list_append(AwardDetail.Grammys,[2016])  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   `Music` テーブルから項目のリスト値を削除します。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               REMOVE AwardDetail.Grammys[2]  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   `Music` テーブルに、項目の新しいマップメンバーを追加します。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET AwardDetail.BillBoard=[2020]  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   `Music` テーブルに、項目の新しい文字列セットの属性を追加します。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET BandMembers =<<'member1', 'member2'>>  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

   `Music` テーブルで、項目の文字列セットの属性を更新します。

   ```
   aws dynamodb execute-statement --statement "UPDATE Music  \
                                               SET BandMembers =set_add(BandMembers, <<'newmember'>>)  \
                                               WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

1. DELETE PartiQL ステートメントを使用して、`Music` テーブルから項目を削除します。

   ```
   aws dynamodb execute-statement --statement "DELETE  FROM Music  \
       WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
   ```

------
#### [ Java ]

```
import java.util.ArrayList;
import java.util.List;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import software.amazon.dynamodb.AmazonDynamoDB;
import software.amazon.dynamodb.AmazonDynamoDBClientBuilder;
import software.amazon.dynamodb.model.AttributeValue;
import software.amazon.dynamodb.model.ConditionalCheckFailedException;
import software.amazon.dynamodb.model.ExecuteStatementRequest;
import software.amazon.dynamodb.model.ExecuteStatementResult;
import software.amazon.dynamodb.model.InternalServerErrorException;
import software.amazon.dynamodb.model.ItemCollectionSizeLimitExceededException;
import software.amazon.dynamodb.model.ProvisionedThroughputExceededException;
import software.amazon.dynamodb.model.RequestLimitExceededException;
import software.amazon.dynamodb.model.ResourceNotFoundException;
import software.amazon.dynamodb.model.TransactionConflictException;

public class DynamoDBPartiQGettingStarted {

    public static void main(String[] args) {
        // Create the DynamoDB Client with the region you want
        AmazonDynamoDB dynamoDB = createDynamoDbClient("us-west-1");

        try {
            // Create ExecuteStatementRequest
            ExecuteStatementRequest executeStatementRequest = new ExecuteStatementRequest();
            List<AttributeValue> parameters= getPartiQLParameters();

            //Create an item in the Music table using the INSERT PartiQL statement
            processResults(executeStatementRequest(dynamoDB, "INSERT INTO Music value {'Artist':?,'SongTitle':?}", parameters));

            //Retrieve an item from the Music table using the SELECT PartiQL statement.
            processResults(executeStatementRequest(dynamoDB, "SELECT * FROM Music  where Artist=? and SongTitle=?", parameters));

            //Update an item in the Music table using the UPDATE PartiQL statement.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET AwardsWon=1 SET AwardDetail={'Grammys':[2020, 2018]}  where Artist=? and SongTitle=?", parameters));

            //Add a list value for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET AwardDetail.Grammys =list_append(AwardDetail.Grammys,[2016])  where Artist=? and SongTitle=?", parameters));

            //Remove a list value for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music REMOVE AwardDetail.Grammys[2]   where Artist=? and SongTitle=?", parameters));

            //Add a new map member for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music set AwardDetail.BillBoard=[2020] where Artist=? and SongTitle=?", parameters));

            //Add a new string set attribute for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET BandMembers =<<'member1', 'member2'>> where Artist=? and SongTitle=?", parameters));

            //update a string set attribute for an item in the Music table.
            processResults(executeStatementRequest(dynamoDB, "UPDATE Music SET BandMembers =set_add(BandMembers, <<'newmember'>>) where Artist=? and SongTitle=?", parameters));

            //Retrieve an item from the Music table using the SELECT PartiQL statement.
            processResults(executeStatementRequest(dynamoDB, "SELECT * FROM Music  where Artist=? and SongTitle=?", parameters));

            //delete an item from the Music Table
            processResults(executeStatementRequest(dynamoDB, "DELETE  FROM Music  where Artist=? and SongTitle=?", parameters));
        } catch (Exception e) {
            handleExecuteStatementErrors(e);
        }
    }

    private static AmazonDynamoDB createDynamoDbClient(String region) {
        return AmazonDynamoDBClientBuilder.standard().withRegion(region).build();
    }

    private static List<AttributeValue> getPartiQLParameters() {
        List<AttributeValue> parameters = new ArrayList<AttributeValue>();
        parameters.add(new AttributeValue("Acme Band"));
        parameters.add(new AttributeValue("PartiQL Rocks"));
        return parameters;
    }

    private static ExecuteStatementResult executeStatementRequest(AmazonDynamoDB client, String statement, List<AttributeValue> parameters ) {
        ExecuteStatementRequest request = new ExecuteStatementRequest();
        request.setStatement(statement);
        request.setParameters(parameters);
        return client.executeStatement(request);
    }

    private static void processResults(ExecuteStatementResult executeStatementResult) {
        System.out.println("ExecuteStatement successful: "+ executeStatementResult.toString());

    }

    // Handles errors during ExecuteStatement execution. Use recommendations in error messages below to add error handling specific to
    // your application use-case.
    private static void handleExecuteStatementErrors(Exception exception) {
        try {
            throw exception;
        } catch (ConditionalCheckFailedException ccfe) {
            System.out.println("Condition check specified in the operation failed, review and update the condition " +
                                       "check before retrying. Error: " + ccfe.getErrorMessage());
        } catch (TransactionConflictException tce) {
            System.out.println("Operation was rejected because there is an ongoing transaction for the item, generally " +
                                       "safe to retry with exponential back-off. Error: " + tce.getErrorMessage());
        } catch (ItemCollectionSizeLimitExceededException icslee) {
            System.out.println("An item collection is too large, you\'re using Local Secondary Index and exceeded " +
                                       "size limit of items per partition key. Consider using Global Secondary Index instead. Error: " + icslee.getErrorMessage());
        } catch (Exception e) {
            handleCommonErrors(e);
        }
    }

    private static void handleCommonErrors(Exception exception) {
        try {
            throw exception;
        } catch (InternalServerErrorException isee) {
            System.out.println("Internal Server Error, generally safe to retry with exponential back-off. Error: " + isee.getErrorMessage());
        } catch (RequestLimitExceededException rlee) {
            System.out.println("Throughput exceeds the current throughput limit for your account, increase account level throughput before " +
                                       "retrying. Error: " + rlee.getErrorMessage());
        } catch (ProvisionedThroughputExceededException ptee) {
            System.out.println("Request rate is too high. If you're using a custom retry strategy make sure to retry with exponential back-off. " +
                                       "Otherwise consider reducing frequency of requests or increasing provisioned capacity for your table or secondary index. Error: " +
                                       ptee.getErrorMessage());
        } catch (ResourceNotFoundException rnfe) {
            System.out.println("One of the tables was not found, verify table exists before retrying. Error: " + rnfe.getErrorMessage());
        } catch (AmazonServiceException ase) {
            System.out.println("An AmazonServiceException occurred, indicates that the request was correctly transmitted to the DynamoDB " +
                                       "service, but for some reason, the service was not able to process it, and returned an error response instead. Investigate and " +
                                       "configure retry strategy. Error type: " + ase.getErrorType() + ". Error message: " + ase.getErrorMessage());
        } catch (AmazonClientException ace) {
            System.out.println("An AmazonClientException occurred, indicates that the client was unable to get a response from DynamoDB " +
                                       "service, or the client was unable to parse the response from the service. Investigate and configure retry strategy. "+
                                       "Error: " + ace.getMessage());
        } catch (Exception e) {
            System.out.println("An exception occurred, investigate and configure retry strategy. Error: " + e.getMessage());
        }
    }

}
```

------

## パラメータ化されたステートメントの使用
<a name="ql-gettingstarted.parameterized"></a>

PartiQL ステートメント文字列に値を直接埋め込む代わりに、疑問符 (`?`) プレースホルダーを使用して、`Parameters` フィールドに値を個別に指定できます。各 `?` は、指定された順序で、対応するパラメータ値に置き換えられます。

パラメータ化されたステートメントを使用すると、ステートメント構造がデータ値から分離され、ステートメントの読み取りと再利用が容易になるため、ベストプラクティスです。また、ステートメント文字列の属性値を手動でフォーマットしたりエスケープしたりする必要もなくなります。

パラメータ化されたステートメントは `ExecuteStatement`、`BatchExecuteStatement`、および `ExecuteTransaction` オペレーションでサポートされています。

次の例では、パーティションキーとソートキーのパラメータ化された値を使用して、`Music` テーブルから項目を取得します。

------
#### [ AWS CLI parameterized ]

```
aws dynamodb execute-statement \
    --statement "SELECT * FROM \"Music\" WHERE Artist=? AND SongTitle=?" \
    --parameters '[{"S": "Acme Band"}, {"S": "PartiQL Rocks"}]'
```

------
#### [ Java parameterized ]

```
List<AttributeValue> parameters = new ArrayList<>();
parameters.add(new AttributeValue("Acme Band"));
parameters.add(new AttributeValue("PartiQL Rocks"));

ExecuteStatementRequest request = new ExecuteStatementRequest()
    .withStatement("SELECT * FROM Music WHERE Artist=? AND SongTitle=?")
    .withParameters(parameters);

ExecuteStatementResult result = dynamoDB.executeStatement(request);
```

------
#### [ Python parameterized ]

```
response = dynamodb_client.execute_statement(
    Statement="SELECT * FROM Music WHERE Artist=? AND SongTitle=?",
    Parameters=[
        {'S': 'Acme Band'},
        {'S': 'PartiQL Rocks'}
    ]
)
```

------

**注記**  
前の開始方法セクションの Java の例では、全体にわたってパラメータ化されたステートメントを使用しています。`getPartiQLParameters()` メソッドはパラメータリストを構築し、各ステートメントはインライン値の代わりに `?` プレースホルダーを使用します。

# DynamoDB の PartiQL データ型
<a name="ql-reference.data-types"></a>

次の表に、DynamoDB 用の PartiQL で使用できるデータ型を、一覧で表示します。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/ql-reference.data-types.html)

## 例
<a name="ql-reference.data-types"></a>

次のデータ型を挿入する方法を、次のステートメントで示します。`String`、`Number`、`Map`、`List`、`Number Set` および `String Set`。

```
INSERT INTO TypesTable value {'primarykey':'1', 
'NumberType':1,
'MapType' : {'entryname1': 'value', 'entryname2': 4}, 
'ListType': [1,'stringval'], 
'NumberSetType':<<1,34,32,4.5>>, 
'StringSetType':<<'stringval','stringval2'>>
}
```

次のステートメントでは、`Map`、`List`、`Number Set` および `String Set` の型に、新しい要素を挿入する方法を示しています。また、`Number` 型の値を変更する方法も示しています。

```
UPDATE TypesTable 
SET NumberType=NumberType + 100 
SET MapType.NewMapEntry=[2020, 'stringvalue', 2.4]
SET ListType = LIST_APPEND(ListType, [4, <<'string1', 'string2'>>])
SET NumberSetType= SET_ADD(NumberSetType, <<345, 48.4>>)
SET StringSetType = SET_ADD(StringSetType, <<'stringsetvalue1', 'stringsetvalue2'>>)
WHERE primarykey='1'
```

次のステートメントでは、`Map`、`List`、`Number Set` および `String Set` の型から要素を削除する方法を示しています。また、`Number` 型の値を変更する方法も示しています。

```
UPDATE TypesTable 
SET NumberType=NumberType - 1
REMOVE ListType[1]
REMOVE MapType.NewMapEntry
SET NumberSetType = SET_DELETE( NumberSetType, <<345>>)
SET StringSetType = SET_DELETE( StringSetType, <<'stringsetvalue1'>>)
WHERE primarykey='1'
```

詳細については、「[DynamoDB のデータ型](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes)」を参照してください。

# DynamoDB 用の PartiQL ステートメント
<a name="ql-reference.statements"></a>

Amazon DynamoDB は、次の PartiQL ステートメントをサポートしています。

**注記**  
DynamoDB はすべての PartiQL ステートメントをサポートしているわけではありません。  
このリファレンスでは、AWS CLI シェルまたは API で手動で実行する PartiQL ステートメントについて、ベーシックな構文と使用例を示します。

*データ操作言語* (DML) は、DynamoDB テーブル内のデータを管理するために使用する、PartiQL ステートメントのセットです。DML ステートメントを使用して、テーブル内のデータを追加、変更、または削除します。

次の DML ステートメントとクエリ言語ステートメントがサポートされています。
+ [DynamoDB 用の PartiQL select ステートメント](ql-reference.select.md)
+ [DynamoDB 用の PartiQL 更新ステートメント](ql-reference.update.md)
+ [DynamoDB 用の PartiQL 挿入ステートメント](ql-reference.insert.md)
+ [DynamoDB 用の PartiQL 削除ステートメント](ql-reference.delete.md)

[DynamoDB 用の PartiQL を使用してトランザクションを実行する](ql-reference.multiplestatements.transactions.md) および [DynamoDB 用の PartiQL を使用してバッチ操作を実行する](ql-reference.multiplestatements.batching.md) は、DynamoDB 用の PartiQL でもサポートされています。

# DynamoDB 用の PartiQL select ステートメント
<a name="ql-reference.select"></a>

Amazon DynamoDB では、`SELECT` ステートメントを使用して、テーブルからデータを取得します。

`SELECT` ステートメントを使用すると、パーティションキーを持つ等価条件または IN 条件が WHERE 句で指定されていない場合、完全なテーブルスキャンになることがあります。スキャンオペレーションは、すべての項目でリクエストされた値を調べるので、大きなテーブルまたはインデックスに対してプロビジョニングされたスループットを 1 回のオペレーションで使い果たすことがあります。

PartiQL で完全なテーブルスキャンを避けたい場合は、次のようにします。
+ 完全なテーブルスキャンが行われないように、[WHERE 句の条件](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ql-reference.select.html#ql-reference.select.parameters)を適切に設定していることを確かめながら、`SELECT` ステートメントを作成します。
+ DynamoDB デベロッパーガイドの [例: DynamoDB 用の PartiQL で ステートメントの選択を許可し、テーブル全体のスキャンを行うステートメントを拒否する](ql-iam.md#access-policy-ql-iam-example6) に記載されているように、IAM ポリシーを使用して、完全なテーブルスキャンを無効にします。

詳細については、「DynamoDB デベロッパーガイド」の「[データのクエリとスキャンのベストプラクティス](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-query-scan.html)」を参照してください。

**Topics**
+ [構文](#ql-reference.select.syntax)
+ [パラメータ](#ql-reference.select.parameters)
+ [例](#ql-reference.select.examples)

## 構文
<a name="ql-reference.select.syntax"></a>

```
SELECT expression  [, ...] 
FROM table[.index]
[ WHERE condition ] [ [ORDER BY key [DESC|ASC] , ...]
```

## パラメータ
<a name="ql-reference.select.parameters"></a>

***expression***  
(必須) `*` ワイルドカードからの射影、または結果セットからの 1 つ以上の属性名かドキュメントパスの射影リスト。式には、[DynamoDB での PartiQL 関数の使用](ql-functions.md) への呼び出し、または [DynamoDB での PartiQL 算術演算子、比較演算子、論理演算子](ql-operators.md) によって変更されたフィールドで構成できます。

***テーブル*\$1**  
(必須) クエリするテーブル名。

*** インデックス***  
(オプション) クエリを実行するインデックスの名前です。  
インデックスにクエリを実行するときは、テーブル名とインデックス名に二重引用符を追加する必要があります。  

```
SELECT * 
FROM "TableName"."IndexName"
```

***condition***  
(オプション) クエリの選択条件。  
`SELECT` ステートメントによって、完全なテーブルスキャンが行われないようにするには、`WHERE` 句の条件がパーティションキーを指定する必要があります。等価演算子または IN 演算子を使用します。  
例えば、`OrderID` パーティションキーと、`Address` を含むその他の非キー属性がある `Orders` テーブルがある場合、次のステートメントは完全なテーブルスキャンを実行しません。  

```
SELECT * 
FROM "Orders" 
WHERE OrderID = 100

SELECT * 
FROM "Orders" 
WHERE OrderID = 100 and Address='some address'

SELECT * 
FROM "Orders" 
WHERE OrderID = 100 or OrderID = 200

SELECT * 
FROM "Orders" 
WHERE OrderID IN [100, 300, 234]
```
ただし、次の `SELECT` ステートメントを実行すると、完全なテーブルスキャンが行われます。  

```
SELECT * 
FROM "Orders" 
WHERE OrderID > 1

SELECT * 
FROM "Orders" 
WHERE Address='some address'

SELECT * 
FROM "Orders" 
WHERE OrderID = 100 OR Address='some address'
```

***key***  
(任意) 返ってきた結果の並び替えに使用するハッシュキーまたはソートキー。デフォルトの順序は昇順 (`ASC`) です。返ってきた結果を降順に並べる場合は、`DESC` を指定します。

**注記**  
`WHERE` 句を省略すると、テーブル内のすべての項目が取得されます。

## 例
<a name="ql-reference.select.examples"></a>

次のクエリは、`Orders` テーブルでパーティションキーと `OrderID` を指定し、等価演算子を使用することで、存在する場合に項目を 1 つ返します。

```
SELECT OrderID, Total
FROM "Orders"
WHERE OrderID = 1
```

次のクエリは、OR 演算子を使用することで、特定のパーティションキーと `OrderID`、値を持つ `Orders` テーブルから、すべての項目を返します。

```
SELECT OrderID, Total
FROM "Orders"
WHERE OrderID = 1 OR OrderID = 2
```

次のクエリは、IN 演算子を使用することで、特定のパーティションキーと `OrderID`、値を持つ `Orders` テーブルから、すべての項目を返します。返ってきた結果は、`OrderID` キー属性の値によって、降順に並べられます。

```
SELECT OrderID, Total
FROM "Orders"
WHERE OrderID IN [1, 2, 3] ORDER BY OrderID DESC
```

次のクエリは、`Total` が非キー属性である場合に、`Total` が 500 以上である `Orders` テーブルからすべての項目を返す、完全なテーブルスキャンを示します。

```
SELECT OrderID, Total 
FROM "Orders"
WHERE Total > 500
```

次のクエリは、IN 演算子と非キー属性である `Total` を使用して、特定の `Total` 範囲の順序で、`Orders` テーブルからすべての項目を返す、完全なテーブルスキャンを示します。

```
SELECT OrderID, Total 
FROM "Orders"
WHERE Total IN [500, 600]
```

次のクエリは、BETWEEN 演算子と非キー属性である `Total` を使用して、特定の `Total` 範囲の順序で、`Orders` テーブルからすべての項目を返す、完全なテーブルスキャンを示します。

```
SELECT OrderID, Total 
FROM "Orders" 
WHERE Total BETWEEN 500 AND 600
```

次のクエリは、WHERE 句の条件で `CustomerID` パーティションキーと `MovieID` ソートキーを指定し、SELECT 句でドキュメントのパスを使用することで、firestick デバイスで視聴を開始した最初の日付を返します。

```
SELECT Devices.FireStick.DateWatched[0] 
FROM WatchList 
WHERE CustomerID= 'C1' AND MovieID= 'M1'
```

次のクエリは、テーブル全体のスキャンを示しています。このスキャンでは、WHERE 句の条件でドキュメントのパスを使用し、2019 年 12 月 24 日以降に初めて firestick デバイスを使用した項目のリストを返します。

```
SELECT Devices 
FROM WatchList 
WHERE Devices.FireStick.DateWatched[0] >= '12/24/19'
```

# DynamoDB 用の PartiQL 更新ステートメント
<a name="ql-reference.update"></a>

`UPDATE` ステートメントを使用して、Amazon DynamoDB テーブルの項目内にある、1 つ以上の属性の値を変更します。

**注記**  
一度に更新できる項目は 1 つだけです。1 つの DynamoDB PartiQL ステートメントを発行して、複数の項目を更新することはできません。複数項目の更新については、「[DynamoDB 用の PartiQL を使用してトランザクションを実行する](ql-reference.multiplestatements.transactions.md)」または「[DynamoDB 用の PartiQL を使用してバッチ操作を実行する](ql-reference.multiplestatements.batching.md)」を参照してください。

**Topics**
+ [構文](#ql-reference.update.syntax)
+ [パラメータ](#ql-reference.update.parameters)
+ [戻り値](#ql-reference.update.return)
+ [例](#ql-reference.update.examples)

## 構文
<a name="ql-reference.update.syntax"></a>

```
UPDATE  table  
[SET | REMOVE]  path  [=  data] […]
WHERE condition [RETURNING returnvalues]
<returnvalues>  ::= [ALL OLD | MODIFIED OLD | ALL NEW | MODIFIED NEW] *
```

## パラメータ
<a name="ql-reference.update.parameters"></a>

***テーブル*\$1**  
(必須) 修正されるデータを含んでいるテーブル。

***パス***  
(必須) 作成または変更される属性名、またはドキュメントパス。

***data***  
(必須) 属性値またはオペレーションの結果。  
SET で使用するためにサポートされている操作は、次の通りです。  
+ LIST\$1APPEND: List 型に値を追加します。
+ SET\$1ADD: 数値または文字列セットに値を追加します。
+ SET\$1DELETE: 数値または文字列セットから値を削除します。

***condition***  
(必須) 修正される項目の選択条件。この条件は、単一のプライマリキー値を解決する必要があります。

***returnvalues***  
(オプション) 属性が更新される前か、更新された後に、表示された項目の属性を取得したい場合に、`returnvalues` を使用します。有効な値は以下のとおりです。  
+ `ALL OLD *`: 更新操作の前に表示されていた項目について、すべての属性を返します。
+ `MODIFIED OLD *`: 更新操作の前に表示されていた属性について、更新された属性だけを返します。
+ `ALL NEW *`: 更新操作の後に表示される項目について、すべての属性を返します。
+ `MODIFIED NEW *`: `UpdateItem` 操作の後に表示される属性について、更新された属性だけを返します。

## 戻り値
<a name="ql-reference.update.return"></a>

`returnvalues` パラメータが指定されない限り、このステートメントは値を返しません。

**注記**  
UPDATE ステートメントの WHERE 句が、DynamoDB テーブルのどの項目も true と評価しない場合、`ConditionalCheckFailedException` が返ります。

## 例
<a name="ql-reference.update.examples"></a>

既存の項目の属性値を更新します。属性が存在しない場合は、作成されます。

次のクエリは、数値型の属性 (`AwardsWon`) とマップ型の属性 (`AwardDetail`) を追加して、`"Music"` テーブルの項目を更新します。

```
UPDATE "Music" 
SET AwardsWon=1 
SET AwardDetail={'Grammys':[2020, 2018]}  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

`RETURNING ALL OLD *` を追加すると、`Update` 操作の前に表示されていた属性を返すことができます。

```
UPDATE "Music" 
SET AwardsWon=1 
SET AwardDetail={'Grammys':[2020, 2018]}  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
RETURNING ALL OLD *
```

以下が返されます。

```
{
    "Items": [
        {
            "Artist": {
                "S": "Acme Band"
            },
            "SongTitle": {
                "S": "PartiQL Rocks"
            }
        }
    ]
}
```

`RETURNING ALL NEW *` を追加すると、`Update` 操作の後に表示されていた属性を返すことができます。

```
UPDATE "Music" 
SET AwardsWon=1 
SET AwardDetail={'Grammys':[2020, 2018]}  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
RETURNING ALL NEW *
```

以下が返されます。

```
{
    "Items": [
        {
            "AwardDetail": {
                "M": {
                    "Grammys": {
                        "L": [
                            {
                                "N": "2020"
                            },
                            {
                                "N": "2018"
                            }
                        ]
                    }
                }
            },
            "AwardsWon": {
                "N": "1"
            }
        }
    ]
}
```

次のクエリは、`"Music"` テーブルの項目を、`AwardDetail.Grammys` リストに追加して更新します。

```
UPDATE "Music" 
SET AwardDetail.Grammys =list_append(AwardDetail.Grammys,[2016])  
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

次のクエリは、`"Music"` テーブルの項目を、`AwardDetail.Grammys` リストから削除して更新します。

```
UPDATE "Music" 
REMOVE AwardDetail.Grammys[2]   
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

次のクエリは、`"Music"` テーブルで `AwardDetail` マップに `BillBoard` を追加して、項目を更新します。

```
UPDATE "Music" 
SET AwardDetail.BillBoard=[2020] 
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

次のクエリは、`"Music"` テーブルで、文字列セットの属性 `BandMembers` を追加して、項目を更新します。

```
UPDATE "Music" 
SET BandMembers =<<'member1', 'member2'>> 
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

次のクエリは、`"Music"` テーブルで文字列セットの属性 `BandMembers` に `newbandmember` を追加して、項目を更新します。

```
UPDATE "Music" 
SET BandMembers =set_add(BandMembers, <<'newbandmember'>>) 
WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'
```

# DynamoDB 用の PartiQL 削除ステートメント
<a name="ql-reference.delete"></a>

`DELETE` ステートメントを使用して、Amazon DynamoDB テーブルにある項目を削除します。

**注記**  
一度に削除できる項目は 1 つだけです。1 つの DynamoDB PartiQL ステートメントを発行して、複数の項目を削除することはできません。複数のアイテムの削除については、「[DynamoDB 用の PartiQL を使用してトランザクションを実行する](ql-reference.multiplestatements.transactions.md)」または「[DynamoDB 用の PartiQL を使用してバッチ操作を実行する](ql-reference.multiplestatements.batching.md)」を参照してください。

**Topics**
+ [構文](#ql-reference.delete.syntax)
+ [パラメータ](#ql-reference.delete.parameters)
+ [戻り値](#ql-reference.delete.return)
+ [例](#ql-reference.delete.examples)

## 構文
<a name="ql-reference.delete.syntax"></a>

```
DELETE FROM table 
 WHERE condition [RETURNING returnvalues]
 <returnvalues>  ::= ALL OLD *
```

## パラメータ
<a name="ql-reference.delete.parameters"></a>

***テーブル*\$1**  
(必須) 削除する項目を含む DynamoDB テーブル。

***condition***  
(必須) 削除する項目の選択基準。この条件は、単一のプライマリキー値を解決する必要があります。

***returnvalues***  
(オプション) 削除される前に表示された、項目の属性を取得したい場合には、`returnvalues` を使用します。有効な値は以下のとおりです。  
+ `ALL OLD *`: 古い項目の内容が返されます。

## 戻り値
<a name="ql-reference.delete.return"></a>

`returnvalues` パラメータが指定されない限り、このステートメントは値を返しません。

**注記**  
DynamoDB テーブルに、DELETE が発行された項目と同じプライマリキーを持つ項目が無い場合、削除した項目を 0 としたうえで、SUCCESS を返します。テーブルに同じプライマリキーを持つ項目があるが、DELETE ステートメントの WHERE 句の条件で false と評価された場合、`ConditionalCheckFailedException` が返されます。

## 例
<a name="ql-reference.delete.examples"></a>

次のクエリは、`"Music"` テーブルの項目を削除します。

```
DELETE FROM "Music" WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks'
```

`RETURNING ALL OLD *` を追加すると、削除されたデータを返すことができます。

```
DELETE FROM "Music" WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks' RETURNING ALL OLD *
```

`Delete` ステートメントは、以下を返すようになりました。

```
{
    "Items": [
        {
            "Artist": {
                "S": "Acme Band"
            },
            "SongTitle": {
                "S": "PartiQL Rocks"
            }
        }
    ]
}
```

# DynamoDB 用の PartiQL 挿入ステートメント
<a name="ql-reference.insert"></a>

`INSERT` ステートメントを使用して、Amazon DynamoDB のテーブルに項目を追加します。

**注記**  
一度に挿入できる項目は 1 つだけです。1 つの DynamoDB PartiQL ステートメントを発行して、複数の項目を挿入することはできません。複数の項目の挿入については、「[DynamoDB 用の PartiQL を使用してトランザクションを実行する](ql-reference.multiplestatements.transactions.md)」または「[DynamoDB 用の PartiQL を使用してバッチ操作を実行する](ql-reference.multiplestatements.batching.md)」を参照してください。

**Topics**
+ [構文](#ql-reference.insert.syntax)
+ [パラメータ](#ql-reference.insert.parameters)
+ [戻り値](#ql-reference.insert.return)
+ [例](#ql-reference.insert.examples)

## 構文
<a name="ql-reference.insert.syntax"></a>

項目を 1 つ挿入します。

```
INSERT INTO table VALUE item
```

## パラメータ
<a name="ql-reference.insert.parameters"></a>

***テーブル*\$1**  
(必須) データを挿入するテーブル。このテーブルは既存であることが必要です。

***item***  
(必須) 有効な DynamoDB 項目は [PartiQL タプル](https://partiql.org/docs.html)。*1 つ*の項目のみ指定する必要があります。また、項目の各属性名は大文字と小文字が区別され、PartiQL では*一重*引用符 (`'...'`) で示されます。  
文字列値は、PartiQL では*一重*引用符 (`'...'`) で示されます。

## 戻り値
<a name="ql-reference.insert.return"></a>

このステートメントは値を返しません。

**注記**  
DynamoDB テーブルに、挿入される項目と同じプライマリキーを持つ項目が既にある場合、`DuplicateItemException` が返されます。

## 例
<a name="ql-reference.insert.examples"></a>

```
INSERT INTO "Music" value {'Artist' : 'Acme Band','SongTitle' : 'PartiQL Rocks'}
```

# DynamoDB での PartiQL 関数の使用
<a name="ql-functions"></a>

Amazon DynamoDB の PartiQL は、次の SQL 標準関数の組み込みバージョンをサポートしています。

**注記**  
このリストに含まれていない SQL 関数は、DynamoDB で現在サポートされていません。

## 集計関数
<a name="ql-functions.aggregate"></a>
+ [Amazon DynamoDB 用の PartiQL で SIZE 関数を使用する](ql-functions.size.md)

## 条件関数
<a name="ql-functions.conditional"></a>
+ [DynamoDB 用の PartiQL での EXISTS 関数の使用](ql-functions.exists.md)
+ [DynamoDB 用の PartiQL で ATTRIBUTE\$1TYPE 関数を使用する](ql-functions.attribute_type.md)
+ [DynamoDB 用の PartiQL で BEGINS\$1WITH 関数を使用する](ql-functions.beginswith.md)
+ [DynamoDB 用の PartiQL で CONTAINS 関数を使用する](ql-functions.contains.md)
+ [DynamoDB 用の PartiQL で MISSING 関数を使用する](ql-functions.missing.md)

# DynamoDB 用の PartiQL での EXISTS 関数の使用
<a name="ql-functions.exists"></a>

EXISTS を使用して、`ConditionCheck` が [TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems) API で実行するのと同じ機能を実行できます。EXISTS 関数は、トランザクションでのみ使用できます。

値が指定されると、値が空でないコレクションである場合に `TRUE` を返します。それ以外の場合は `FALSE` を返します。

**注記**  
この関数は、トランザクション操作でのみ使用できます。

## 構文
<a name="ql-functions.exists.syntax"></a>

```
EXISTS ( statement )
```

## 引数
<a name="ql-functions.exists.arguments"></a>

*statement*  
(必須) 関数が評価する SELECT ステートメント。  
SELECT 文では、完全なプライマリキーと他の条件を、1 つ指定する必要があります。

## 戻り型
<a name="ql-functions.exists.return-type"></a>

`bool`

## 例
<a name="ql-functions.exists.examples"></a>

```
EXISTS(
    SELECT * FROM "Music" 
    WHERE "Artist" = 'Acme Band' AND "SongTitle" = 'PartiQL Rocks')
```

# DynamoDB 用の PartiQL で BEGINS\$1WITH 関数を使用する
<a name="ql-functions.beginswith"></a>

指定した属性が特定の部分文字列から始まる場合、`TRUE` を返します。

## 構文
<a name="ql-functions.beginswith.syntax"></a>

```
begins_with(path, value )
```

## 引数
<a name="ql-functions.beginswith.arguments"></a>

*パス*  
(必須) 使用する属性名またはドキュメントのパス。

*value*  
(必須) 検索対象の文字列。

## 戻り型
<a name="ql-functions.beginswith.return-type"></a>

`bool`

## 例
<a name="ql-functions.beginswith.examples"></a>

```
SELECT * FROM "Orders" WHERE "OrderID"=1 AND begins_with("Address", '7834 24th')
```

# DynamoDB 用の PartiQL で MISSING 関数を使用する
<a name="ql-functions.missing"></a>

指定した属性が項目に含まれていない場合、`TRUE` を返します。この関数では、等価演算子および不等価演算子のみを使用できます。

## 構文
<a name="ql-functions.missing.syntax"></a>

```
 attributename IS | IS NOT  MISSING 
```

## 引数
<a name="ql-functions.missing.arguments"></a>

*attributename*  
(必須) 検索対象の属性名。

## 戻り型
<a name="ql-functions.missing.return-type"></a>

`bool`

## 例
<a name="ql-functions.missing.examples"></a>

```
SELECT * FROM Music WHERE "Awards" is MISSING
```

# DynamoDB 用の PartiQL で ATTRIBUTE\$1TYPE 関数を使用する
<a name="ql-functions.attribute_type"></a>

指定したパスの属性が特定のデータ型のものである場合、`TRUE` を返します。

## 構文
<a name="ql-functions.attribute_type.syntax"></a>

```
attribute_type( attributename, type )
```

## 引数
<a name="ql-functions.attribute_type.arguments"></a>

*attributename*  
(必須) 使用する属性名。

*type*  
(必須) チェックする属性タイプ。有効な値のリストについては、DynamoDB の「[attribute\$1type](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions)」を参照してください。

## 戻り型
<a name="ql-functions.attribute_type.return-type"></a>

`bool`

## 例
<a name="ql-functions.attribute_type.examples"></a>

```
SELECT * FROM "Music" WHERE attribute_type("Artist", 'S')
```

# DynamoDB 用の PartiQL で CONTAINS 関数を使用する
<a name="ql-functions.contains"></a>

パスで指定した属性が次のいずれかである場合、`TRUE` を返します。
+ 特定の部分文字列を含む文字列型。
+ 特定の要素を含むセット型。

詳細については、DynamoDB の「[contains](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) 関数」を参照してください。

## 構文
<a name="ql-functions.contains.syntax"></a>

```
contains( path, substring )
```

## 引数
<a name="ql-functions.contains.arguments"></a>

*パス*  
(必須) 使用する属性名またはドキュメントのパス。

*substring*  
(必須) チェックする対象の属性の部分文字列またはセットのメンバー。詳細については、DynamoDB の「[contains](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) 関数」を参照してください。

## 戻り型
<a name="ql-functions.contains.return-type"></a>

`bool`

## 例
<a name="ql-functions.contains.examples"></a>

```
SELECT * FROM "Orders" WHERE "OrderID"=1 AND contains("Address", 'Kirkland')
```

# Amazon DynamoDB 用の PartiQL で SIZE 関数を使用する
<a name="ql-functions.size"></a>

属性のサイズを表す数値をバイト単位で返します。Size で使用できる有効なデータ型は、次の通りです。詳細については、DynamoDB の「[size](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) 関数」を参照してください。

## 構文
<a name="ql-functions.size.syntax"></a>

```
size( path)
```

## 引数
<a name="ql-functions.size.arguments"></a>

*パス*  
(必須) 属性名またはドキュメントのパス。  
サポートされているタイプについては、DynamoDB の「[size](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) 関数」を参照してください。

## 戻り型
<a name="ql-functions.size.return-type"></a>

`int`

## 例
<a name="ql-functions.size.examples"></a>

```
 SELECT * FROM "Orders" WHERE "OrderID"=1 AND size("Image") >300
```

# DynamoDB での PartiQL 算術演算子、比較演算子、論理演算子
<a name="ql-operators"></a>

Amazon DynamoDB の PartiQL は、次の [SQL 標準演算子](https://www.w3schools.com/sql/sql_operators.asp)をサポートしています。

**注記**  
このリストに含まれていない SQL 演算子は、DynamoDB で現在サポートされていません。

## 算術演算子
<a name="ql-operators.arithmetic"></a>


****  

| 演算子 | 説明 | 
| --- | --- | 
| \$1 | Add | 
| - | - (減算) | 

## 比較演算子
<a name="ql-operators.comparison"></a>


****  

| 演算子 | 説明 | 
| --- | --- | 
| = | Equal to | 
| <> | 等しくない | 
| \$1= | 等しくない | 
| > | 超 | 
| < | 未満 | 
| >= | 以上 | 
| <= | 以下 | 

## 論理演算子
<a name="ql-operators.logical"></a>


****  

| 演算子 | 説明 | 
| --- | --- | 
| AND | TRUE AND で区切られたすべての条件が TRUE の場合に | 
| BETWEEN |  `TRUE` オペランドが比較の範囲内にある場合に この演算子には、適用するオペランドの下限と上限が含まれます。  | 
| IN | `TRUE` オペランドが (最大 50 ハッシュ属性値、または 100 個の非キー属性値において) 式のリストの 1 つに等しい場合。 結果は最大 10 項目までのページで返されます。`IN` リストにより多くの値が含まれている場合は、レスポンスで返された `NextToken` を使用して後続のページを取得する必要があります。 | 
| IS | TRUE オペランドが指定されていて、PartiQL のデータ型であり、NULL または MISSING を含む場合に | 
| NOT | 指定されたブール式の値を反転する | 
| OR | TRUE OR で区切られた条件のいずれかが TRUEの場合に | 

論理演算子の使用の詳細については、「[比較の実行](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.Comparators)」および「[論理評価](Expressions.OperatorsAndFunctions.md#Expressions.OperatorsAndFunctions.LogicalEvaluations)」を参照してください。

# DynamoDB 用の PartiQL を使用してトランザクションを実行する
<a name="ql-reference.multiplestatements.transactions"></a>

このセクションでは、DynamoDB 用の PartiQL でトランザクションを使用する方法について説明します。PartiQL トランザクションは、合計 100 件のステートメント (アクション) に制限されています。

DynamoDB トランザクションの詳細については、「[DynamoDB トランザクションで複雑なワークフローを管理する](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transactions.html)」を参照してください。

**注記**  
トランザクション全体は、読み込みステートメントまたは 書き込みステートメントのいずれかで構成されている必要があります。1 つのトランザクションで両方を混在させることはできません。この EXISTS 関数は例外です。[TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems) API オペレーションの `ConditionCheck` と同様に、項目の特定の属性の状態を確認するために使用できます。

**Topics**
+ [構文](#ql-reference.multiplestatements.transactions.syntax)
+ [パラメータ](#ql-reference.multiplestatements.transactions.parameters)
+ [戻り値](#ql-reference.multiplestatements.transactions.return)
+ [例](#ql-reference.multiplestatements.transactions.examples)

## 構文
<a name="ql-reference.multiplestatements.transactions.syntax"></a>

```
[
   {
      "Statement":" statement ",
      "Parameters":[
         {
            " parametertype " : " parametervalue "
         }, ...]
   } , ...
]
```

## パラメータ
<a name="ql-reference.multiplestatements.transactions.parameters"></a>

***ステートメント***  
(必須) DynamoDB 用の PartiQL がサポートするステートメントです。  
トランザクション全体は、読み込みステートメントまたは 書き込みステートメントのいずれかで構成されている必要があります。1 つのトランザクションで両方を混在させることはできません。

***parametertype***  
(オプション) PartiQL ステートメントを指定するときにパラメータが使用された場合のDynamoDB タイプ。

***parametervalue***  
(オプション) PartiQL ステートメントを指定するときにパラメータが使用された場合のパラメータの値。

## 戻り値
<a name="ql-reference.multiplestatements.transactions.return"></a>

このステートメントは、書き込み操作 (INSERT、UPDATE、DELETE) の値を返しません。ただし、WHERE 句で指定された条件に基づいて、読み取り操作 (SELECT) に対して異なる値を返します。

**注記**  
シングルトンの INSERT、UPDATE、または DELETE 操作のいずれかでエラーが返された場合、`TransactionCanceledException` 例外によりトランザクションがキャンセルされます。キャンセル理由コードには、個々のシングルトン操作からのエラーが含まれます。

## 例
<a name="ql-reference.multiplestatements.transactions.examples"></a>

以下の例では、トランザクションとして複数のステートメントを実行します。

------
#### [ AWS CLI ]

1. 次の JSON コードを partiql.json というファイルに保存します 

   ```
   [
       {
           "Statement": "EXISTS(SELECT * FROM \"Music\" where Artist='No One You Know' and SongTitle='Call Me Today' and Awards is  MISSING)"
       },
       {
           "Statement": "INSERT INTO Music value {'Artist':?,'SongTitle':'?'}",
           "Parameters": [{\"S\": \"Acme Band\"}, {\"S\": \"Best Song\"}]
       },
       {
           "Statement": "UPDATE \"Music\" SET AwardsWon=1 SET AwardDetail={'Grammys':[2020, 2018]}  where Artist='Acme Band' and SongTitle='PartiQL Rocks'"
       }
   ]
   ```

1. コマンドプロンプトで、次のコマンドを実行します。

   ```
   aws dynamodb execute-transaction --transact-statements  file://partiql.json
   ```

------
#### [ Java ]

```
public class DynamoDBPartiqlTransaction {

    public static void main(String[] args) {
        // Create the DynamoDB Client with the region you want
        AmazonDynamoDB dynamoDB = createDynamoDbClient("us-west-2");
        
        try {
            // Create ExecuteTransactionRequest
            ExecuteTransactionRequest executeTransactionRequest = createExecuteTransactionRequest();
            ExecuteTransactionResult executeTransactionResult = dynamoDB.executeTransaction(executeTransactionRequest);
            System.out.println("ExecuteTransaction successful.");
            // Handle executeTransactionResult

        } catch (Exception e) {
            handleExecuteTransactionErrors(e);
        }
    }

    private static AmazonDynamoDB createDynamoDbClient(String region) {
        return AmazonDynamoDBClientBuilder.standard().withRegion(region).build();
    }

    private static ExecuteTransactionRequest createExecuteTransactionRequest() {
        ExecuteTransactionRequest request = new ExecuteTransactionRequest();
        
        // Create statements
        List<ParameterizedStatement> statements = getPartiQLTransactionStatements();

        request.setTransactStatements(statements);
        return request;
    }

    private static List<ParameterizedStatement> getPartiQLTransactionStatements() {
        List<ParameterizedStatement> statements = new ArrayList<ParameterizedStatement>();

        statements.add(new ParameterizedStatement()
                               .withStatement("EXISTS(SELECT * FROM "Music" where Artist='No One You Know' and SongTitle='Call Me Today' and Awards is  MISSING)"));

        statements.add(new ParameterizedStatement()
                               .withStatement("INSERT INTO "Music" value {'Artist':'?','SongTitle':'?'}")
                               .withParameters(new AttributeValue("Acme Band"),new AttributeValue("Best Song")));

        statements.add(new ParameterizedStatement()
                               .withStatement("UPDATE "Music" SET AwardsWon=1 SET AwardDetail={'Grammys':[2020, 2018]}  where Artist='Acme Band' and SongTitle='PartiQL Rocks'"));

        return statements;
    }

    // Handles errors during ExecuteTransaction execution. Use recommendations in error messages below to add error handling specific to 
    // your application use-case.
    private static void handleExecuteTransactionErrors(Exception exception) {
        try {
            throw exception;
        } catch (TransactionCanceledException tce) {
            System.out.println("Transaction Cancelled, implies a client issue, fix before retrying. Error: " + tce.getErrorMessage());
        } catch (TransactionInProgressException tipe) {
            System.out.println("The transaction with the given request token is already in progress, consider changing " +
                "retry strategy for this type of error. Error: " + tipe.getErrorMessage());
        } catch (IdempotentParameterMismatchException ipme) {
            System.out.println("Request rejected because it was retried with a different payload but with a request token that was already used, " +
                "change request token for this payload to be accepted. Error: " + ipme.getErrorMessage());
        } catch (Exception e) {
            handleCommonErrors(e);
        }
    }

    private static void handleCommonErrors(Exception exception) {
        try {
            throw exception;
        } catch (InternalServerErrorException isee) {
            System.out.println("Internal Server Error, generally safe to retry with exponential back-off. Error: " + isee.getErrorMessage());
        } catch (RequestLimitExceededException rlee) {
            System.out.println("Throughput exceeds the current throughput limit for your account, increase account level throughput before " + 
                "retrying. Error: " + rlee.getErrorMessage());
        } catch (ProvisionedThroughputExceededException ptee) {
            System.out.println("Request rate is too high. If you're using a custom retry strategy make sure to retry with exponential back-off. " +
                "Otherwise consider reducing frequency of requests or increasing provisioned capacity for your table or secondary index. Error: " + 
                ptee.getErrorMessage());
        } catch (ResourceNotFoundException rnfe) {
            System.out.println("One of the tables was not found, verify table exists before retrying. Error: " + rnfe.getErrorMessage());
        } catch (AmazonServiceException ase) {
            System.out.println("An AmazonServiceException occurred, indicates that the request was correctly transmitted to the DynamoDB " + 
                "service, but for some reason, the service was not able to process it, and returned an error response instead. Investigate and " +
                "configure retry strategy. Error type: " + ase.getErrorType() + ". Error message: " + ase.getErrorMessage());
        } catch (AmazonClientException ace) {
            System.out.println("An AmazonClientException occurred, indicates that the client was unable to get a response from DynamoDB " +
                "service, or the client was unable to parse the response from the service. Investigate and configure retry strategy. "+
                "Error: " + ace.getMessage());
        } catch (Exception e) {
            System.out.println("An exception occurred, investigate and configure retry strategy. Error: " + e.getMessage());
        }
    }

}
```

------

次の例は、DynamoDB が WHERE 句で指定された異なる条件を持つ項目を読み取るときのさまざまな戻り値を示しています。

------
#### [ AWS CLI ]

1. 次の JSON コードを partiql.json というファイルに保存します

   ```
   [
       // Item exists and projected attribute exists
       {
           "Statement": "SELECT * FROM "Music" WHERE Artist='No One You Know' and SongTitle='Call Me Today'"
       },
       // Item exists but projected attributes do not exist
       {
           "Statement": "SELECT non_existent_projected_attribute FROM "Music" WHERE Artist='No One You Know' and SongTitle='Call Me Today'"
       },
       // Item does not exist
       {
           "Statement": "SELECT * FROM "Music" WHERE Artist='No One I Know' and SongTitle='Call You Today'"
       }
   ]
   ```

1.  コマンドプロンプトで、次のコマンドを実行します。

   ```
   aws dynamodb execute-transaction --transact-statements  file://partiql.json
   ```

1. 以下のレスポンスが返されます。

   ```
   {
       "Responses": [
           // Item exists and projected attribute exists
           {
               "Item": {
                   "Artist":{
                       "S": "No One You Know"
                   },
                   "SongTitle":{
                       "S": "Call Me Today"
                   }    
               }
           },
           // Item exists but projected attributes do not exist
           {
               "Item": {}
           },
           // Item does not exist
           {}
       ]
   }
   ```

------

# DynamoDB 用の PartiQL を使用してバッチ操作を実行する
<a name="ql-reference.multiplestatements.batching"></a>

このセクションでは、DynamoDB 用の PartiQL でバッチステートメントを使用する方法について説明します。

**注記**  
バッチ全体は、読み取りステートメントまたは書き込みステートメントのいずれかで構成する必要があります。1 つのバッチに両方を混在させることはできません。
`BatchExecuteStatement` と `BatchWriteItem` が実行できるステートメントの数は、バッチあたり 25 が上限です。
`BatchExecuteStatement` は、`BatchGetItem` を使用して、個別のステートメントでプライマリキーのリストを取得します。

**Topics**
+ [構文](#ql-reference.multiplestatements.batching.syntax)
+ [パラメータ](#ql-reference.multiplestatements.batching.parameters)
+ [例](#ql-reference.multiplestatements.batching.examples)

## 構文
<a name="ql-reference.multiplestatements.batching.syntax"></a>

```
[
  {
    "Statement": "SELECT pk FROM ProblemSet WHERE pk = 'p#9StkWHYTxm7x2AqSXcrfu7' AND sk = 'info'"
  },
  {
    "Statement": "SELECT pk FROM ProblemSet WHERE pk = 'p#isC2ChceGbxHgESc4szoTE' AND sk = 'info'"
  }
]
```

```
[
   {
      "Statement":" statement ",
      "Parameters":[
         {
            " parametertype " : " parametervalue "
         }, ...]
   } , ...
]
```

## パラメータ
<a name="ql-reference.multiplestatements.batching.parameters"></a>

***ステートメント***  
(必須) DynamoDB 用の PartiQL がサポートするステートメントです。  
+ バッチ全体は、読み取りステートメントまたは書き込みステートメントのいずれかで構成する必要があります。1 つのバッチに両方を混在させることはできません。
+ `BatchExecuteStatement` と `BatchWriteItem` が実行できるステートメントの数は、バッチあたり 25 が上限です。

***parametertype***  
(オプション) PartiQL ステートメントを指定するときにパラメータが使用された場合のDynamoDB タイプ。

***parametervalue***  
(オプション) PartiQL ステートメントを指定するときにパラメータが使用された場合のパラメータの値。

## 例
<a name="ql-reference.multiplestatements.batching.examples"></a>

------
#### [ AWS CLI ]

1. 次の json を partiql.json というファイルに保存します

   ```
   [
      {
   	 "Statement": "INSERT INTO Music VALUE {'Artist':?,'SongTitle':?}",
   	  "Parameters": [{"S": "Acme Band"}, {"S": "Best Song"}]
   	},
   	{
   	 "Statement": "UPDATE Music SET AwardsWon=1, AwardDetail={'Grammys':[2020, 2018]} WHERE Artist='Acme Band' AND SongTitle='PartiQL Rocks'"
       }
   ]
   ```

1. コマンドプロンプトで、次のコマンドを実行します。

   ```
   aws dynamodb batch-execute-statement  --statements  file://partiql.json
   ```

------
#### [ Java ]

```
public class DynamoDBPartiqlBatch {

    public static void main(String[] args) {
        // Create the DynamoDB Client with the region you want
        AmazonDynamoDB dynamoDB = createDynamoDbClient("us-west-2");
        
        try {
            // Create BatchExecuteStatementRequest
            BatchExecuteStatementRequest batchExecuteStatementRequest = createBatchExecuteStatementRequest();
            BatchExecuteStatementResult batchExecuteStatementResult = dynamoDB.batchExecuteStatement(batchExecuteStatementRequest);
            System.out.println("BatchExecuteStatement successful.");
            // Handle batchExecuteStatementResult

        } catch (Exception e) {
            handleBatchExecuteStatementErrors(e);
        }
    }

    private static AmazonDynamoDB createDynamoDbClient(String region) {

        return AmazonDynamoDBClientBuilder.standard().withRegion(region).build();
    }

    private static BatchExecuteStatementRequest createBatchExecuteStatementRequest() {
        BatchExecuteStatementRequest request = new BatchExecuteStatementRequest();

        // Create statements
        List<BatchStatementRequest> statements = getPartiQLBatchStatements();

        request.setStatements(statements);
        return request;
    }

    private static List<BatchStatementRequest> getPartiQLBatchStatements() {
        List<BatchStatementRequest> statements = new ArrayList<BatchStatementRequest>();

        statements.add(new BatchStatementRequest()
                               .withStatement("INSERT INTO Music value {'Artist':'Acme Band','SongTitle':'PartiQL Rocks'}"));

        statements.add(new BatchStatementRequest()
                               .withStatement("UPDATE Music set AwardDetail.BillBoard=[2020] where Artist='Acme Band' and SongTitle='PartiQL Rocks'"));

        return statements;
    }

    // Handles errors during BatchExecuteStatement execution. Use recommendations in error messages below to add error handling specific to 
    // your application use-case.
    private static void handleBatchExecuteStatementErrors(Exception exception) {
        try {
            throw exception;
        } catch (Exception e) {
            // There are no API specific errors to handle for BatchExecuteStatement, common DynamoDB API errors are handled below
            handleCommonErrors(e);
        }
    }

    private static void handleCommonErrors(Exception exception) {
        try {
            throw exception;
        } catch (InternalServerErrorException isee) {
            System.out.println("Internal Server Error, generally safe to retry with exponential back-off. Error: " + isee.getErrorMessage());
        } catch (RequestLimitExceededException rlee) {
            System.out.println("Throughput exceeds the current throughput limit for your account, increase account level throughput before " + 
                "retrying. Error: " + rlee.getErrorMessage());
        } catch (ProvisionedThroughputExceededException ptee) {
            System.out.println("Request rate is too high. If you're using a custom retry strategy make sure to retry with exponential back-off. " +
                "Otherwise consider reducing frequency of requests or increasing provisioned capacity for your table or secondary index. Error: " + 
                ptee.getErrorMessage());
        } catch (ResourceNotFoundException rnfe) {
            System.out.println("One of the tables was not found, verify table exists before retrying. Error: " + rnfe.getErrorMessage());
        } catch (AmazonServiceException ase) {
            System.out.println("An AmazonServiceException occurred, indicates that the request was correctly transmitted to the DynamoDB " + 
                "service, but for some reason, the service was not able to process it, and returned an error response instead. Investigate and " +
                "configure retry strategy. Error type: " + ase.getErrorType() + ". Error message: " + ase.getErrorMessage());
        } catch (AmazonClientException ace) {
            System.out.println("An AmazonClientException occurred, indicates that the client was unable to get a response from DynamoDB " +
                "service, or the client was unable to parse the response from the service. Investigate and configure retry strategy. "+
                "Error: " + ace.getMessage());
        } catch (Exception e) {
            System.out.println("An exception occurred, investigate and configure retry strategy. Error: " + e.getMessage());
        }
    }

}
```

------

# DynamoDB 用 PartiQL における IAM セキュリティポリシー
<a name="ql-iam"></a>

以下のアクセス権限が必要です。
+ DynamoDB 用の PartiQL を使用して項目を読み込むには、`dynamodb:PartiQLSelect` アクセス許可を、テーブルまたはインデックスに付与します。
+ DynamoDB 用の PartiQL を使用して項目を挿入するには、`dynamodb:PartiQLInsert` アクセス許可をテーブルまたはインデックスに付与します。
+ DynamoDB 用の PartiQL を使用して項目を更新するには、`dynamodb:PartiQLUpdate` アクセス許可をテーブルまたはインデックスに付与します。
+ DynamoDB 用の PartiQL を使用して項目を削除するには、`dynamodb:PartiQLDelete` アクセス許可をテーブルまたはインデックスに付与します。

## 例: テーブルに対して、すべての DynamoDB 用の PartiQL ステートメントを許可する (選択、挿入、更新、削除)
<a name="access-policy-ql-iam-example1"></a>

次の IAM ポリシーは、すべての DynamoDB 用の PartiQL ステートメントをテーブルに対して実行するための、アクセス許可を付与します。

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLInsert",
            "dynamodb:PartiQLUpdate",
            "dynamodb:PartiQLDelete",
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ]
      }
   ]
}
```

------

## 例: テーブルに対して、DynamoDB 用の PartiQL 選択ステートメントを許可する
<a name="access-policy-ql-iam-example2"></a>

次の IAM ポリシーは、特定のテーブルに対して `select` ステートメントを実行するためのアクセス許可を付与します。

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ]
      }
   ]
}
```

------

## 例: インデックスに対して、DynamoDB 用の PartiQL 挿入ステートメントを許可する
<a name="access-policy-ql-iam-example3"></a>

次の IAM ポリシーは、特定のインデックスに対して `insert` ステートメントを実行するためのアクセス許可を付与します。

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLInsert"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music/index/index1"
         ]
      }
   ]
}
```

------

## 例: テーブルに対して、DynamoDB 用の PartiQL トランザクションステートメントを許可する
<a name="access-policy-ql-iam-example4"></a>

次の IAM ポリシーは、特定のテーブルに対してトランザクションステートメントだけを実行するためのアクセス許可を付与します。

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLInsert",
            "dynamodb:PartiQLUpdate",
            "dynamodb:PartiQLDelete",
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ],
         "Condition":{
            "StringEquals":{
               "dynamodb:EnclosingOperation":[
                  "ExecuteTransaction"
               ]
            }
         }
      }
   ]
}
```

------

## 例: テーブルに対して、DynamoDB 用の PartiQL 非トランザクションの読み込み/書き込みステートメントを許可し、PartiQL 読み込み/書き込みトランザクションをブロックします。
<a name="access-policy-ql-iam-example5"></a>

 次の IAM ポリシーは、DynamoDB 用の PartiQL トランザクション読み込み/書き込みをブロックしている間に、DynamoDB 用の PartiQL 非トランザクションの読み込み/書き込みを実行するためのアクセス許可を付与します。

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Deny",
         "Action":[
            "dynamodb:PartiQLInsert",
            "dynamodb:PartiQLUpdate",
            "dynamodb:PartiQLDelete",
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ],
         "Condition":{
            "StringEquals":{
               "dynamodb:EnclosingOperation":[
                  "ExecuteTransaction"
               ]
            }
         }
      },
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLInsert",
            "dynamodb:PartiQLUpdate",
            "dynamodb:PartiQLDelete",
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/Music"
         ]
      }
   ]
}
```

------

## 例: DynamoDB 用の PartiQL で ステートメントの選択を許可し、テーブル全体のスキャンを行うステートメントを拒否する
<a name="access-policy-ql-iam-example6"></a>

次の IAM ポリシーは、テーブル全体のスキャンを行う `select` ステートメントをブロックしている間に、特定のテーブルに対して `select` ステートメントを実行するためのアクセス許可を付与します。

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Deny",
         "Action":[
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/WatchList"
         ],
         "Condition":{
            "Bool":{
               "dynamodb:FullTableScan":[
                  "true"
               ]
            }
         }
      },
      {
         "Effect":"Allow",
         "Action":[
            "dynamodb:PartiQLSelect"
         ],
         "Resource":[
            "arn:aws:dynamodb:us-west-2:123456789012:table/WatchList"
         ]
      }
   ]
}
```

------

# 項目の操作: Java
<a name="JavaDocumentAPIItemCRUD"></a>

AWS SDK for Java ドキュメント API を使用して、テーブル内の Amazon DynamoDB 項目に対して、一般的な作成、読み込み、更新、削除 (CRUD) のオペレーションを実行できます。

**注記**  
SDK for Java には、オブジェクト永続性モデルも用意されています。このモデルにより、クライアント側のクラスを DynamoDB テーブルにマッピングすることができます。この方法により、記述する必要のあるコードの量を減らすことができます。詳細については、「」を参照してください[Java 1.x: DynamoDBMapper](DynamoDBMapper.md)

このセクションには、いくつかの Java ドキュメント API 項目のアクションを実行する Java サンプルといくつかの完全な操作例が含まれています。

**Topics**
+ [項目の置換](#PutDocumentAPIJava)
+ [項目の取得](#JavaDocumentAPIGetItem)
+ [バッチ書き込み: 複数の項目の置換および削除](#BatchWriteDocumentAPIJava)
+ [バッチ取得: 複数の項目の取得](#JavaDocumentAPIBatchGetItem)
+ [項目の更新](#JavaDocumentAPIItemUpdate)
+ [項目の削除](#DeleteMidLevelJava)
+ [例: AWS SDK for Java ドキュメント API を使用した CRUD オペレーション](JavaDocumentAPICRUDExample.md)
+ [例: AWS SDK for Java ドキュメント API を使用したバッチオペレーション](batch-operation-document-api-java.md)
+ [例: AWS SDK for Java ドキュメント API を使用したバイナリタイプ属性の処理](JavaDocumentAPIBinaryTypeExample.md)

## 項目の置換
<a name="PutDocumentAPIJava"></a>

`putItem` メソッドによって、項目をテーブルに格納します。項目が存在する場合、その項目全体が置き換えられます。項目全体を置き換える代わりに固有の属性のみを更新する場合は、`updateItem` メソッドを使用できます。詳細については、「」を参照してください[項目の更新](#JavaDocumentAPIItemUpdate) 

------
#### [ Java v2 ]

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.PutItemResponse;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import java.util.HashMap;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 *
 * To place items into an Amazon DynamoDB table using the AWS SDK for Java V2,
 * its better practice to use the
 * Enhanced Client. See the EnhancedPutItem example.
 */
public class PutItem {
    public static void main(String[] args) {
        final String usage = """

                Usage:
                    <tableName> <key> <keyVal> <albumtitle> <albumtitleval> <awards> <awardsval> <Songtitle> <songtitleval>

                Where:
                    tableName - The Amazon DynamoDB table in which an item is placed (for example, Music3).
                    key - The key used in the Amazon DynamoDB table (for example, Artist).
                    keyval - The key value that represents the item to get (for example, Famous Band).
                    albumTitle - The Album title (for example, AlbumTitle).
                    AlbumTitleValue - The name of the album (for example, Songs About Life ).
                    Awards - The awards column (for example, Awards).
                    AwardVal - The value of the awards (for example, 10).
                    SongTitle - The song title (for example, SongTitle).
                    SongTitleVal - The value of the song title (for example, Happy Day).
                **Warning** This program will  place an item that you specify into a table!
                """;

        if (args.length != 9) {
            System.out.println(usage);
            System.exit(1);
        }

        String tableName = args[0];
        String key = args[1];
        String keyVal = args[2];
        String albumTitle = args[3];
        String albumTitleValue = args[4];
        String awards = args[5];
        String awardVal = args[6];
        String songTitle = args[7];
        String songTitleVal = args[8];

        Region region = Region.US_EAST_1;
        DynamoDbClient ddb = DynamoDbClient.builder()
                .region(region)
                .build();

        putItemInTable(ddb, tableName, key, keyVal, albumTitle, albumTitleValue, awards, awardVal, songTitle,
                songTitleVal);
        System.out.println("Done!");
        ddb.close();
    }

    public static void putItemInTable(DynamoDbClient ddb,
            String tableName,
            String key,
            String keyVal,
            String albumTitle,
            String albumTitleValue,
            String awards,
            String awardVal,
            String songTitle,
            String songTitleVal) {

        HashMap<String, AttributeValue> itemValues = new HashMap<>();
        itemValues.put(key, AttributeValue.builder().s(keyVal).build());
        itemValues.put(songTitle, AttributeValue.builder().s(songTitleVal).build());
        itemValues.put(albumTitle, AttributeValue.builder().s(albumTitleValue).build());
        itemValues.put(awards, AttributeValue.builder().s(awardVal).build());

        PutItemRequest request = PutItemRequest.builder()
                .tableName(tableName)
                .item(itemValues)
                .build();

        try {
            PutItemResponse response = ddb.putItem(request);
            System.out.println(tableName + " was successfully updated. The request id is "
                    + response.responseMetadata().requestId());

        } catch (ResourceNotFoundException e) {
            System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName);
            System.err.println("Be sure that it exists and that you've typed its name correctly!");
            System.exit(1);
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
}
```

------
#### [ Java v1 ]

以下のステップに従ってください。

1. `DynamoDB` クラスのインスタンスを作成します。

1. 操作対象のテーブルを表すために、`Table` クラスのインスタンスを作成します。

1. 新しい項目を表す `Item` クラスのインスタンスを作成します。新しい項目のプライマリキーと属性を指定する必要があります。

1. 前の手順で作成した `putItem` を使用して、`Table` オブジェクトの `Item` メソッドを呼び出します。

以下の Java コード例は、前述のタスクの例です。このコードでは、`ProductCatalog` テーブルに新しい項目を書き込みます。

**Example**  

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

// Build a list of related items
List<Number> relatedItems = new ArrayList<Number>();
relatedItems.add(341);
relatedItems.add(472);
relatedItems.add(649);

//Build a map of product pictures
Map<String, String> pictures = new HashMap<String, String>();
pictures.put("FrontView", "http://example.com/products/123_front.jpg");
pictures.put("RearView", "http://example.com/products/123_rear.jpg");
pictures.put("SideView", "http://example.com/products/123_left_side.jpg");

//Build a map of product reviews
Map<String, List<String>> reviews = new HashMap<String, List<String>>();

List<String> fiveStarReviews = new ArrayList<String>();
fiveStarReviews.add("Excellent! Can't recommend it highly enough!  Buy it!");
fiveStarReviews.add("Do yourself a favor and buy this");
reviews.put("FiveStar", fiveStarReviews);

List<String> oneStarReviews = new ArrayList<String>();
oneStarReviews.add("Terrible product!  Do not buy this.");
reviews.put("OneStar", oneStarReviews);

// Build the item
Item item = new Item()
    .withPrimaryKey("Id", 123)
    .withString("Title", "Bicycle 123")
    .withString("Description", "123 description")
    .withString("BicycleType", "Hybrid")
    .withString("Brand", "Brand-Company C")
    .withNumber("Price", 500)
    .withStringSet("Color",  new HashSet<String>(Arrays.asList("Red", "Black")))
    .withString("ProductCategory", "Bicycle")
    .withBoolean("InStock", true)
    .withNull("QuantityOnHand")
    .withList("RelatedItems", relatedItems)
    .withMap("Pictures", pictures)
    .withMap("Reviews", reviews);

// Write the item to the table
PutItemOutcome outcome = table.putItem(item);
```

前の例では、項目にはスカラー (`String`、`Number`、`Boolean`、`Null`)、セット (`String Set`)、ドキュメントタイプ (`List`、`Map`) があります。

------

### オプションパラメータの指定
<a name="PutItemJavaDocumentAPIOptions"></a>

必須のパラメータに加え、`putItem` メソッドにはオプションパラメータも指定できます。たとえば、以下の Java コード例では、オプションパラメータを使用して、項目のアップロード条件を指定します。指定した条件を満たさない場合は、AWS SDK for Java が `ConditionalCheckFailedException` をスローします。このコード例では、`putItem` メソッドに以下のオプションパラメータを指定します。
+ リクエストの条件を定義する `ConditionExpression`。このコードでは、特定の値に等しい ISBN 属性が既存の項目にある場合にのみ同じプライマリキーを持つ既存の項目を置き換えるという条件を定義します。
+ 条件で使用される `ExpressionAttributeValues` のマップ。この場合、必要な置き換えは 1 つだけです。条件式のプレースホルダー `:val` が、実行時に、チェックする実際の ISBN 値に置き換えられます。

以下の例では、これらのオプションパラメータを使用して新しい書籍項目を追加します。

**Example**  

```
Item item = new Item()
    .withPrimaryKey("Id", 104)
    .withString("Title", "Book 104 Title")
    .withString("ISBN", "444-4444444444")
    .withNumber("Price", 20)
    .withStringSet("Authors",
        new HashSet<String>(Arrays.asList("Author1", "Author2")));

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val", "444-4444444444");

PutItemOutcome outcome = table.putItem(
    item,
    "ISBN = :val", // ConditionExpression parameter
    null,          // ExpressionAttributeNames parameter - we're not using it for this example
    expressionAttributeValues);
```

### PutItem および JSON ドキュメント
<a name="PutItemJavaDocumentAPI.JSON"></a>

JSON ドキュメントは、DynamoDB テーブルに属性として格納できます。これを行うには、`withJSON` 項目の `Item` メソッドを使用します。このメソッドは、JSON ドキュメントを解析し、各要素を DynamoDB のネイティブデータ型にマッピングします。

特定の製品の注文を処理できるベンダーを含む、次の JSON ドキュメントを格納するとします。

**Example**  

```
{
    "V01": {
        "Name": "Acme Books",
        "Offices": [ "Seattle" ]
    },
    "V02": {
        "Name": "New Publishers, Inc.",
        "Offices": ["London", "New York"
        ]
    },
    "V03": {
        "Name": "Better Buy Books",
        "Offices": [ "Tokyo", "Los Angeles", "Sydney"
        ]
    }
}
```

`withJSON` メソッドを使用して、`ProductCatalog` という名前の `Map` 属性でこれを `VendorInfo` テーブルに格納することができます。次の Java コード例はそれを行う方法を示しています。

```
// Convert the document into a String.  Must escape all double-quotes.
String vendorDocument = "{"
    + "    \"V01\": {"
    + "        \"Name\": \"Acme Books\","
    + "        \"Offices\": [ \"Seattle\" ]"
    + "    },"
    + "    \"V02\": {"
    + "        \"Name\": \"New Publishers, Inc.\","
    + "        \"Offices\": [ \"London\", \"New York\"" + "]" + "},"
    + "    \"V03\": {"
    + "        \"Name\": \"Better Buy Books\","
    +          "\"Offices\": [ \"Tokyo\", \"Los Angeles\", \"Sydney\""
    + "            ]"
    + "        }"
    + "    }";

Item item = new Item()
    .withPrimaryKey("Id", 210)
    .withString("Title", "Book 210 Title")
    .withString("ISBN", "210-2102102102")
    .withNumber("Price", 30)
    .withJSON("VendorInfo", vendorDocument);

PutItemOutcome outcome = table.putItem(item);
```

## 項目の取得
<a name="JavaDocumentAPIGetItem"></a>

単一の項目を取り出すには、`getItem` オブジェクトの `Table` メソッドを使用します。以下のステップに従ってください。

1. `DynamoDB` クラスのインスタンスを作成します。

1. 操作対象のテーブルを表すために、`Table` クラスのインスタンスを作成します。

1. `getItem` インスタンスの `Table` メソッドを呼び出します。取り出す項目のプライマリキーを指定する必要があります。

以下の Java コード例は、前述のステップの例です。このコードでは、指定したパーティションキーを持つ項目を取得します。

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

Item item = table.getItem("Id", 210);
```

### オプションパラメータの指定
<a name="GetItemJavaDocumentAPIOptions"></a>

必須のパラメータに加え、`getItem` メソッドにはオプションパラメータも指定できます。たとえば、以下の Java コード例では、オプションメソッドを使用して、特定の属性リストのみを取り出します。また、強い整合性のある戻り値をリクエストします。読み込み整合性の詳細については、「[DynamoDB の読み取り整合性](HowItWorks.ReadConsistency.md)」を参照してください。

`ProjectionExpression` を使用すると、項目全体ではなく特定の属性または要素のみを取り出すことができます。`ProjectionExpression` は、ドキュメントのパスを使用して最上位の属性または入れ子になった属性を指定できます。詳細については、「」を参照してください[DynamoDB でのプロジェクション式の使用](Expressions.ProjectionExpressions.md)

`getItem` メソッドのパラメータでは、読み取りの一貫性を指定できません。ただし、`GetItemSpec` を作成して、低レベル `GetItem` オペレーションへの入力のすべてに対するフルアクセスを提供できます。以下のコード例では、`GetItemSpec` を作成し、その仕様を `getItem` メソッドへの入力として使用します。

**Example**  

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 206)
    .withProjectionExpression("Id, Title, RelatedItems[0], Reviews.FiveStar")
    .withConsistentRead(true);

Item item = table.getItem(spec);

System.out.println(item.toJSONPretty());
```

 `Item` を人間が読める形式で出力するには、`toJSONPretty` メソッドを使用します。前のサンプルからの出力は、次のようになります。

```
{
  "RelatedItems" : [ 341 ],
  "Reviews" : {
    "FiveStar" : [ "Excellent! Can't recommend it highly enough! Buy it!", "Do yourself a favor and buy this" ]
  },
  "Id" : 123,
  "Title" : "20-Bicycle 123"
}
```

### GetItem および JSON ドキュメント
<a name="GetItemJavaDocumentAPI.JSON"></a>

[PutItem および JSON ドキュメント](#PutItemJavaDocumentAPI.JSON) セクションでは、`Map` という名前の `VendorInfo` 属性に JSON ドキュメントを格納します。`getItem` メソッドを使用して、ドキュメント全体を JSON 形式で取得できます。または、ドキュメントパスの表記を使用して、ドキュメントの一部の要素のみを取得することもできます。次の Java コード例は、この手法を示しています。

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 210);

System.out.println("All vendor info:");
spec.withProjectionExpression("VendorInfo");
System.out.println(table.getItem(spec).toJSON());

System.out.println("A single vendor:");
spec.withProjectionExpression("VendorInfo.V03");
System.out.println(table.getItem(spec).toJSON());

System.out.println("First office location for this vendor:");
spec.withProjectionExpression("VendorInfo.V03.Offices[0]");
System.out.println(table.getItem(spec).toJSON());
```

前のサンプルからの出力は、次のようになります。

```
All vendor info:
{"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]},"V02":{"Name":"New Publishers, Inc.","Offices":["London","New York"]},"V01":{"Name":"Acme Books","Offices":["Seattle"]}}}
A single vendor:
{"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]}}}
First office location for a single vendor:
{"VendorInfo":{"V03":{"Offices":["Tokyo"]}}}
```

**注記**  
`toJSON` メソッドを使用して、任意の項目（またはその属性）を JSON 形式文字列に変換できます。次のコード例は、最上位の属性と入れ子になった属性を複数取り出し、JSON として結果を出力します。  

```
GetItemSpec spec = new GetItemSpec()
    .withPrimaryKey("Id", 210)
    .withProjectionExpression("VendorInfo.V01, Title, Price");

Item item = table.getItem(spec);
System.out.println(item.toJSON());
```
出力は次のようになります。  

```
{"VendorInfo":{"V01":{"Name":"Acme Books","Offices":["Seattle"]}},"Price":30,"Title":"Book 210 Title"}
```

## バッチ書き込み: 複数の項目の置換および削除
<a name="BatchWriteDocumentAPIJava"></a>

*バッチ書き込み*は、複数の項目の書き込みと削除をバッチで行うことを意味します。`batchWriteItem` メソッドによって、単一の コール内にある 1 つまたは複数のテーブルから複数の項目を置換および削除できます。以下に、AWS SDK for Java ドキュメント API を使用して複数の項目を入力および削除する手順を示します。

1. `DynamoDB` クラスのインスタンスを作成します。

1. テーブルのすべての入力および削除オペレーションを記述する `TableWriteItems` クラスのインスタンスを作成します。1 つのバッチ書き込みオペレーションで複数のテーブルに書き込む場合、テーブルごとに `TableWriteItems` インスタンスを 1 つずつ作成する必要があります。

1. 前の手順で作成した `batchWriteItem` オブジェクトを指定して、`TableWriteItems` メソッドを呼び出します。

1. 応答を処理します。返された未処理のリクエスト項目が応答内に存在していたかどうかをチェックする必要があります。これは、プロビジョニングされたスループットクォータまたは他の何らかの一時的エラーに達する場合に、発生する可能性があります。また、DynamoDB によって、リクエストのサイズ、およびリクエスト内で指定できるオペレーションの数が制限されます。これらの制限を超えると、DynamoDB によってリクエストが却下されます。詳細については、「[Amazon DynamoDB のクォータ](ServiceQuotas.md)」を参照してください。

以下の Java コード例は、前述のステップの例です。この例では、2 つのテーブル (`batchWriteItem` と `Forum`) で `Thread` オペレーションを実行します。対応する `TableWriteItems` オブジェクトは、次のアクションを定義します。
+ `Forum` テーブル内で項目を配置します。
+ `Thread` テーブル内で項目を入力および削除します。

その後、コードは `batchWriteItem` を呼び出してオペレーションを実行します。

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

TableWriteItems forumTableWriteItems = new TableWriteItems("Forum")
    .withItemsToPut(
        new Item()
            .withPrimaryKey("Name", "Amazon RDS")
            .withNumber("Threads", 0));

TableWriteItems threadTableWriteItems = new TableWriteItems("Thread")
    .withItemsToPut(
        new Item()
            .withPrimaryKey("ForumName","Amazon RDS","Subject","Amazon RDS Thread 1")
    .withHashAndRangeKeysToDelete("ForumName","Some partition key value", "Amazon S3", "Some sort key value");

BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems);

// Code for checking unprocessed items is omitted in this example
```

実例については、「[例: AWS SDK for Java ドキュメント API を使用したバッチ書き込みオペレーション](batch-operation-document-api-java.md#JavaDocumentAPIBatchWrite)」を参照してください。

## バッチ取得: 複数の項目の取得
<a name="JavaDocumentAPIBatchGetItem"></a>

`batchGetItem` メソッドによって、1 つまたは複数のテーブルから複数の項目を取得できます。単一の項目を取り出すために、`getItem` メソッドを使用できます。

以下のステップに従ってください。

1. `DynamoDB` クラスのインスタンスを作成します。

1. テーブルから取り出すプライマリキーのリストを記述する `TableKeysAndAttributes` クラスのインスタンスを作成します。1 つのバッチ取得オペレーションで複数のテーブルから読み込む場合、テーブルごとに `TableKeysAndAttributes` インスタンスを 1 つずつ作成する必要があります。

1. 前の手順で作成した `batchGetItem` オブジェクトを指定して、`TableKeysAndAttributes` メソッドを呼び出します。

以下の Java コード例は、前述のステップの例です。この例では、`Forum` テーブル内の 2 つの項目、および `Thread` テーブル内の 3 つの項目を取り出します。

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

    TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName);
    forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name",
    "Amazon S3",
    "Amazon DynamoDB");

TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName);
threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject",
    "Amazon DynamoDB","DynamoDB Thread 1",
    "Amazon DynamoDB","DynamoDB Thread 2",
    "Amazon S3","S3 Thread 1");

BatchGetItemOutcome outcome = dynamoDB.batchGetItem(
    forumTableKeysAndAttributes, threadTableKeysAndAttributes);

for (String tableName : outcome.getTableItems().keySet()) {
    System.out.println("Items in table " + tableName);
    List<Item> items = outcome.getTableItems().get(tableName);
    for (Item item : items) {
        System.out.println(item);
    }
}
```

### オプションパラメータの指定
<a name="BatchGetItemJavaDocumentAPIOptions"></a>

必須のパラメータに加え、`batchGetItem` を使用する場合はオプションパラメータも指定できます。たとえば、定義した `ProjectionExpression` ごとに `TableKeysAndAttributes` を指定できます。これにより、テーブルから取り出す属性を指定することができます。

次のサンプルコードでは、`Forum` から 2 つの項目を取得します。`withProjectionExpression` パラメータは、`Threads` 属性のみを取得することを指定します。

**Example**  

```
TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes("Forum")
    .withProjectionExpression("Threads");

forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name",
    "Amazon S3",
    "Amazon DynamoDB");

BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes);
```

## 項目の更新
<a name="JavaDocumentAPIItemUpdate"></a>

`updateItem` オブジェクトの `Table` メソッドは、既存の属性値の更新、新しい属性の追加、または既存の項目からの属性の削除を実行できます。

`updateItem` メソッドは、以下のように動作します。
+ 項目が存在しない (指定されたプライマリキーを持つ項目がテーブル内にない) 場合、`updateItem` はテーブルに新しい項目を追加します
+ 項目が存在する場合、`updateItem` は `UpdateExpression` パラメータで指定されたとおりに更新を実行します。

**注記**  
`putItem` を使用して項目を「更新」することもできます。たとえば、`putItem` を呼び出して項目をテーブルに追加したが、指定されたプライマリキーを持つ項目がすでに存在する場合、`putItem` は項目全体を置き換えます。入力で指定されていない属性が既存の項目内にある場合、`putItem` は項目からそれらの属性を削除します。  
一般に、項目属性を変更するときは必ず `updateItem` を使用することをお勧めします。`updateItem` メソッドは、入力で指定した項目属性のみを変更し、項目内の他の属性は変更されません。

以下のステップに従ってください。

1. 操作対象のテーブルを表すために、`Table` クラスのインスタンスを作成します。

1. `updateTable` インスタンスの `Table` メソッドを呼び出します。変更する属性とその変更方法を記述する `UpdateExpression` と同時に、取り出す項目のプライマリーキーを指定する必要があります。

以下の Java コード例は、前述のタスクの例です。このコードでは、`ProductCatalog` テーブルの書籍項目を更新します。この例では、`Authors` のセットに著者を追加し、既存の `ISBN` 属性を削除します。また、価格を 1 引き下げます。

`ExpressionAttributeValues` マップは `UpdateExpression` で使用されます。プレースホルダー `:val1` および `:val2` は、実行時に、`Authors` と `Price` の実際の値に置き換えられます。

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

Map<String, String> expressionAttributeNames = new HashMap<String, String>();
expressionAttributeNames.put("#A", "Authors");
expressionAttributeNames.put("#P", "Price");
expressionAttributeNames.put("#I", "ISBN");

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val1",
    new HashSet<String>(Arrays.asList("Author YY","Author ZZ")));
expressionAttributeValues.put(":val2", 1);   //Price

UpdateItemOutcome outcome =  table.updateItem(
    "Id",          // key attribute name
    101,           // key attribute value
    "add #A :val1 set #P = #P - :val2 remove #I", // UpdateExpression
    expressionAttributeNames,
    expressionAttributeValues);
```

### オプションパラメータの指定
<a name="UpdateItemJavaDocumentAPIOptions"></a>

必須のパラメータに加えて、更新を実行するために満たす必要がある条件も含めて、`updateItem` メソッドのオプションパラメータを指定することもできます。指定した条件を満たさない場合は、AWS SDK for Java が `ConditionalCheckFailedException` をスローします。たとえば、以下の Java コード例では、書籍項目の価格を条件付きで 25 に更新します。現在の価格が 20 である場合にのみ価格を更新する必要があることを示す `ConditionExpression` を指定します。

**Example**  

```
Table table = dynamoDB.getTable("ProductCatalog");

Map<String, String> expressionAttributeNames = new HashMap<String, String>();
expressionAttributeNames.put("#P", "Price");

Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":val1", 25);  // update Price to 25...
expressionAttributeValues.put(":val2", 20);  //...but only if existing Price is 20

UpdateItemOutcome outcome = table.updateItem(
    new PrimaryKey("Id",101),
    "set #P = :val1", // UpdateExpression
    "#P = :val2",     // ConditionExpression
    expressionAttributeNames,
    expressionAttributeValues);
```

### アトミックカウンタ
<a name="AtomicCounterJavaDocumentAPI"></a>

`updateItem` を使用してアトミックカウンターを実装できます。アトミックカウンターでは、他の書き込みリクエストを妨げることなく、既存の属性の値をインクリメントまたはデクリメントします。アトミックカウンターをインクリメントするには、`UpdateExpression` を使用して、`set` アクションで既存の `Number` 型の属性に数値を加算します。

次のサンプルはこのアトミックカウンターを示しており、`Quantity` 属性を 1 ずつインクリメントさせています。さらに、`ExpressionAttributeNames` での `UpdateExpression` パラメータの使用方法も示します。

```
Table table = dynamoDB.getTable("ProductCatalog");

Map<String,String> expressionAttributeNames = new HashMap<String,String>();
expressionAttributeNames.put("#p", "PageCount");

Map<String,Object> expressionAttributeValues = new HashMap<String,Object>();
expressionAttributeValues.put(":val", 1);

UpdateItemOutcome outcome = table.updateItem(
    "Id", 121,
    "set #p = #p + :val",
    expressionAttributeNames,
    expressionAttributeValues);
```

## 項目の削除
<a name="DeleteMidLevelJava"></a>

`deleteItem` メソッドによって、テーブルから項目を削除します。削除する項目のプライマリキーを入力する必要があります。

以下のステップに従ってください。

1. `DynamoDB` クライアントのインスタンスを作成します。

1. 削除する項目のキーを指定して、`deleteItem` メソッドを呼び出します。

次の Java サンプルは、このタスクを示しています。

**Example**  

```
AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamoDB = new DynamoDB(client);

Table table = dynamoDB.getTable("ProductCatalog");

DeleteItemOutcome outcome = table.deleteItem("Id", 101);
```

### オプションパラメータの指定
<a name="DeleteItemJavaDocumentAPIOptions"></a>

`deleteItem` のオプションパラメータを指定できます。たとえば、次の Java コード例は、`ConditionExpression` 内の書籍項目は書籍が絶版になった (`ProductCatalog` 属性が false) 場合のみ削除可能であることを示す `InPublication` を指定します。

**Example**  

```
Map<String,Object> expressionAttributeValues = new HashMap<String,Object>();
expressionAttributeValues.put(":val", false);

DeleteItemOutcome outcome = table.deleteItem("Id",103,
    "InPublication = :val",
    null, // ExpressionAttributeNames - not used in this example
    expressionAttributeValues);
```

# 例: AWS SDK for Java ドキュメント API を使用した CRUD オペレーション
<a name="JavaDocumentAPICRUDExample"></a>

以下のコード例は、Amazon DynamoDB 項目に対する CRUD オペレーションの例です。この例では、項目の作成、項目の取得、さまざまな更新の実行、さらに項目の削除を行います。

**注記**  
SDK for Java には、オブジェクト永続性モデルも用意されています。このモデルにより、クライアント側のクラスを DynamoDB テーブルにマッピングできます。この方法により、記述する必要のあるコードの量を減らすことができます。詳細については、「[Java 1.x: DynamoDBMapper](DynamoDBMapper.md)」を参照してください。

**注記**  
このコード例では、アカウントの DynamoDB に対し、[DynamoDB でのコード例用のテーブルの作成とデータのロード](SampleData.md) セクションの手順に従ってデータが既にロードされていることを前提としています。  
以下の例を実行するための詳しい手順については、「[Java コードの例](CodeSamples.Java.md)」を参照してください。

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DeleteItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.UpdateItemOutcome;
import com.amazonaws.services.dynamodbv2.document.spec.DeleteItemSpec;
import com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec;
import com.amazonaws.services.dynamodbv2.document.utils.NameMap;
import com.amazonaws.services.dynamodbv2.document.utils.ValueMap;
import com.amazonaws.services.dynamodbv2.model.ReturnValue;

public class DocumentAPIItemCRUDExample {

    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String tableName = "ProductCatalog";

    public static void main(String[] args) throws IOException {

        createItems();

        retrieveItem();

        // Perform various updates.
        updateMultipleAttributes();
        updateAddNewAttribute();
        updateExistingAttributeConditionally();

        // Delete the item.
        deleteItem();

    }

    private static void createItems() {

        Table table = dynamoDB.getTable(tableName);
        try {

            Item item = new Item().withPrimaryKey("Id", 120).withString("Title", "Book 120 Title")
                    .withString("ISBN", "120-1111111111")
                    .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author12", "Author22")))
                    .withNumber("Price", 20).withString("Dimensions", "8.5x11.0x.75").withNumber("PageCount", 500)
                    .withBoolean("InPublication", false).withString("ProductCategory", "Book");
            table.putItem(item);

            item = new Item().withPrimaryKey("Id", 121).withString("Title", "Book 121 Title")
                    .withString("ISBN", "121-1111111111")
                    .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author21", "Author 22")))
                    .withNumber("Price", 20).withString("Dimensions", "8.5x11.0x.75").withNumber("PageCount", 500)
                    .withBoolean("InPublication", true).withString("ProductCategory", "Book");
            table.putItem(item);

        } catch (Exception e) {
            System.err.println("Create items failed.");
            System.err.println(e.getMessage());

        }
    }

    private static void retrieveItem() {
        Table table = dynamoDB.getTable(tableName);

        try {

            Item item = table.getItem("Id", 120, "Id, ISBN, Title, Authors", null);

            System.out.println("Printing item after retrieving it....");
            System.out.println(item.toJSONPretty());

        } catch (Exception e) {
            System.err.println("GetItem failed.");
            System.err.println(e.getMessage());
        }

    }

    private static void updateAddNewAttribute() {
        Table table = dynamoDB.getTable(tableName);

        try {

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 121)
                    .withUpdateExpression("set #na = :val1").withNameMap(new NameMap().with("#na", "NewAttribute"))
                    .withValueMap(new ValueMap().withString(":val1", "Some value"))
                    .withReturnValues(ReturnValue.ALL_NEW);

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after adding new attribute...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Failed to add new attribute in " + tableName);
            System.err.println(e.getMessage());
        }
    }

    private static void updateMultipleAttributes() {

        Table table = dynamoDB.getTable(tableName);

        try {

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 120)
                    .withUpdateExpression("add #a :val1 set #na=:val2")
                    .withNameMap(new NameMap().with("#a", "Authors").with("#na", "NewAttribute"))
                    .withValueMap(
                            new ValueMap().withStringSet(":val1", "Author YY", "Author ZZ").withString(":val2",
                                    "someValue"))
                    .withReturnValues(ReturnValue.ALL_NEW);

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after multiple attribute update...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Failed to update multiple attributes in " + tableName);
            System.err.println(e.getMessage());

        }
    }

    private static void updateExistingAttributeConditionally() {

        Table table = dynamoDB.getTable(tableName);

        try {

            // Specify the desired price (25.00) and also the condition (price =
            // 20.00)

            UpdateItemSpec updateItemSpec = new UpdateItemSpec().withPrimaryKey("Id", 120)
                    .withReturnValues(ReturnValue.ALL_NEW).withUpdateExpression("set #p = :val1")
                    .withConditionExpression("#p = :val2").withNameMap(new NameMap().with("#p", "Price"))
                    .withValueMap(new ValueMap().withNumber(":val1", 25).withNumber(":val2", 20));

            UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

            // Check the response.
            System.out.println("Printing item after conditional update to new attribute...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Error updating item in " + tableName);
            System.err.println(e.getMessage());
        }
    }

    private static void deleteItem() {

        Table table = dynamoDB.getTable(tableName);

        try {

            DeleteItemSpec deleteItemSpec = new DeleteItemSpec().withPrimaryKey("Id", 120)
                    .withConditionExpression("#ip = :val").withNameMap(new NameMap().with("#ip", "InPublication"))
                    .withValueMap(new ValueMap().withBoolean(":val", false)).withReturnValues(ReturnValue.ALL_OLD);

            DeleteItemOutcome outcome = table.deleteItem(deleteItemSpec);

            // Check the response.
            System.out.println("Printing item that was deleted...");
            System.out.println(outcome.getItem().toJSONPretty());

        } catch (Exception e) {
            System.err.println("Error deleting item in " + tableName);
            System.err.println(e.getMessage());
        }
    }
}
```

# 例: AWS SDK for Java ドキュメント API を使用したバッチオペレーション
<a name="batch-operation-document-api-java"></a>

このセクションでは、AWS SDK for Java ドキュメント API を使用した Amazon DynamoDB でのバッチ書き込みおよびバッチ取得オペレーションの例を示します。

**注記**  
SDK for Java には、オブジェクト永続性モデルも用意されています。このモデルにより、クライアント側のクラスを DynamoDB テーブルにマッピングできます。この方法により、記述する必要のあるコードの量を減らすことができます。詳細については、「」を参照してください[Java 1.x: DynamoDBMapper](DynamoDBMapper.md)

**Topics**
+ [例: AWS SDK for Java ドキュメント API を使用したバッチ書き込みオペレーション](#JavaDocumentAPIBatchWrite)
+ [例: AWS SDK for Java ドキュメント API を使用したバッチ取得オペレーション](#JavaDocumentAPIBatchGet)

## 例: AWS SDK for Java ドキュメント API を使用したバッチ書き込みオペレーション
<a name="JavaDocumentAPIBatchWrite"></a>

以下の Java コード例では、`batchWriteItem` メソッドを使用して、以下の置換および削除のオペレーションを実行します。
+ `Forum` テーブル内で 1 つの項目を配置します。
+ `Thread` テーブルに対して 1 つの項目を配置および削除します。

バッチの書き込みリクエストを作成すると、1 つまたは複数のテーブルに対して多数の置換リクエストと削除リクエストを指定できます。ただし、`batchWriteItem` では、1 回のバッチ書き込みオペレーションで可能なバッチ書き込みリクエストのサイズ、置換および削除のオペレーションの数を制限しています。これらの制限を超えるリクエストは却下されます。プロビジョニングされたスループットがテーブルに不足しているためにこのリクエストを処理できない場合は、応答時に未処理のリクエスト項目が返されます。

以下の例では、未処理のリクエスト項目がないか、応答を確認します。未処理のリクエスト項目がある場合は、`batchWriteItem` リクエストをループバックして再送信します。このガイドの例に従っていれば、`Forum` テーブルおよび `Thread` テーブルは作成済みです。プログラムで、これらのテーブルを作成し、サンプルデータをアップロードすることもできます。詳細については、「」を参照してください[AWS SDK for Java を使用してサンプルテーブルを作成してデータをアップロードする](AppendixSampleDataCodeJava.md)

以下の例をテストするための詳細な手順については、「[Java コードの例](CodeSamples.Java.md)」を参照してください。

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.BatchWriteItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.TableWriteItems;
import com.amazonaws.services.dynamodbv2.model.WriteRequest;

public class DocumentAPIBatchWrite {

    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String forumTableName = "Forum";
    static String threadTableName = "Thread";

    public static void main(String[] args) throws IOException {

        writeMultipleItemsBatchWrite();

    }

    private static void writeMultipleItemsBatchWrite() {
        try {

            // Add a new item to Forum
            TableWriteItems forumTableWriteItems = new TableWriteItems(forumTableName) // Forum
                    .withItemsToPut(new Item().withPrimaryKey("Name", "Amazon RDS").withNumber("Threads", 0));

            // Add a new item, and delete an existing item, from Thread
            // This table has a partition key and range key, so need to specify
            // both of them
            TableWriteItems threadTableWriteItems = new TableWriteItems(threadTableName)
                    .withItemsToPut(
                            new Item().withPrimaryKey("ForumName", "Amazon RDS", "Subject", "Amazon RDS Thread 1")
                                    .withString("Message", "ElastiCache Thread 1 message")
                                    .withStringSet("Tags", new HashSet<String>(Arrays.asList("cache", "in-memory"))))
                    .withHashAndRangeKeysToDelete("ForumName", "Subject", "Amazon S3", "S3 Thread 100");

            System.out.println("Making the request.");
            BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems);

            do {

                // Check for unprocessed keys which could happen if you exceed
                // provisioned throughput

                Map<String, List<WriteRequest>> unprocessedItems = outcome.getUnprocessedItems();

                if (outcome.getUnprocessedItems().size() == 0) {
                    System.out.println("No unprocessed items found");
                } else {
                    System.out.println("Retrieving the unprocessed items");
                    outcome = dynamoDB.batchWriteItemUnprocessed(unprocessedItems);
                }

            } while (outcome.getUnprocessedItems().size() > 0);

        } catch (Exception e) {
            System.err.println("Failed to retrieve items: ");
            e.printStackTrace(System.err);
        }

    }

}
```

## 例: AWS SDK for Java ドキュメント API を使用したバッチ取得オペレーション
<a name="JavaDocumentAPIBatchGet"></a>

以下の Java コード例では、`batchGetItem` メソッドを使用して、`Forum` テーブルおよび `Thread` テーブルから複数の項目を取り出します。`BatchGetItemRequest` は、取得する各項目のテーブル名とキーのリストを指定します。この例では、取得した項目を印刷して応答を処理します。

**注記**  
このコード例では、アカウントの DynamoDB に対し、[DynamoDB でのコード例用のテーブルの作成とデータのロード](SampleData.md) セクションの手順に従ってデータが既にロードされていることを前提としています。  
以下の例を実行するための詳しい手順については、「[Java コードの例](CodeSamples.Java.md)」を参照してください。

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.BatchGetItemOutcome;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.TableKeysAndAttributes;
import com.amazonaws.services.dynamodbv2.model.KeysAndAttributes;

public class DocumentAPIBatchGet {
    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String forumTableName = "Forum";
    static String threadTableName = "Thread";

    public static void main(String[] args) throws IOException {
        retrieveMultipleItemsBatchGet();
    }

    private static void retrieveMultipleItemsBatchGet() {

        try {

            TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName);
            // Add a partition key
            forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB");

            TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName);
            // Add a partition key and a sort key
            threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject", "Amazon DynamoDB",
                    "DynamoDB Thread 1", "Amazon DynamoDB", "DynamoDB Thread 2", "Amazon S3", "S3 Thread 1");

            System.out.println("Making the request.");

            BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes,
                    threadTableKeysAndAttributes);

            Map<String, KeysAndAttributes> unprocessed = null;

            do {
                for (String tableName : outcome.getTableItems().keySet()) {
                    System.out.println("Items in table " + tableName);
                    List<Item> items = outcome.getTableItems().get(tableName);
                    for (Item item : items) {
                        System.out.println(item.toJSONPretty());
                    }
                }

                // Check for unprocessed keys which could happen if you exceed
                // provisioned
                // throughput or reach the limit on response size.
                unprocessed = outcome.getUnprocessedKeys();

                if (unprocessed.isEmpty()) {
                    System.out.println("No unprocessed keys found");
                } else {
                    System.out.println("Retrieving the unprocessed keys");
                    outcome = dynamoDB.batchGetItemUnprocessed(unprocessed);
                }

            } while (!unprocessed.isEmpty());

        } catch (Exception e) {
            System.err.println("Failed to retrieve items.");
            System.err.println(e.getMessage());
        }

    }

}
```

# 例: AWS SDK for Java ドキュメント API を使用したバイナリタイプ属性の処理
<a name="JavaDocumentAPIBinaryTypeExample"></a>

以下の Java コード例は、バイナリタイプ属性の処理の例です。この例では、`Reply` テーブルに項目を追加します。この項目には、圧縮データを格納するバイナリタイプ属性（`ExtendedMessage`）などがあります。また、この例では、項目を取得し、すべての属性値を印刷します。説明のため、この例では `GZIPOutputStream` クラスを使用して、サンプルストリームを圧縮し、圧縮したデータを `ExtendedMessage` 属性に割り当てます。バイナリ属性が取得されると、`GZIPInputStream` クラスを使用して展開されます。

**注記**  
SDK for Java には、オブジェクト永続性モデルも用意されています。このモデルにより、クライアント側のクラスを DynamoDB テーブルにマッピングできます。この方法により、記述する必要のあるコードの量を減らすことができます。詳細については、「」を参照してください[Java 1.x: DynamoDBMapper](DynamoDBMapper.md)

[DynamoDB でのコード例用のテーブルの作成とデータのロード](SampleData.md) セクションの手順に従っていれば、`Reply` テーブルは作成済みです。このテーブルは、プログラムで作成することもできます。詳細については、「」を参照してください[AWS SDK for Java を使用してサンプルテーブルを作成してデータをアップロードする](AppendixSampleDataCodeJava.md)

以下の例をテストするための詳細な手順については、「[Java コードの例](CodeSamples.Java.md)」を参照してください。

**Example**  

```
package com.amazonaws.codesamples.document;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.document.DynamoDB;
import com.amazonaws.services.dynamodbv2.document.Item;
import com.amazonaws.services.dynamodbv2.document.Table;
import com.amazonaws.services.dynamodbv2.document.spec.GetItemSpec;

public class DocumentAPIItemBinaryExample {

    static AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
    static DynamoDB dynamoDB = new DynamoDB(client);

    static String tableName = "Reply";
    static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

    public static void main(String[] args) throws IOException {
        try {

            // Format the primary key values
            String threadId = "Amazon DynamoDB#DynamoDB Thread 2";

            dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
            String replyDateTime = dateFormatter.format(new Date());

            // Add a new reply with a binary attribute type
            createItem(threadId, replyDateTime);

            // Retrieve the reply with a binary attribute type
            retrieveItem(threadId, replyDateTime);

            // clean up by deleting the item
            deleteItem(threadId, replyDateTime);
        } catch (Exception e) {
            System.err.println("Error running the binary attribute type example: " + e);
            e.printStackTrace(System.err);
        }
    }

    public static void createItem(String threadId, String replyDateTime) throws IOException {

        Table table = dynamoDB.getTable(tableName);

        // Craft a long message
        String messageInput = "Long message to be compressed in a lengthy forum reply";

        // Compress the long message
        ByteBuffer compressedMessage = compressString(messageInput.toString());

        table.putItem(new Item().withPrimaryKey("Id", threadId).withString("ReplyDateTime", replyDateTime)
                .withString("Message", "Long message follows").withBinary("ExtendedMessage", compressedMessage)
                .withString("PostedBy", "User A"));
    }

    public static void retrieveItem(String threadId, String replyDateTime) throws IOException {

        Table table = dynamoDB.getTable(tableName);

        GetItemSpec spec = new GetItemSpec().withPrimaryKey("Id", threadId, "ReplyDateTime", replyDateTime)
                .withConsistentRead(true);

        Item item = table.getItem(spec);

        // Uncompress the reply message and print
        String uncompressed = uncompressString(ByteBuffer.wrap(item.getBinary("ExtendedMessage")));

        System.out.println("Reply message:\n" + " Id: " + item.getString("Id") + "\n" + " ReplyDateTime: "
                + item.getString("ReplyDateTime") + "\n" + " PostedBy: " + item.getString("PostedBy") + "\n"
                + " Message: "
                + item.getString("Message") + "\n" + " ExtendedMessage (uncompressed): " + uncompressed + "\n");
    }

    public static void deleteItem(String threadId, String replyDateTime) {

        Table table = dynamoDB.getTable(tableName);
        table.deleteItem("Id", threadId, "ReplyDateTime", replyDateTime);
    }

    private static ByteBuffer compressString(String input) throws IOException {
        // Compress the UTF-8 encoded String into a byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream os = new GZIPOutputStream(baos);
        os.write(input.getBytes("UTF-8"));
        os.close();
        baos.close();
        byte[] compressedBytes = baos.toByteArray();

        // The following code writes the compressed bytes to a ByteBuffer.
        // A simpler way to do this is by simply calling
        // ByteBuffer.wrap(compressedBytes);
        // However, the longer form below shows the importance of resetting the
        // position of the buffer
        // back to the beginning of the buffer if you are writing bytes directly
        // to it, since the SDK
        // will consider only the bytes after the current position when sending
        // data to DynamoDB.
        // Using the "wrap" method automatically resets the position to zero.
        ByteBuffer buffer = ByteBuffer.allocate(compressedBytes.length);
        buffer.put(compressedBytes, 0, compressedBytes.length);
        buffer.position(0); // Important: reset the position of the ByteBuffer
                            // to the beginning
        return buffer;
    }

    private static String uncompressString(ByteBuffer input) throws IOException {
        byte[] bytes = input.array();
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPInputStream is = new GZIPInputStream(bais);

        int chunkSize = 1024;
        byte[] buffer = new byte[chunkSize];
        int length = 0;
        while ((length = is.read(buffer, 0, chunkSize)) != -1) {
            baos.write(buffer, 0, length);
        }

        String result = new String(baos.toByteArray(), "UTF-8");

        is.close();
        baos.close();
        bais.close();

        return result;
    }
}
```

# 項目の操作: .NET
<a name="LowLevelDotNetItemCRUD"></a>

AWS SDK for .NET 低レベル API を使用して、テーブル内の項目に対して、一般的な作成、読み込み、更新、削除 (CRUD) のオペレーションを実行できます。以下に、.NET の低レベル API を使用してデータ CRUD オペレーションを実行するための一般的なステップを示します。

1. `AmazonDynamoDBClient` クラスのインスタンス（クライアント）を作成します。

1. 対応するリクエストオブジェクトで、オペレーション固有の必須パラメータを指定します。

   たとえば、項目をアップロードするときは `PutItemRequest` リクエストオブジェクトを使用し、既存の項目を取得するときは `GetItemRequest` リクエストオブジェクトを使用します。

   リクエストオブジェクトを使用して、必須パラメータとオプションパラメータの両方を指定できます。

1. 前述のステップで作成したリクエストオブジェクトを渡して、クライアントから提供された適切なメソッドを実行します。

   `AmazonDynamoDBClient` クライアントは、CRUD オペレーションに、`PutItem`、`GetItem`、`UpdateItem` および `DeleteItem` メソッドを提供します。

**Topics**
+ [項目の置換](#PutItemLowLevelAPIDotNet)
+ [項目の取得](#GetItemLowLevelDotNET)
+ [項目の更新](#UpdateItemLowLevelDotNet)
+ [アトミックカウンタ](#AtomicCounterLowLevelDotNet)
+ [項目の削除](#DeleteMidLevelDotNet)
+ [バッチ書き込み: 複数の項目の置換および削除](#BatchWriteLowLevelDotNet)
+ [バッチ取得: 複数の項目の取得](#BatchGetLowLevelDotNet)
+ [例: AWS SDK for .NET 低レベル API を使用した CRUD オペレーション](LowLevelDotNetItemsExample.md)
+ [例: AWS SDK for .NET 低レベル API を使用したバッチオペレーション](batch-operation-lowlevel-dotnet.md)
+ [例: AWS SDK for .NET 低レベル API を使用したバイナリタイプ属性の処理](LowLevelDotNetBinaryTypeExample.md)

## 項目の置換
<a name="PutItemLowLevelAPIDotNet"></a>

`PutItem` メソッドは、項目をテーブルにアップロードします。項目が存在する場合、その項目全体が置き換えられます。

**注記**  
項目全体を置き換える代わりに固有の属性のみを更新する場合は、`UpdateItem` メソッドを使用できます。詳細については、「」を参照してください[項目の更新](#UpdateItemLowLevelDotNet)

以下に、低レベル .NET SDK API を使用して項目をアップロードするステップを示します。

1. `AmazonDynamoDBClient` クラスのインスタンスを作成します。

1. `PutItemRequest` クラスのインスタンスを作成して、必要なパラメータを指定します。

   項目を配置するには、テーブル名と項目を指定する必要があります。

1. 前のステップで作成した `PutItemRequest` オブジェクトを指定して、`PutItem` メソッドを実行します。

以下の C\$1 サンプルは、前述のステップの例です。この例では、項目を `ProductCatalog` テーブルにアップロードします。

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new PutItemRequest
{
   TableName = tableName,
   Item = new Dictionary<string, AttributeValue>()
      {
          { "Id", new AttributeValue { N = "201" }},
          { "Title", new AttributeValue { S = "Book 201 Title" }},
          { "ISBN", new AttributeValue { S = "11-11-11-11" }},
          { "Price", new AttributeValue { S = "20.00" }},
          {
            "Authors",
            new AttributeValue
            { SS = new List<string>{"Author1", "Author2"}   }
          }
      }
};
client.PutItem(request);
```

前の例では、`Id`、`Title`、`ISBN` および `Authors` 属性を持つブック項目をアップロードします。`Id` は数値型の属性であり、他のすべての属性は文字列型であることに注意してください。作成者は `String` セットです。

### オプションパラメータの指定
<a name="PutItemLowLevelAPIDotNetOptions"></a>

次の C\$1 例に示すように、`PutItemRequest` オブジェクトを使用してオプションのパラメータを指定することもできます。この例では、次のオプションパラメータが指定されています。
+ `ExpressionAttributeNames`、`ExpressionAttributeValues` および `ConditionExpression` は、既存の項目に特定の値を持つ ISBN 属性がある場合にのみ、項目を置き換えるように指定します。
+ レスポンスで古い項目をリクエストする `ReturnValues` パラメータ。

**Example**  

```
var request = new PutItemRequest
 {
   TableName = tableName,
   Item = new Dictionary<string, AttributeValue>()
               {
                   { "Id", new AttributeValue { N = "104" }},
                   { "Title", new AttributeValue { S = "Book 104  Title" }},
                   { "ISBN", new AttributeValue { S = "444-4444444444" }},
                   { "Authors",
                     new AttributeValue { SS = new List<string>{"Author3"}}}
               },
    // Optional parameters.
    ExpressionAttributeNames = new Dictionary<string,string>()
    {
        {"#I", "ISBN"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":isbn",new AttributeValue {S = "444-4444444444"}}
    },
    ConditionExpression = "#I = :isbn"

};
var response = client.PutItem(request);
```

詳細については、「[PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)」を参照してください。

## 項目の取得
<a name="GetItemLowLevelDotNET"></a>

`GetItem` メソッドは項目を取得します。

**注記**  
複数の項目を取り出すために、`BatchGetItem` メソッドを使用できます。詳細については、「」を参照してください[バッチ取得: 複数の項目の取得](#BatchGetLowLevelDotNet)

以下に、低レベル AWS SDK for .NET API を使用して既存の項目を取得するステップを示します。

1. `AmazonDynamoDBClient` クラスのインスタンスを作成します。

1. `GetItemRequest` クラスのインスタンスを作成して、必要なパラメータを指定します。

   項目を吸いtpィするには、テーブル名と項目のプライマリキーを指定する必要があります。

1. 前のステップで作成した `GetItemRequest` オブジェクトを指定して、`GetItem` メソッドを実行します。

以下の C\$1 サンプルは、前述のステップの例です。例では、`ProductCatalog` テーブルから項目を取得します。

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new GetItemRequest
 {
   TableName = tableName,
   Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } },
 };
 var response = client.GetItem(request);

// Check the response.
var result = response.GetItemResult;
var attributeMap = result.Item; // Attribute list in the response.
```

### オプションパラメータの指定
<a name="GetItemLowLevelDotNETOptions"></a>

次の C\$1 例に示すように、`GetItemRequest` オブジェクトを使用してオプションのパラメータを指定することもできます。このサンプルでは、次のオプションパラメータが指定されています。
+ 取得する属性を指定する `ProjectionExpression` パラメータ。
+ 強力な整合性のある読み込みを実行する `ConsistentRead` パラメータ。読み込み整合性の詳細については、「[DynamoDB の読み取り整合性](HowItWorks.ReadConsistency.md)」を参照してください。

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new GetItemRequest
 {
   TableName = tableName,
   Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } },
   // Optional parameters.
   ProjectionExpression = "Id, ISBN, Title, Authors",
   ConsistentRead = true
 };

 var response = client.GetItem(request);

// Check the response.
var result = response.GetItemResult;
var attributeMap = result.Item;
```

詳細については、「[GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html)」を参照してください。

## 項目の更新
<a name="UpdateItemLowLevelDotNet"></a>

`UpdateItem` メソッドは、既存の項目があればそれを更新します。`UpdateItem` オペレーションを使用して、既存の属性値を更新するか、新しい属性を追加するか、既存のコレクションから属性を削除することができます。プライマリキーが指定されている項目がない場合は、新しい項目が追加されます。

`UpdateItem` オペレーションは、以下のガイドラインに従います。
+ 項目が存在しない場合、`UpdateItem` は入力で指定されたプライマリキーを使用して、新しい項目を追加します。
+ 項目が存在する場合、`UpdateItem` は次のように更新を適用します。
  + 既存の属性値を更新による値に置き換えます。
  + 入力で指定された属性が存在しない場合は、新しい属性を項目に追加します。
  + 入力された属性が null である場合は、属性を削除します。
  + `ADD` に `Action` を使用する場合は、既存のセット (文字列または数値セット) に値を追加するか、既存の数値属性値から数学的に加算 (正の数を使用) または減算 (負の数を使用) することができます。

**注記**  
`PutItem` オペレーションにより、更新を実行できます。詳細については、「」を参照してください[項目の置換](#PutItemLowLevelAPIDotNet) たとえば、`PutItem` をコールして項目をアップロードするときにプライマリキーが存在する場合は、`PutItem` オペレーションによって項目全体が置き換わります。既存の項目内に属性があり、入力でそれらの属性が指定されていない場合、それらの属性は、`PutItem` オペレーションによって削除されます。ただし、`UpdateItem` が更新するのは指定された入力属性だけです。その項目では、その他の既存の属性は変更されません。

以下に、低レベル .NET SDK API を使用して既存の項目を更新するステップを示します。

1. `AmazonDynamoDBClient` クラスのインスタンスを作成します。

1. `UpdateItemRequest` クラスのインスタンスを作成して、必要なパラメータを指定します。

   これは、属性の追加、既存の属性の更新、属性の削除など、すべての更新を記述するリクエストオブジェクトです。既存の属性を削除するには、その属性名に null 値を指定します。

1. 前のステップで作成した `UpdateItemRequest` オブジェクトを指定して、`UpdateItem` メソッドを実行します。

以下の C\$1 サンプルコードは、前述のステップの例です。例では、`ProductCatalog` テーブルのブック項目を更新します。この例では、`Authors` のコレクションに著者を追加し、既存の `ISBN` 属性を削除します。また、価格を 1 引き下げます。



```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new UpdateItemRequest
{
    TableName = tableName,
    Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } },
    ExpressionAttributeNames = new Dictionary<string,string>()
    {
        {"#A", "Authors"},
        {"#P", "Price"},
        {"#NA", "NewAttribute"},
        {"#I", "ISBN"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":auth",new AttributeValue { SS = {"Author YY","Author ZZ"}}},
        {":p",new AttributeValue {N = "1"}},
        {":newattr",new AttributeValue {S = "someValue"}},
    },

    // This expression does the following:
    // 1) Adds two new authors to the list
    // 2) Reduces the price
    // 3) Adds a new attribute to the item
    // 4) Removes the ISBN attribute from the item
    UpdateExpression = "ADD #A :auth SET #P = #P - :p, #NA = :newattr REMOVE #I"
};
var response = client.UpdateItem(request);
```

### オプションパラメータの指定
<a name="UpdateItemLowLevelDotNETOptions"></a>

次の C\$1 例に示すように、`UpdateItemRequest` オブジェクトを使用してオプションのパラメータを指定することもできます。次のオプションパラメータが指定されています。
+ `ExpressionAttributeValues` および `ConditionExpression` は、既存の料金が 20.00 である場合にのみ料金を更新できるように指定します。
+ レスポンスで更新された項目をリクエストする `ReturnValues` パラメータ。

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new UpdateItemRequest
{
    Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } },

    // Update price only if the current price is 20.00.
    ExpressionAttributeNames = new Dictionary<string,string>()
    {
        {"#P", "Price"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":newprice",new AttributeValue {N = "22"}},
        {":currprice",new AttributeValue {N = "20"}}
    },
    UpdateExpression = "SET #P = :newprice",
    ConditionExpression = "#P = :currprice",
    TableName = tableName,
    ReturnValues = "ALL_NEW" // Return all the attributes of the updated item.
};

var response = client.UpdateItem(request);
```

詳細については、「[UpdateItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html)」を参照してください。

## アトミックカウンタ
<a name="AtomicCounterLowLevelDotNet"></a>

`updateItem` を使用してアトミックカウンターを実装できます。アトミックカウンターでは、他の書き込みリクエストを妨げることなく、既存の属性の値をインクリメントまたはデクリメントします。アトミックカウンタを更新するには、`UpdateExpression` パラメータにタイプに `Number` の属性を持つ `updateItem` および `ADD` を、`Action` として使用します。

次のサンプルはこのアトミックカウンターを示しており、`Quantity` 属性を 1 ずつインクリメントさせています。

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new UpdateItemRequest
{
    Key = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { N = "121" } } },
    ExpressionAttributeNames = new Dictionary<string, string>()
    {
        {"#Q", "Quantity"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":incr",new AttributeValue {N = "1"}}
    },
    UpdateExpression = "SET #Q = #Q + :incr",
    TableName = tableName
};

var response = client.UpdateItem(request);
```

## 項目の削除
<a name="DeleteMidLevelDotNet"></a>

`DeleteItem` メソッドによって、テーブルから項目を削除します。

以下では、低レベル .NET SDK API を使用して項目を削除するステップを示します。

1. `AmazonDynamoDBClient` クラスのインスタンスを作成します。

1. `DeleteItemRequest` クラスのインスタンスを作成して、必要なパラメータを指定します。

    項目を削除するには、テーブル名と項目のプライマリキーが必要です。

1. 前のステップで作成した `DeleteItemRequest` オブジェクトを指定して、`DeleteItem` メソッドを実行します。

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
string tableName = "ProductCatalog";

var request = new DeleteItemRequest
{
    TableName = tableName,
    Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "201" } } },
};

var response = client.DeleteItem(request);
```

### オプションパラメータの指定
<a name="DeleteItemLowLevelDotNETOptions"></a>

次の C\$1 コード例に示すように、`DeleteItemRequest` オブジェクトを使用して任意のパラメータを指定することもできます。次のオプションパラメータが指定されています。
+ `ExpressionAttributeValues` および `ConditionExpression` は、ブック項目が公開されていない場合にのみ削除できるよう指定します (InPublication 属性値は false です)。
+ レスポンスで削除された項目をリクエストする `ReturnValues` パラメータ。

**Example**  

```
var request = new DeleteItemRequest
{
    TableName = tableName,
    Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "201" } } },

    // Optional parameters.
    ReturnValues = "ALL_OLD",
    ExpressionAttributeNames = new Dictionary<string, string>()
    {
        {"#IP", "InPublication"}
    },
    ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
    {
        {":inpub",new AttributeValue {BOOL = false}}
    },
    ConditionExpression = "#IP = :inpub"
};

var response = client.DeleteItem(request);
```

詳細については、「[DeleteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DeleteItem.html)」を参照してください。

## バッチ書き込み: 複数の項目の置換および削除
<a name="BatchWriteLowLevelDotNet"></a>

*バッチ書き込み*は、複数の項目の書き込みと削除をバッチで行うことを意味します。`BatchWriteItem` メソッドによって、単一の コール内にある 1 つまたは複数のテーブルから複数の項目を置換および削除できます。以下に、低レベル .NET SDK API を使用して複数の項目を取得するステップを示します。

1. `AmazonDynamoDBClient` クラスのインスタンスを作成します。

1. `BatchWriteItemRequest` クラスのインスタンスを作成して、すべての入力および削除オペレーションを記述します。

1. 前のステップで作成した `BatchWriteItemRequest` オブジェクトを指定して、`BatchWriteItem` メソッドを実行します。

1. 応答を処理します。返された未処理のリクエスト項目が応答内に存在していたかどうかをチェックする必要があります。これは、プロビジョニングされたスループットクォータまたは他の何らかの一時的エラーに達する場合に、発生する可能性があります。また、DynamoDB によって、リクエストのサイズ、およびリクエスト内で指定できるオペレーションの数が制限されます。これらの制限を超えると、DynamoDB によってリクエストが却下されます。詳細については、[BatchWriteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html) を参照してください。

以下の C\$1 サンプルコードは、前述のステップの例です。この例では、`BatchWriteItemRequest` を作成して次の書き込みオペレーションを実行します。
+ `Forum` テーブル内で項目を配置します。
+ `Thread` テーブルから項目を入力および削除します。

このコードは `BatchWriteItem` を実行してバッチ操作を実行します。

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();

string table1Name = "Forum";
string table2Name = "Thread";

var request = new BatchWriteItemRequest
 {
   RequestItems = new Dictionary<string, List<WriteRequest>>
    {
      {
        table1Name, new List<WriteRequest>
        {
          new WriteRequest
          {
             PutRequest = new PutRequest
             {
                Item = new Dictionary<string,AttributeValue>
                {
                  { "Name", new AttributeValue { S = "Amazon S3 forum" } },
                  { "Threads", new AttributeValue { N = "0" }}
                }
             }
          }
        }
      } ,
      {
        table2Name, new List<WriteRequest>
        {
          new WriteRequest
          {
            PutRequest = new PutRequest
            {
               Item = new Dictionary<string,AttributeValue>
               {
                 { "ForumName", new AttributeValue { S = "Amazon S3 forum" } },
                 { "Subject", new AttributeValue { S = "My sample question" } },
                 { "Message", new AttributeValue { S = "Message Text." } },
                 { "KeywordTags", new AttributeValue { SS = new List<string> { "Amazon S3", "Bucket" }  } }
               }
            }
          },
          new WriteRequest
          {
             DeleteRequest = new DeleteRequest
             {
                Key = new Dictionary<string,AttributeValue>()
                {
                   { "ForumName", new AttributeValue { S = "Some forum name" } },
                   { "Subject", new AttributeValue { S = "Some subject" } }
                }
             }
          }
        }
      }
    }
 };
response = client.BatchWriteItem(request);
```

実例については、「[例: AWS SDK for .NET 低レベル API を使用したバッチオペレーション](batch-operation-lowlevel-dotnet.md)」を参照してください。

## バッチ取得: 複数の項目の取得
<a name="BatchGetLowLevelDotNet"></a>

`BatchGetItem` メソッドによって、1 つまたは複数のテーブルから複数の項目を取得できます。

**注記**  
単一の項目を取り出すために、`GetItem` メソッドを使用できます。

以下に、低レベル AWS SDK for .NET API を使用して複数の項目を取得するステップを示します。

1. `AmazonDynamoDBClient` クラスのインスタンスを作成します。

1. `BatchGetItemRequest` クラスのインスタンスを作成して、必要なパラメータを指定します。

   複数の項目を取得するには、テーブル名とプライマリキーバリューのリストが必要です。

1. 前のステップで作成した `BatchGetItemRequest` オブジェクトを指定して、`BatchGetItem` メソッドを実行します。

1. 応答を処理します。未処理キーがなかったかどうかを確認する必要があります。これは、プロビジョニングされたスループットクォータまたは他の何らかの一時的エラーに達する場合に発生する可能性があります。

以下の C\$1 サンプルコードは、前述のステップの例です。この例では、`Forum` および `Thread` の 2 つのテーブルから取得します。リクエストでは、`Forum` テーブルに 2 つの項目、`Thread` テーブルに 3 つの項目を指定します。応答には、両方のテーブルの項目が含まれます。このコードは、応答を処理する方法を示しています。



```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();

string table1Name = "Forum";
string table2Name = "Thread";

var request = new BatchGetItemRequest
{
  RequestItems = new Dictionary<string, KeysAndAttributes>()
  {
    { table1Name,
      new KeysAndAttributes
      {
        Keys = new List<Dictionary<string, AttributeValue>>()
        {
          new Dictionary<string, AttributeValue>()
          {
            { "Name", new AttributeValue { S = "DynamoDB" } }
          },
          new Dictionary<string, AttributeValue>()
          {
            { "Name", new AttributeValue { S = "Amazon S3" } }
          }
        }
      }
    },
    {
      table2Name,
      new KeysAndAttributes
      {
        Keys = new List<Dictionary<string, AttributeValue>>()
        {
          new Dictionary<string, AttributeValue>()
          {
            { "ForumName", new AttributeValue { S = "DynamoDB" } },
            { "Subject", new AttributeValue { S = "DynamoDB Thread 1" } }
          },
          new Dictionary<string, AttributeValue>()
          {
            { "ForumName", new AttributeValue { S = "DynamoDB" } },
            { "Subject", new AttributeValue { S = "DynamoDB Thread 2" } }
          },
          new Dictionary<string, AttributeValue>()
          {
            { "ForumName", new AttributeValue { S = "Amazon S3" } },
            { "Subject", new AttributeValue { S = "Amazon S3 Thread 1" } }
          }
        }
      }
    }
  }
};

var response = client.BatchGetItem(request);

// Check the response.
var result = response.BatchGetItemResult;
var responses = result.Responses; // The attribute list in the response.

var table1Results = responses[table1Name];
Console.WriteLine("Items in table {0}" + table1Name);
foreach (var item1 in table1Results.Items)
{
  PrintItem(item1);
}

var table2Results = responses[table2Name];
Console.WriteLine("Items in table {1}" + table2Name);
foreach (var item2 in table2Results.Items)
{
  PrintItem(item2);
}
// Any unprocessed keys? could happen if you exceed ProvisionedThroughput or some other error.
Dictionary<string, KeysAndAttributes> unprocessedKeys = result.UnprocessedKeys;
foreach (KeyValuePair<string, KeysAndAttributes> pair in unprocessedKeys)
{
    Console.WriteLine(pair.Key, pair.Value);
}
```



### オプションパラメータの指定
<a name="BatchGetItemLowLevelDotNETOptions"></a>

次の C\$1 コード例に示すように、`BatchGetItemRequest` オブジェクトを使用して任意のパラメータを指定することもできます。例では、`Forum` テーブルから 2 つの項目を取得します。次のオプションパラメータが指定されています。
+  取得する属性を指定する `ProjectionExpression` パラメータ。

**Example**  

```
AmazonDynamoDBClient client = new AmazonDynamoDBClient();

string table1Name = "Forum";

var request = new BatchGetItemRequest
{
  RequestItems = new Dictionary<string, KeysAndAttributes>()
  {
    { table1Name,
      new KeysAndAttributes
      {
        Keys = new List<Dictionary<string, AttributeValue>>()
        {
          new Dictionary<string, AttributeValue>()
          {
            { "Name", new AttributeValue { S = "DynamoDB" } }
          },
          new Dictionary<string, AttributeValue>()
          {
            { "Name", new AttributeValue { S = "Amazon S3" } }
          }
        }
      },
      // Optional - name of an attribute to retrieve.
      ProjectionExpression = "Title"
    }
  }
};

var response = client.BatchGetItem(request);
```

詳細については、[BatchGetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html) を参照してください。

# 例: AWS SDK for .NET 低レベル API を使用した CRUD オペレーション
<a name="LowLevelDotNetItemsExample"></a>

以下の C\$1 コード例は、Amazon DynamoDB 項目に対する CRUD オペレーションの例です。この例では、`ProductCatalog` テーブルへの項目の追加、項目の取得、さまざまな更新の実行、さらに項目の削除を行います。このテーブルを作成していない場合は、プログラムで作成することもできます。詳細については、「[AWS SDK for .NET を使用してサンプルテーブルを作成してデータをアップロードする](AppendixSampleDataCodeDotNET.md)」を参照してください。

以下の例をテストするための詳細な手順については、「[.NET コード例](CodeSamples.DotNet.md)」を参照してください。

**Example**  

```
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;
using Amazon.SecurityToken;

namespace com.amazonaws.codesamples
{
    class LowLevelItemCRUDExample
    {
        private static string tableName = "ProductCatalog";
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            try
            {
                CreateItem();
                RetrieveItem();

                // Perform various updates.
                UpdateMultipleAttributes();
                UpdateExistingAttributeConditionally();

                // Delete item.
                DeleteItem();
                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
        }

        private static void CreateItem()
        {
            var request = new PutItemRequest
            {
                TableName = tableName,
                Item = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  }},
                { "Title", new AttributeValue {
                      S = "Book 201 Title"
                  }},
                { "ISBN", new AttributeValue {
                      S = "11-11-11-11"
                  }},
                { "Authors", new AttributeValue {
                      SS = new List<string>{"Author1", "Author2" }
                  }},
                { "Price", new AttributeValue {
                      N = "20.00"
                  }},
                { "Dimensions", new AttributeValue {
                      S = "8.5x11.0x.75"
                  }},
                { "InPublication", new AttributeValue {
                      BOOL = false
                  } }
            }
            };
            client.PutItem(request);
        }

        private static void RetrieveItem()
        {
            var request = new GetItemRequest
            {
                TableName = tableName,
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  } }
            },
                ProjectionExpression = "Id, ISBN, Title, Authors",
                ConsistentRead = true
            };
            var response = client.GetItem(request);

            // Check the response.
            var attributeList = response.Item; // attribute list in the response.
            Console.WriteLine("\nPrinting item after retrieving it ............");
            PrintItem(attributeList);
        }

        private static void UpdateMultipleAttributes()
        {
            var request = new UpdateItemRequest
            {
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  } }
            },
                // Perform the following updates:
                // 1) Add two new authors to the list
                // 1) Set a new attribute
                // 2) Remove the ISBN attribute
                ExpressionAttributeNames = new Dictionary<string, string>()
            {
                {"#A","Authors"},
                {"#NA","NewAttribute"},
                {"#I","ISBN"}
            },
                ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
            {
                {":auth",new AttributeValue {
                     SS = {"Author YY", "Author ZZ"}
                 }},
                {":new",new AttributeValue {
                     S = "New Value"
                 }}
            },

                UpdateExpression = "ADD #A :auth SET #NA = :new REMOVE #I",

                TableName = tableName,
                ReturnValues = "ALL_NEW" // Give me all attributes of the updated item.
            };
            var response = client.UpdateItem(request);

            // Check the response.
            var attributeList = response.Attributes; // attribute list in the response.
                                                     // print attributeList.
            Console.WriteLine("\nPrinting item after multiple attribute update ............");
            PrintItem(attributeList);
        }

        private static void UpdateExistingAttributeConditionally()
        {
            var request = new UpdateItemRequest
            {
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  } }
            },
                ExpressionAttributeNames = new Dictionary<string, string>()
            {
                {"#P", "Price"}
            },
                ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
            {
                {":newprice",new AttributeValue {
                     N = "22.00"
                 }},
                {":currprice",new AttributeValue {
                     N = "20.00"
                 }}
            },
                // This updates price only if current price is 20.00.
                UpdateExpression = "SET #P = :newprice",
                ConditionExpression = "#P = :currprice",

                TableName = tableName,
                ReturnValues = "ALL_NEW" // Give me all attributes of the updated item.
            };
            var response = client.UpdateItem(request);

            // Check the response.
            var attributeList = response.Attributes; // attribute list in the response.
            Console.WriteLine("\nPrinting item after updating price value conditionally ............");
            PrintItem(attributeList);
        }

        private static void DeleteItem()
        {
            var request = new DeleteItemRequest
            {
                TableName = tableName,
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      N = "1000"
                  } }
            },

                // Return the entire item as it appeared before the update.
                ReturnValues = "ALL_OLD",
                ExpressionAttributeNames = new Dictionary<string, string>()
            {
                {"#IP", "InPublication"}
            },
                ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
            {
                {":inpub",new AttributeValue {
                     BOOL = false
                 }}
            },
                ConditionExpression = "#IP = :inpub"
            };

            var response = client.DeleteItem(request);

            // Check the response.
            var attributeList = response.Attributes; // Attribute list in the response.
                                                     // Print item.
            Console.WriteLine("\nPrinting item that was just deleted ............");
            PrintItem(attributeList);
        }

        private static void PrintItem(Dictionary<string, AttributeValue> attributeList)
        {
            foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
            {
                string attributeName = kvp.Key;
                AttributeValue value = kvp.Value;

                Console.WriteLine(
                    attributeName + " " +
                    (value.S == null ? "" : "S=[" + value.S + "]") +
                    (value.N == null ? "" : "N=[" + value.N + "]") +
                    (value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") +
                    (value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]")
                    );
            }
            Console.WriteLine("************************************************");
        }
    }
}
```

# 例: AWS SDK for .NET 低レベル API を使用したバッチオペレーション
<a name="batch-operation-lowlevel-dotnet"></a>

**Topics**
+ [例: AWS SDK for .NET 低レベル API を使用したバッチ書き込みオペレーション](#batch-write-low-level-dotnet)
+ [例: AWS SDK for .NET 低レベル API を使用したバッチ取得オペレーション](#LowLevelDotNetBatchGet)

このセクションでは、Amazon DynamoDB がサポートするバッチ操作、*バッチ書き込み*、および*バッチ取得*の例を示します。

## 例: AWS SDK for .NET 低レベル API を使用したバッチ書き込みオペレーション
<a name="batch-write-low-level-dotnet"></a>

以下の C\$1 コード例では、`BatchWriteItem` メソッドを使用して、以下の置換および削除のオペレーションを実行します。
+ `Forum` テーブル内で 1 つの項目を配置します。
+ `Thread` テーブルに対して 1 つの項目を配置および削除します。

バッチの書き込みリクエストを作成すると、1 つまたは複数のテーブルに対して多数の置換リクエストと削除リクエストを指定できます。ただし、DynamoDB `BatchWriteItem` では、1 回のバッチ書き込みオペレーションで可能なバッチ書き込みリクエストのサイズ、置換および削除のオペレーションの数を制限しています。詳細については、[BatchWriteItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html) を参照してください。これらの制限を超えるリクエストは却下されます。プロビジョニングされたスループットがテーブルに不足しているためにこのリクエストを処理できない場合は、応答時に未処理のリクエスト項目が返されます。

以下の例では、未処理のリクエスト項目がないか、応答を確認します。未処理のリクエスト項目がある場合は、`BatchWriteItem` リクエストをループバックして再送信します。プログラムで、これらのサンプルテーブルを作成し、サンプルデータをアップロードすることもできます。詳細については、「」を参照してください[AWS SDK for .NET を使用してサンプルテーブルを作成してデータをアップロードする](AppendixSampleDataCodeDotNET.md)

以下の例をテストするための詳細な手順については、「[.NET コード例](CodeSamples.DotNet.md)」を参照してください。

**Example**  

```
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;

namespace com.amazonaws.codesamples
{
    class LowLevelBatchWrite
    {
        private static string table1Name = "Forum";
        private static string table2Name = "Thread";
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            try
            {
                TestBatchWrite();
            }
            catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
            catch (Exception e) { Console.WriteLine(e.Message); }

            Console.WriteLine("To continue, press Enter");
            Console.ReadLine();
        }

        private static void TestBatchWrite()
        {
            var request = new BatchWriteItemRequest
            {
                ReturnConsumedCapacity = "TOTAL",
                RequestItems = new Dictionary<string, List<WriteRequest>>
            {
                {
                    table1Name, new List<WriteRequest>
                    {
                        new WriteRequest
                        {
                            PutRequest = new PutRequest
                            {
                                Item = new Dictionary<string, AttributeValue>
                                {
                                    { "Name", new AttributeValue {
                                          S = "S3 forum"
                                      } },
                                    { "Threads", new AttributeValue {
                                          N = "0"
                                      }}
                                }
                            }
                        }
                    }
                },
                {
                    table2Name, new List<WriteRequest>
                    {
                        new WriteRequest
                        {
                            PutRequest = new PutRequest
                            {
                                Item = new Dictionary<string, AttributeValue>
                                {
                                    { "ForumName", new AttributeValue {
                                          S = "S3 forum"
                                      } },
                                    { "Subject", new AttributeValue {
                                          S = "My sample question"
                                      } },
                                    { "Message", new AttributeValue {
                                          S = "Message Text."
                                      } },
                                    { "KeywordTags", new AttributeValue {
                                          SS = new List<string> { "S3", "Bucket" }
                                      } }
                                }
                            }
                        },
                        new WriteRequest
                        {
                            // For the operation to delete an item, if you provide a primary key value
                            // that does not exist in the table, there is no error, it is just a no-op.
                            DeleteRequest = new DeleteRequest
                            {
                                Key = new Dictionary<string, AttributeValue>()
                                {
                                    { "ForumName",  new AttributeValue {
                                          S = "Some partition key value"
                                      } },
                                    { "Subject", new AttributeValue {
                                          S = "Some sort key value"
                                      } }
                                }
                            }
                        }
                    }
                }
            }
            };

            CallBatchWriteTillCompletion(request);
        }

        private static void CallBatchWriteTillCompletion(BatchWriteItemRequest request)
        {
            BatchWriteItemResponse response;

            int callCount = 0;
            do
            {
                Console.WriteLine("Making request");
                response = client.BatchWriteItem(request);
                callCount++;

                // Check the response.

                var tableConsumedCapacities = response.ConsumedCapacity;
                var unprocessed = response.UnprocessedItems;

                Console.WriteLine("Per-table consumed capacity");
                foreach (var tableConsumedCapacity in tableConsumedCapacities)
                {
                    Console.WriteLine("{0} - {1}", tableConsumedCapacity.TableName, tableConsumedCapacity.CapacityUnits);
                }

                Console.WriteLine("Unprocessed");
                foreach (var unp in unprocessed)
                {
                    Console.WriteLine("{0} - {1}", unp.Key, unp.Value.Count);
                }
                Console.WriteLine();

                // For the next iteration, the request will have unprocessed items.
                request.RequestItems = unprocessed;
            } while (response.UnprocessedItems.Count > 0);

            Console.WriteLine("Total # of batch write API calls made: {0}", callCount);
        }
    }
}
```

## 例: AWS SDK for .NET 低レベル API を使用したバッチ取得オペレーション
<a name="LowLevelDotNetBatchGet"></a>

次の C\$1 コード例では、`BatchGetItem` メソッドを使用して、Amazon DynamoDB の `Forum` テーブルおよび `Thread` テーブルから複数の項目を取り出します。`BatchGetItemRequest` は、各テーブルのテーブル名とプライマリキーのリストを指定します。この例では、取得した項目を印刷して応答を処理します。

以下の例をテストするための詳細な手順については、「[.NET コード例](CodeSamples.DotNet.md)」を参照してください。

**Example**  

```
using System;
using System.Collections.Generic;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;

namespace com.amazonaws.codesamples
{
    class LowLevelBatchGet
    {
        private static string table1Name = "Forum";
        private static string table2Name = "Thread";
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            try
            {
                RetrieveMultipleItemsBatchGet();

                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
            catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
            catch (Exception e) { Console.WriteLine(e.Message); }
        }

        private static void RetrieveMultipleItemsBatchGet()
        {
            var request = new BatchGetItemRequest
            {
                RequestItems = new Dictionary<string, KeysAndAttributes>()
            {
                { table1Name,
                  new KeysAndAttributes
                  {
                      Keys = new List<Dictionary<string, AttributeValue> >()
                      {
                          new Dictionary<string, AttributeValue>()
                          {
                              { "Name", new AttributeValue {
                            S = "Amazon DynamoDB"
                        } }
                          },
                          new Dictionary<string, AttributeValue>()
                          {
                              { "Name", new AttributeValue {
                            S = "Amazon S3"
                        } }
                          }
                      }
                  }},
                {
                    table2Name,
                    new KeysAndAttributes
                    {
                        Keys = new List<Dictionary<string, AttributeValue> >()
                        {
                            new Dictionary<string, AttributeValue>()
                            {
                                { "ForumName", new AttributeValue {
                                      S = "Amazon DynamoDB"
                                  } },
                                { "Subject", new AttributeValue {
                                      S = "DynamoDB Thread 1"
                                  } }
                            },
                            new Dictionary<string, AttributeValue>()
                            {
                                { "ForumName", new AttributeValue {
                                      S = "Amazon DynamoDB"
                                  } },
                                { "Subject", new AttributeValue {
                                      S = "DynamoDB Thread 2"
                                  } }
                            },
                            new Dictionary<string, AttributeValue>()
                            {
                                { "ForumName", new AttributeValue {
                                      S = "Amazon S3"
                                  } },
                                { "Subject", new AttributeValue {
                                      S = "S3 Thread 1"
                                  } }
                            }
                        }
                    }
                }
            }
            };

            BatchGetItemResponse response;
            do
            {
                Console.WriteLine("Making request");
                response = client.BatchGetItem(request);

                // Check the response.
                var responses = response.Responses; // Attribute list in the response.

                foreach (var tableResponse in responses)
                {
                    var tableResults = tableResponse.Value;
                    Console.WriteLine("Items retrieved from table {0}", tableResponse.Key);
                    foreach (var item1 in tableResults)
                    {
                        PrintItem(item1);
                    }
                }

                // Any unprocessed keys? could happen if you exceed ProvisionedThroughput or some other error.
                Dictionary<string, KeysAndAttributes> unprocessedKeys = response.UnprocessedKeys;
                foreach (var unprocessedTableKeys in unprocessedKeys)
                {
                    // Print table name.
                    Console.WriteLine(unprocessedTableKeys.Key);
                    // Print unprocessed primary keys.
                    foreach (var key in unprocessedTableKeys.Value.Keys)
                    {
                        PrintItem(key);
                    }
                }

                request.RequestItems = unprocessedKeys;
            } while (response.UnprocessedKeys.Count > 0);
        }

        private static void PrintItem(Dictionary<string, AttributeValue> attributeList)
        {
            foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
            {
                string attributeName = kvp.Key;
                AttributeValue value = kvp.Value;

                Console.WriteLine(
                    attributeName + " " +
                    (value.S == null ? "" : "S=[" + value.S + "]") +
                    (value.N == null ? "" : "N=[" + value.N + "]") +
                    (value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") +
                    (value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]")
                    );
            }
            Console.WriteLine("************************************************");
        }
    }
}
```

# 例: AWS SDK for .NET 低レベル API を使用したバイナリタイプ属性の処理
<a name="LowLevelDotNetBinaryTypeExample"></a>

以下の C\$1 コード例は、バイナリタイプ属性の処理の例です。この例では、`Reply` テーブルに項目を追加します。この項目には、圧縮データを格納するバイナリタイプ属性（`ExtendedMessage`）などがあります。また、この例では、項目を取得し、すべての属性値を印刷します。説明のため、この例では `GZipStream` クラスを使用して、サンプルストリームを圧縮し、圧縮したデータを `ExtendedMessage` 属性に割り当て、属性値を出力するときに解凍します。

以下の例をテストするための詳細な手順については、「[.NET コード例](CodeSamples.DotNet.md)」を参照してください。

**Example**  

```
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.Model;
using Amazon.Runtime;

namespace com.amazonaws.codesamples
{
    class LowLevelItemBinaryExample
    {
        private static string tableName = "Reply";
        private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();

        static void Main(string[] args)
        {
            // Reply table primary key.
            string replyIdPartitionKey = "Amazon DynamoDB#DynamoDB Thread 1";
            string replyDateTimeSortKey = Convert.ToString(DateTime.UtcNow);

            try
            {
                CreateItem(replyIdPartitionKey, replyDateTimeSortKey);
                RetrieveItem(replyIdPartitionKey, replyDateTimeSortKey);
                // Delete item.
                DeleteItem(replyIdPartitionKey, replyDateTimeSortKey);
                Console.WriteLine("To continue, press Enter");
                Console.ReadLine();
            }
            catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); }
            catch (AmazonServiceException e) { Console.WriteLine(e.Message); }
            catch (Exception e) { Console.WriteLine(e.Message); }
        }

        private static void CreateItem(string partitionKey, string sortKey)
        {
            MemoryStream compressedMessage = ToGzipMemoryStream("Some long extended message to compress.");
            var request = new PutItemRequest
            {
                TableName = tableName,
                Item = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      S = partitionKey
                  }},
                { "ReplyDateTime", new AttributeValue {
                      S = sortKey
                  }},
                { "Subject", new AttributeValue {
                      S = "Binary type "
                  }},
                { "Message", new AttributeValue {
                      S = "Some message about the binary type"
                  }},
                { "ExtendedMessage", new AttributeValue {
                      B = compressedMessage
                  }}
            }
            };
            client.PutItem(request);
        }

        private static void RetrieveItem(string partitionKey, string sortKey)
        {
            var request = new GetItemRequest
            {
                TableName = tableName,
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      S = partitionKey
                  } },
                { "ReplyDateTime", new AttributeValue {
                      S = sortKey
                  } }
            },
                ConsistentRead = true
            };
            var response = client.GetItem(request);

            // Check the response.
            var attributeList = response.Item; // attribute list in the response.
            Console.WriteLine("\nPrinting item after retrieving it ............");

            PrintItem(attributeList);
        }

        private static void DeleteItem(string partitionKey, string sortKey)
        {
            var request = new DeleteItemRequest
            {
                TableName = tableName,
                Key = new Dictionary<string, AttributeValue>()
            {
                { "Id", new AttributeValue {
                      S = partitionKey
                  } },
                { "ReplyDateTime", new AttributeValue {
                      S = sortKey
                  } }
            }
            };
            var response = client.DeleteItem(request);
        }

        private static void PrintItem(Dictionary<string, AttributeValue> attributeList)
        {
            foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
            {
                string attributeName = kvp.Key;
                AttributeValue value = kvp.Value;

                Console.WriteLine(
                    attributeName + " " +
                    (value.S == null ? "" : "S=[" + value.S + "]") +
                    (value.N == null ? "" : "N=[" + value.N + "]") +
                    (value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") +
                    (value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]") +
                    (value.B == null ? "" : "B=[" + FromGzipMemoryStream(value.B) + "]")
                    );
            }
            Console.WriteLine("************************************************");
        }

        private static MemoryStream ToGzipMemoryStream(string value)
        {
            MemoryStream output = new MemoryStream();
            using (GZipStream zipStream = new GZipStream(output, CompressionMode.Compress, true))
            using (StreamWriter writer = new StreamWriter(zipStream))
            {
                writer.Write(value);
            }
            return output;
        }

        private static string FromGzipMemoryStream(MemoryStream stream)
        {
            using (GZipStream zipStream = new GZipStream(stream, CompressionMode.Decompress))
            using (StreamReader reader = new StreamReader(zipStream))
            {
                return reader.ReadToEnd();
            }
        }
    }
}
```