Amazon DynamoDB 入門ガイド API Version 2012-08-10 Amazon DynamoDB 入門ガイド Amazon DynamoDB 入門ガイド Amazon DynamoDB: 入門ガイド Copyright © 2017 Amazon Web Services, Inc. and/or its affiliates. All rights reserved. Amazon's trademarks and trade dress may not be used in connection with any product or service that is not Amazon's, in any manner that is likely to cause confusion among customers, or in any manner that disparages or discredits Amazon. All other trademarks not owned by Amazon are the property of their respective owners, who may or may not be affiliated with, connected to, or sponsored by Amazon. Amazon DynamoDB 入門ガイド Table of Contents Amazon DynamoDB の使用開始 ...................................................................................................... 1 DynamoDB の概念について .................................................................................................... 1 テーブル ...................................................................................................................... 1 アイテム ...................................................................................................................... 1 属性 ............................................................................................................................ 2 プライマリキー ............................................................................................................. 2 セカンダリインデックス ................................................................................................ 2 コンピュータでの DynamoDB の実行 ...................................................................................... 3 DynamoDB (ダウンロード可能バージョン) と DynamoDB ウェブサービス ............................. 3 DynamoDB のダウンロードと実行 ................................................................................... 4 Java と DynamoDB ...................................................................................................................... 6 前提条件 .............................................................................................................................. 6 ステップ 1: テーブルを作成する ............................................................................................. 7 ステップ 2: サンプルデータをロードする ................................................................................. 8 ステップ 2.1: サンプルデータファイルをダウンロードする ................................................. 9 ステップ 2.2: 映画テーブルにサンプルデータをロードする ................................................. 9 ステップ 3: 項目を作成、読み込み、更新、削除する ................................................................ 11 ステップ 3.1: 新しい項目を作成する .............................................................................. 11 ステップ 3.2: 項目を読み取る ....................................................................................... 12 ステップ 3.3: 項目を更新する ....................................................................................... 13 ステップ 3.4: アトミックカウンターを増分する ............................................................... 15 ステップ 3.5: 項目を更新する (条件付き) ........................................................................ 16 ステップ 3.6: 項目を削除する ....................................................................................... 18 ステップ 4: データをクエリおよびスキャンする ...................................................................... 19 ステップ 4.1: クエリ ................................................................................................... 19 ステップ 4.2: スキャン ................................................................................................ 21 ステップ 5: (オプション) テーブルを削除する ......................................................................... 23 概要 .................................................................................................................................. 24 Amazon DynamoDB サービスを使用する ........................................................................ 24 JavaScript と DynamoDB ............................................................................................................. 25 前提条件 ............................................................................................................................ 25 ステップ 1: テーブルを作成する ............................................................................................ 26 ステップ 2: サンプルデータをロードする ................................................................................ 27 ステップ 2.1: サンプルデータファイルをダウンロードする ................................................ 29 ステップ 2.2: 映画テーブルにサンプルデータをロードする ................................................ 29 ステップ 3: 項目を作成、読み込み、更新、削除する ................................................................ 30 ステップ 3.1: 新しい項目を作成する .............................................................................. 31 ステップ 3.2: 項目を読み取る ....................................................................................... 32 ステップ 3.3: 項目を更新する ....................................................................................... 33 ステップ 3.4: アトミックカウンターを増分する ............................................................... 35 ステップ 3.5: 項目を更新する (条件付き) ........................................................................ 37 ステップ 3.6: 項目を削除する ....................................................................................... 38 ステップ 4: データをクエリおよびスキャンする ...................................................................... 40 ステップ 4.1: クエリ - 1 年間にリリースされたすべての映画 ............................................. 41 ステップ 4.2: クエリ - 1 年間にリリースされた特定のタイトルを持つすべての映画 ............... 42 ステップ 4.3: スキャン ................................................................................................ 44 ステップ 5: (オプション) テーブルを削除する ......................................................................... 45 概要 .................................................................................................................................. 46 AWS 設定リージョンの更新 .......................................................................................... 47 AWS CLI のインストールと設定 .................................................................................... 47 Amazon Cognito を使用したファイルでの AWS 認証情報の設定 ........................................ 47 Node.js と DynamoDB ................................................................................................................. 50 前提条件 ............................................................................................................................ 50 ステップ 1: テーブルを作成する ............................................................................................ 51 ステップ 2: サンプルデータをロードする ................................................................................ 52 API Version 2012-08-10 iv Amazon DynamoDB 入門ガイド ステップ 2.1: サンプルデータファイルをダウンロードする ................................................ 53 ステップ 2.2: 映画テーブルにサンプルデータをロードする ................................................ 53 ステップ 3: 項目を作成、読み込み、更新、削除する ................................................................ 54 ステップ 3.1: 新しい項目を作成する .............................................................................. 54 ステップ 3.2: 項目を読み取る ....................................................................................... 55 ステップ 3.3: 項目を更新する ....................................................................................... 56 ステップ 3.4: アトミックカウンターを増分する ............................................................... 58 ステップ 3.5: 項目を更新する (条件付き) ........................................................................ 59 ステップ 3.6: 項目を削除する ....................................................................................... 60 ステップ 4: データをクエリおよびスキャンする ...................................................................... 61 ステップ 4.1: クエリ - 1 年間にリリースされたすべての映画 ............................................. 61 ステップ 4.2: クエリ - 1 年間にリリースされた特定のタイトルを持つすべての映画 ............... 63 ステップ 4.3: スキャン ................................................................................................ 64 ステップ 5: (オプション) テーブルを削除する ......................................................................... 65 概要 .................................................................................................................................. 66 Amazon DynamoDB サービスを使用する ........................................................................ 66 .NET と DynamoDB .................................................................................................................... 67 前提条件 ............................................................................................................................ 67 ステップ 1: テーブルを作成する ............................................................................................ 68 ステップ 2: サンプルデータをロードする ................................................................................ 70 ステップ 2.1: サンプルデータファイルをダウンロードする ................................................ 71 ステップ 2.2: 映画テーブルにサンプルデータをロードする ................................................ 71 ステップ 3: 項目を作成、読み込み、更新、削除する ................................................................ 73 ステップ 3.1: 新しい項目を作成する .............................................................................. 74 ステップ 3.2: 項目を読み取る ....................................................................................... 75 ステップ 3.3: 項目を更新する ....................................................................................... 77 ステップ 3.4: アトミックカウンターを増分する ............................................................... 80 ステップ 3.5: 項目を更新する (条件付き) ........................................................................ 82 ステップ 3.6: 項目を削除する ....................................................................................... 84 ステップ 4: データをクエリおよびスキャンする ...................................................................... 86 ステップ 4.1: クエリ ................................................................................................... 86 ステップ 4.2: スキャン ................................................................................................ 91 ステップ 5: (オプション) テーブルを削除する ......................................................................... 94 概要 .................................................................................................................................. 95 Amazon DynamoDB サービスを使用する ........................................................................ 95 PHP および DynamoDB ............................................................................................................... 97 前提条件 ............................................................................................................................ 97 ステップ 1: テーブルを作成する ............................................................................................ 98 ステップ 2: サンプルデータをロードする ................................................................................ 99 ステップ 2.1: サンプルデータファイルをダウンロードする .............................................. 100 ステップ 2.2: 映画テーブルにサンプルデータをロードする .............................................. 100 ステップ 3: 項目を作成、読み込み、更新、削除する ............................................................... 102 ステップ 3.1: 新しい項目を作成する ............................................................................ 102 ステップ 3.2: 項目を読み取る ...................................................................................... 103 ステップ 3.3: 項目を更新する ...................................................................................... 104 ステップ 3.4: アトミックカウンターを増分する ............................................................. 106 ステップ 3.5: 項目を更新する (条件付き) ...................................................................... 107 ステップ 3.6: 項目を削除する ...................................................................................... 109 ステップ 4: データをクエリおよびスキャンする ..................................................................... 110 ステップ 4.1: クエリ - 1 年間にリリースされたすべての映画 ........................................... 111 ステップ 4.2: クエリ - 1 年間にリリースされた特定のタイトルを持つすべての映画 ............. 112 ステップ 4.3: スキャン ............................................................................................... 113 ステップ 5: (オプション) テーブルを削除する ........................................................................ 115 概要 ................................................................................................................................. 116 Amazon DynamoDB サービスを使用する ...................................................................... 116 Python および DynamoDB .......................................................................................................... 117 前提条件 .......................................................................................................................... 117 ステップ 1: テーブルを作成する .......................................................................................... 118 API Version 2012-08-10 v Amazon DynamoDB 入門ガイド ステップ 2: サンプルデータをロードする .............................................................................. 119 ステップ 2.1: サンプルデータファイルをダウンロードする .............................................. 120 ステップ 2.2: 映画テーブルにサンプルデータをロードする .............................................. 120 ステップ 3: 項目を作成、読み込み、更新、削除する ............................................................... 121 ステップ 3.1: 新しい項目を作成する ............................................................................ 121 ステップ 3.2: 項目を読み取る ...................................................................................... 122 ステップ 3.3: 項目を更新する ...................................................................................... 123 ステップ 3.4: アトミックカウンターを増分する ............................................................. 125 ステップ 3.5: 項目を更新する (条件付き) ...................................................................... 126 ステップ 3.6: 項目を削除する ...................................................................................... 127 ステップ 4: データをクエリおよびスキャンする ..................................................................... 128 ステップ 4.1: クエリ - 1 年間にリリースされたすべての映画 ........................................... 129 ステップ 4.2: クエリ - 1 年間にリリースされた特定のタイトルを持つすべての映画 ............. 130 ステップ 4.3: スキャン ............................................................................................... 131 ステップ 5: (オプション) テーブルを削除する ........................................................................ 132 概要 ................................................................................................................................. 133 Amazon DynamoDB サービスへの移動 ......................................................................... 133 Ruby および DynamoDB ............................................................................................................ 134 前提条件 .......................................................................................................................... 134 ステップ 1: テーブルを作成する .......................................................................................... 135 ステップ 2: サンプルデータをロードする .............................................................................. 136 ステップ 2.1: サンプルデータファイルをダウンロードする .............................................. 137 ステップ 2.2: 映画テーブルにサンプルデータをロードする .............................................. 137 ステップ 3: 項目を作成、読み込み、更新、削除する ............................................................... 138 ステップ 3.1: 新しい項目を作成する ............................................................................ 138 ステップ 3.2: 項目を読み取る ...................................................................................... 139 ステップ 3.3: 項目を更新する ...................................................................................... 140 ステップ 3.4: アトミックカウンターを増分する ............................................................. 142 ステップ 3.5: 項目を更新する (条件付き) ...................................................................... 143 ステップ 3.6: 項目を削除する ...................................................................................... 144 ステップ 4: データをクエリおよびスキャンする ..................................................................... 145 ステップ 4.1: クエリ - 1 年間にリリースされたすべての映画 ........................................... 146 ステップ 4.2: クエリ - 1 年間にリリースされた特定のタイトルを持つすべての映画 ............. 147 ステップ 4.3: スキャン ............................................................................................... 148 ステップ 5: (オプション) テーブルを削除する ........................................................................ 149 概要 ................................................................................................................................. 150 Amazon DynamoDB サービスを使用する ...................................................................... 150 API Version 2012-08-10 vi Amazon DynamoDB 入門ガイド DynamoDB の概念について Amazon DynamoDB の使用開始 『Amazon DynamoDB 入門ガイド』へようこそ。このガイドには、Amazon DynamoDB の学習に役 立つハンズオンチュートリアルが含まれています。次のことをお勧めします。 • DynamoDB の概念に精通する。 • DynamoDB をダウンロードして実行する。 • 言語固有のチュートリアルの 1 つを実行する。それらのチュートリアルにあるサンプルコード は、DynamoDB のダウンロード可能バージョンまたは Amazon DynamoDB ウェブサービスに対し て実行できます。 Note AWS SDK は、さまざまな言語で利用できます。詳細なリストについては、「Tools for Amazon Web Services」を参照してください。 また、「Amazon DynamoDB 開発者ガイド」を読むことをお勧めします。ここには、サンプルコード やベストプラクティスなど、DynamoDB に関するさらに詳しい情報が収められています。 トピック • DynamoDB の概念について (p. 1) • コンピュータでの DynamoDB の実行 (p. 3) DynamoDB の概念について このセクションでは、DynamoDB のいくつかの基本的な概念について簡単に説明します。これは、 チュートリアルのステップに従う際に役立ちます。 テーブル 他のデータベース管理システムと同様、DynamoDB はデータをテーブルに保存します。テーブルは、 データのコレクションです。たとえば、People というテーブルを作成し、友人、家族、関心のある 他の人に関する情報を保存できます。その人たちが運転する車に関する情報を保存する Cars テーブ ルを作成することもできます。 アイテム 各テーブルには複数の項目が含まれています。項目は、他のすべての項目間で一意に識別可能な属性 のグループです。People テーブルでは、各項目は 1 人の人を表します。Cars テーブルの場合、各 API Version 2012-08-10 1 Amazon DynamoDB 入門ガイド 属性 項目は 1 台の車を表します。項目は、多くの点でリレーショナルデータベースシステムの行、レコー ド、またはタプルに似ています。DynamoDB では、テーブルに保存できる項目数に制限はありませ ん。 属性 各項目は、1 つ以上の属性で構成されます。属性は、基盤となるデータ要素で あり、それ以上分割する必要がないものです。たとえば、Department 項目に は、DepartmentID、Name、Manager などの属性を設定することができます。People テーブル内の 項目には、PersonID、LastName、FirstName などの属性を含めることができます。DynamoDB 内 の属性は、多くの点で他のデータベース管理システムのフィールドや列に似ています。 プライマリキー テーブルを作成する場合には、テーブル名に加えて、テーブルのプライマリキーを指定する必要があ ります。他のデータベースと同様、DynamoDB でのプライマリキーはテーブルの各項目を一意に識別 するため、テーブル内の 2 つの項目が同じキーを持つことはありません。テーブル内の項目を追加、 更新、または削除するときは、その項目のプライマリキー属性値を指定する必要があります。キー値 は必須です。省略することはできません。 DynamoDB は 2 種類の異なるプライマリキーをサポートします。 • パーティションキー — パーティションキーという 1 つの属性で構成されたシンプルなプライマリ キー。DynamoDB は内部ハッシュ関数への入力として、パーティションキーの値を使用します。 ハッシュ関数からの出力により、項目が保存されるパーティションが決まります。シンプルなプラ イマリキーを使用すると、テーブルの 2 つの項目でパーティションキー値を同じにすることはでき なくなります。 • パーティションキーとソートキー — 2 つの属性で構成された複合プライマリキー。最初の属性 はパーティションキーであり、2 番目の属性はソートキーです。DynamoDB は内部ハッシュ関数 への入力として、パーティションキーの値を使用します。ハッシュ関数からの出力により、項目 が保存されるパーティションが決まります。同じパーティションキーを持つすべての項目は、ソー トキー値でソートされてまとめて保存されます。複合プライマリキーを使用すると、2 つの項目で パーティションキー値を同じにすることは可能ですが、これらの 2 つの項目のソートキー値は異 なっている必要があります。 Note 項目のパーティションキーは、そのハッシュ属性とも呼ばれます。この用語は、サービスが 内部のハッシュ関数を使用し、パーティションキーの値に基づいてパーティション間でデー タ項目を均等に分散することに由来しています。 項目のソートキーは、範囲属性とも呼ばれます。この用語は、ソートキー値で並べ替えられ た順に、DynamoDB が同じパーティションキーを持つ項目どうしを物理的に近くに保存する 方法に由来しています。 セカンダリインデックス DynamoDB では、プライマリキー属性の値を指定することでテーブルのデータを読み取ることができ ます。非キー属性を使用してデータを読み取る場合、セカンダリインデックスを使用してこれを行う ことができます。テーブルにグローバルセカンダリインデックスを作成すると、テーブルから行う場 合とほぼ同じ方法でインデックスからデータを読み取ることができます。セカンダリインデックスを 使用することで、アプリケーションはプライマリキー値によりデータにアクセスできるだけでなく、 多数の異なるクエリパターンを使用できます。 詳細については、『Amazon DynamoDB 開発者ガイド』の「Amazon DynamoDB: 仕組み」を参照し てください。 API Version 2012-08-10 2 Amazon DynamoDB 入門ガイド コンピュータでの DynamoDB の実行 コンピュータでの DynamoDB の実行 Amazon DynamoDB ウェブサービスに加えて、AWS はローカルで実行できる DynamoDB のダウン ロード可能バージョンを提供します。 これにより、Amazon DynamoDB ウェブサービスにアクセスせ ずに、アプリケーションを記述できます。 代わりに、データベースはコンピュータ上で自己完結型と なります。 このローカルバージョンの DynamoDB により、プロビジョニングされたスループット、データスト レージ、およびデータ転送料金を節約できます。 また、アプリケーションを開発している間インター ネットに接続しておく必要はありません。 ただし、本稼働環境でアプリケーションをデプロイする場合、Amazon DynamoDB ウェブサービスを 使用できるように簡単な調整を加えることができます。各言語固有のチュートリアルの概要セクショ ンでは、これを実行する方法を説明します。 トピック • DynamoDB (ダウンロード可能バージョン) と DynamoDB ウェブサービス (p. 3) • DynamoDB のダウンロードと実行 (p. 4) DynamoDB (ダウンロード可能バージョン) と DynamoDB ウェブサービス ダウンロード可能バージョンの DynamoDB は、開発とテストの目的専用です。これに対し て、DynamoDB は拡張性、可用性、耐久性を特長とする本稼働環境用に最適なマネージド型サービス です。以下の表は、ご使用のコンピューターで実行する DynamoDB と Amazon DynamoDB サービス のその他の主な相違点です。 DynamoDB (ダウンロード可能 バージョン) Amazon DynamoDB (ウェブ サービス) テーブルの作成 テーブルは、すぐに作成されま す。 プロビジョニング済みスルー プットの設定によっては、テー ブルの作成に多少の時間がかか ります。DynamoDB は、指定さ れた読み取り/書き込みキャパシ ティーを満たす十分なリソース を割り当てます。 プロビジョニングされたスルー プット ダウンロード可能バージョンの DynamoDB では、プロビジョ ニング済みスループット設定は 無視されます。 プロビジョニング済みスルー プットは、DynamoDB の基 本的な概念です。データの読 み取り/書き込み速度は、プロ ビジョニング済みのキャパシ ティーの設定によって異なりま す。詳細については、Amazon DynamoDB 開発者ガイドの 「Amazon DynamoDB のプロ ビジョニングされたスループッ ト」を参照してください。 データの読み取りと書き込み 読み取り/書き込みは、ネット ワークオーバーヘッドなしで、 できる限り高速で実行されま す。 読み取り/書き込みアクティビ ティはテーブルのプロビジョ ニング済みスループット設定に よって規制されます。最大ス ループットを増やすには、テー API Version 2012-08-10 3 Amazon DynamoDB 入門ガイド DynamoDB のダウンロードと実行 DynamoDB (ダウンロード可能 バージョン) Amazon DynamoDB (ウェブ サービス) ブルのスループット設定を増や す必要があります。ネットワー クレイテンシーも、スループッ トに影響が及びます。 テーブルの削除 テーブルはすぐに削除されま す。 DynamoDB がテーブルに使用さ れていたリソースを解放するた め、テーブルの削除には多少の 時間がかかります。 詳細については、Amazon DynamoDB 開発者ガイドの「ローカルで実行される DynamoDB と Amazon DynamoDB ウェブサービスの違い」を参照してください。 DynamoDB のダウンロードと実行 DynamoDB は、実行可能な .jar ファイルとして入手できます。Windows、Linux、Mac OS X、およ び Java をサポートする他のプラットフォームで動作します。以下のステップに従って DynamoDB を コンピューターにダウンロードして実行します。 1. 以下のいずれかのリンクを使用して、無料で DynamoDB をダウンロードします。 • .tar.gz 形式: https://s3-us-west-2.amazonaws.com/dynamodb-local/dynamodb_local_latest.tar.gz • .zip 形式: https://s3-us-west-2.amazonaws.com/dynamodb-local/dynamodb_local_latest.zip Important ダウンロード可能バージョンの DynamoDB を他の場所で入手できる場合もありますが、 最新バージョンであることは保証されません。確実に最新バージョンを入手するには、 これらのいずれかのリンクを使用します。 DynamoDB は、Java Runtime Environment (JRE) バージョン 6.x 以降をサポートしま す。それよりも古い JRE バージョンでは動作しません。 2. ダウンロードしたアーカイブの内容を抽出し、抽出されたディレクトリを任意の場所にコピーし ます。 3. DynamoDB を開始するには、コマンドプロンプトウィンドウを開き、DynamoDBLocal.jar を抽 出したディレクトリに移動し、次のコマンドを入力します。 java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar sharedDb -inMemory Note DynamoDB は、デフォルトではポート 8000 を使用します。ポート 8000 を使用できない 場合、このコマンドにより例外がスローされます。DynamoDB ランタイムオプション (port) の詳細なリストを表示するには、次のコマンドを入力します。 java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -help 詳細については、Amazon DynamoDB 開発者ガイドの「コマンドラインオプション」を 参照してください。 4. これでアプリケーションの書き込みを開始できます。 API Version 2012-08-10 4 Amazon DynamoDB 入門ガイド DynamoDB のダウンロードと実行 次のステップ 次のチュートリアルの 1 つを実行します。 • Java と DynamoDB (p. 6) • JavaScript と DynamoDB (p. 25) • Node.js と DynamoDB (p. 50) • .NET と DynamoDB (p. 67) • PHP および DynamoDB (p. 97) • Python および DynamoDB (p. 117) • Ruby および DynamoDB (p. 134) AWS SDK は、さまざまな言語で利用できます。詳細なリストについては、「Tools for Amazon Web Services」を参照してください。 API Version 2012-08-10 5 Amazon DynamoDB 入門ガイド 前提条件 Java と DynamoDB このチュートリアルでは、AWS SDK for Java を使用して次の Amazon DynamoDB オペレーションを 実行するシンプルなプログラムを作成します。 • Movies というテーブルを作成し、JSON形式のサンプルデータをロードします。 • テーブルで、作成、読み込み、更新、削除のオペレーションを実行します。 • 簡単なクエリを実行します。 SDK for Java は、異なるユースケースで使用できるいくつかのプログラムモデルを提供しています。 この演習では、Java コードが使用するドキュメントモデルによって、JSON ドキュメントの扱いが容 易になる抽象化レベルが提供されます。 このチュートリアルでは、ダウンロード可能なバージョンの DynamoDB を使用します。概 要 (p. 24) では、DynamoDB ウェブサービスに対して同じコードを実行する方法について説明しま す。 参加費: 無料 前提条件 • Read DynamoDB の概念について (p. 1). • DynamoDB をダウンロードしてコンピュータで実行します。詳細については、「DynamoDB の ダウンロードと実行 (p. 4)」を参照してください。DynamoDB (ダウンロード可能バージョン) は、AWS Toolkit for Eclipse の一部としても入手できます。詳細については、「AWS Toolkit for Eclipse」を参照してください。 • Amazon Web Services にサインアップし、アクセスキーを作成します。AWS SDK を使用するに は、これらの認証情報が必要です。AWS アカウントを作成するには、https://aws.amazon.com/ に アクセスし、[Create an AWS Account] を選択して、オンラインの手順に従います。 • AWS SDK for Java のセットアップ: • Java 開発環境をインストールします。Eclipse IDE を使用している場合、AWS Toolkit for Eclipse をインストールします。 • AWS SDK for Java をインストールします。 • SDK for Java で使用する AWS 認証情報をセットアップします。 手順については、『AWS SDK for Java Developer Guide』の「使用開始」を参照してください。 API Version 2012-08-10 6 Amazon DynamoDB 入門ガイド ステップ 1: テーブルを作成する Tip このチュートリアルを行うときは、「AWS SDK for Java API Reference」を参照できます。 ステップ 1: テーブルを作成する このステップでは、Movies という名前のテーブルを作成します。テーブルのプライマリキーは、以 下の属性で構成されます。 • year – パーティションキー。ScalarAttributeType は、数字 (number) の N です。 • title – ソートキー。ScalarAttributeType は、文字列 (string) の S です。 1. Java 開発環境に次のプログラムをコピーします。 // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import java.util.Arrays; import import import import import import import import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.model.AttributeDefinition; com.amazonaws.services.dynamodbv2.model.KeySchemaElement; com.amazonaws.services.dynamodbv2.model.KeyType; com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; com.amazonaws.services.dynamodbv2.model.ScalarAttributeType; public class MoviesCreateTable { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); String tableName = "Movies"; try { System.out.println("Attempting to create table; please wait..."); Table table = dynamoDB.createTable(tableName, Arrays.asList( new KeySchemaElement("year", KeyType.HASH), // Partition key new KeySchemaElement("title", KeyType.RANGE)), //Sort key Arrays.asList( new AttributeDefinition("year", ScalarAttributeType.N), new AttributeDefinition("title", ScalarAttributeType.S)), API Version 2012-08-10 7 Amazon DynamoDB 入門ガイド ステップ 2: サンプルデータをロードする new ProvisionedThroughput(10L, 10L)); table.waitForActive(); System.out.println("Success. Table status: " + table.getDescription().getTableStatus()); } catch (Exception e) { System.err.println("Unable to create table: "); System.err.println(e.getMessage()); } } } Note • エンドポイントを設定して、コンピュータの DynamoDB にテーブルを作成することを 示します。 • createTable 呼び出しでは、テーブル名、プライマリキー属性、そのデータ型を指定 します。 • ProvisionedThroughput パラメーターは必須ですが、ダウンロード可能なバージョ ンの DynamoDB では無視されます。(プロビジョニングされたスループットはこの演 習では扱いません。) 2. コンパイルして、プログラムを実行します。 テーブルの管理の詳細については、『Amazon DynamoDB 開発者ガイド』の「テーブルの操作」を参 照してください。 ステップ 2: サンプルデータをロードする このステップでは、Movies テーブルにサンプルデータを入力します。 トピック • ステップ 2.1: サンプルデータファイルをダウンロードする (p. 9) • ステップ 2.2: 映画テーブルにサンプルデータをロードする (p. 9) サンプルデータファイルには、インターネット映画データベース (IMDb) にある数千におよぶ映 画の情報が格納されています。映画データは、次の例に示すように JSON 形式です。映画ごと に、year、title、および info という JSON マップが設定されています。 [ { "year" : ... , "title" : ... , "info" : { ... } }, { "year" : ..., "title" : ..., "info" : { ... } }, ... API Version 2012-08-10 8 Amazon DynamoDB 入門ガイド ステップ 2.1: サンプルデータ ファイルをダウンロードする ] JSON データで次の点に注意してください。 • year と title を、Movies テーブルのプライマリキー属性値として使用します。 • 残りの info 値は、info という単一の属性に保存されます。このプログラムは、JSON を DynamoDB 属性で保存する方法を示しています。 以下は、映画データの例です。 { "year" : 2013, "title" : "Turn It Down, Or Else!", "info" : { "directors" : [ "Alice Smith", "Bob Jones" ], "release_date" : "2013-01-18T00:00:00Z", "rating" : 6.2, "genres" : [ "Comedy", "Drama" ], "image_url" : "http://ia.media-imdb.com/images/N/ O9ERWAU7FS797AJ7LU8HN09AMUP908RLlo5JF90EWR7LJKQ7@@._V1_SX400_.jpg", "plot" : "A rock band plays their music at high volumes, annoying the neighbors.", "rank" : 11, "running_time_secs" : 5215, "actors" : [ "David Matthewman", "Ann Thomas", "Jonathan G. Neff" ] } } ステップ 2.1: サンプルデータファイルをダウンロー ドする 1. リンク moviedata.zip をクリックして、サンプルデータアーカイブをダウンロードします。 2. アーカイブからデータファイル (moviedata.json) を抽出します。 3. 現在のディレクトリに moviedata.json ファイルをコピーします。 ステップ 2.2: 映画テーブルにサンプルデータをロー ドする サンプルデータをダウンロードすると、次のプログラムを実行して Movies テーブルに入力できま す。 API Version 2012-08-10 9 Amazon DynamoDB 入門ガイド ステップ 2.2: 映画テーブルに サンプルデータをロードする 1. Java 開発環境に次のプログラムをコピーします。 // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import java.io.File; import java.util.Iterator; import import import import import import import import import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.Table; com.fasterxml.jackson.core.JsonFactory; com.fasterxml.jackson.core.JsonParser; com.fasterxml.jackson.databind.JsonNode; com.fasterxml.jackson.databind.ObjectMapper; com.fasterxml.jackson.databind.node.ObjectNode; public class MoviesLoadData { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Movies"); JsonParser parser = new JsonFactory() .createParser(new File("moviedata.json")); JsonNode rootNode = new ObjectMapper().readTree(parser); Iterator<JsonNode> iter = rootNode.iterator(); ObjectNode currentNode; while (iter.hasNext()) { currentNode = (ObjectNode) iter.next(); int year = currentNode.path("year").asInt(); String title = currentNode.path("title").asText(); try { table.putItem(new Item() .withPrimaryKey("year", year, "title", title) .withJSON("info", currentNode.path("info").toString())); System.out.println("PutItem succeeded: " + year + " " + title); } catch (Exception e) { System.err.println("Unable to add movie: " + year + " " + title); System.err.println(e.getMessage()); break; API Version 2012-08-10 10 Amazon DynamoDB 入門ガイド ステップ 3: 項目を作成、読み込み、更新、削除する } } parser.close(); } } 2. このプログラムでは JSON の処理にオープンソースの Jackson ライブラリを使用しま す。Jackson は AWS SDK for Java に含まれます。別途インストールする必要はありません。 コンパイルして、プログラムを実行します。 ステップ 3: 項目を作成、読み込み、更新、削除 する このステップでは、Movies テーブルの項目で読み取り/書き込みオペレーションを実行します。 データの読み取りと書き込みの詳細については、『Amazon DynamoDB 開発者ガイド』の「項目の操 作」を参照してください。 トピック • ステップ 3.1: 新しい項目を作成する (p. 11) • ステップ 3.2: 項目を読み取る (p. 12) • ステップ 3.3: 項目を更新する (p. 13) • ステップ 3.4: アトミックカウンターを増分する (p. 15) • ステップ 3.5: 項目を更新する (条件付き) (p. 16) • ステップ 3.6: 項目を削除する (p. 18) ステップ 3.1: 新しい項目を作成する このステップでは、Movies テーブルに新しい項目を追加します。 1. Java 開発環境に次のプログラムをコピーします。 // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import java.util.HashMap; import java.util.Map; import import import import import import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.PrimaryKey; com.amazonaws.services.dynamodbv2.document.PutItemOutcome; com.amazonaws.services.dynamodbv2.document.Table; public class MoviesItemOps01 { public static void main(String[] args) throws Exception { API Version 2012-08-10 11 Amazon DynamoDB 入門ガイド ステップ 3.2: 項目を読み取る AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Movies"); int year = 2015; String title = "The Big New Movie"; final Map<String, Object> infoMap = new HashMap<String, Object>(); infoMap.put("plot", "Nothing happens at all."); infoMap.put("rating", 0); try { System.out.println("Adding a new item..."); PutItemOutcome outcome = table.putItem(new Item() .withPrimaryKey("year", year, "title", title) .withMap("info", infoMap)); System.out.println("PutItem succeeded:\n" + outcome.getPutItemResult()); } catch (Exception e) { System.err.println("Unable to add item: " + year + " " + title); System.err.println(e.getMessage()); } } } Note プライマリキーは必須です。このコードは、プライマリキー (year、title) と info 属 性を持つ項目を追加します。info 属性には、映画についての詳細情報を示すサンプル JSON が保存されます。 2. コンパイルして、プログラムを実行します。 ステップ 3.2: 項目を読み取る 前のプログラムでは、テーブルに次の項目を追加しました。 { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } Movies テーブルから項目を読み取る、getItem メソッドを使用できます。 プライマリキー値を指定 する必要があります。そうすると year と title がわかれば、Movies から項目を読み込むことがで きます。 API Version 2012-08-10 12 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する 1. Java 開発環境に次のプログラムをコピーします。 // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import import import import import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.spec.GetItemSpec; public class MoviesItemOps02 { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Movies"); int year = 2015; String title = "The Big New Movie"; GetItemSpec spec = new GetItemSpec() .withPrimaryKey("year", year, "title", title); try { System.out.println("Attempting to read the item..."); Item outcome = table.getItem(spec); System.out.println("GetItem succeeded: " + outcome); } catch (Exception e) { System.err.println("Unable to read item: " + year + " " + title); System.err.println(e.getMessage()); } } } 2. コンパイルして、プログラムを実行します。 ステップ 3.3: 項目を更新する updateItem メソッドを使用して既存の項目を変更できます。既存の属性の値の更新、新しい属性の 追加、または属性の削除を行えます。 このチュートリアルでは、次の更新を行います。 • 既存の属性の値を変更します (rating、plot)。 • 新しいリスト属性 (actors) を既存の info マップに追加します。 API Version 2012-08-10 13 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する 項目の変更前: { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } 項目の変更後: { year: 2015, title: "The Big New Movie", info: { plot: "Everything happens all at once.", rating: 5.5, actors: ["Larry", "Moe", "Curly"] } } 1. Java 開発環境に次のプログラムをコピーします。 // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import java.util.Arrays; import import import import import import import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.UpdateItemOutcome; com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec; com.amazonaws.services.dynamodbv2.document.utils.ValueMap; com.amazonaws.services.dynamodbv2.model.ReturnValue; public class MoviesItemOps03 { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Movies"); int year = 2015; String title = "The Big New Movie"; UpdateItemSpec updateItemSpec = new UpdateItemSpec() .withPrimaryKey("year", year, "title", title) API Version 2012-08-10 14 Amazon DynamoDB 入門ガイド ステップ 3.4: アトミックカウンターを増分する .withUpdateExpression("set info.rating = :r, info.plot=:p, info.actors=:a") .withValueMap(new ValueMap() .withNumber(":r", 5.5) .withString(":p", "Everything happens all at once.") .withList(":a", Arrays.asList("Larry","Moe","Curly"))) .withReturnValues(ReturnValue.UPDATED_NEW); try { System.out.println("Updating the item..."); UpdateItemOutcome outcome = table.updateItem(updateItemSpec); System.out.println("UpdateItem succeeded:\n" + outcome.getItem().toJSONPretty()); } catch (Exception e) { System.err.println("Unable to update item: " + year + " " + title); System.err.println(e.getMessage()); } } } Note このプログラムでは、UpdateExpression を使用して、指定された項目で実行するすべ ての更新を記述します。 ReturnValues パラメーターは、DynamoDB に更新された属性 (UPDATED_NEW) のみを 返すように指示します。 2. コンパイルして、プログラムを実行します。 ステップ 3.4: アトミックカウンターを増分する DynamoDB では、アトミックカウンターがサポートされています。そのため、updateItem メソッド を使用して、他の書き込みリクエストを妨げることなく既存の属性値をインクリメントまたはデクリ メントできます。(すべての書き込みリクエストは、受信された順に適用されます)。 次のプログラムは、映画の rating を増分する方法を示しています。実行するたびに、プログラムは この属性を 1 つ増分します。 1. Java 開発環境に次のプログラムをコピーします。 // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import import import import import import import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.UpdateItemOutcome; com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec; com.amazonaws.services.dynamodbv2.document.utils.ValueMap; com.amazonaws.services.dynamodbv2.model.ReturnValue; public class MoviesItemOps04 { API Version 2012-08-10 15 Amazon DynamoDB 入門ガイド ステップ 3.5: 項目を更新する (条件付き) public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Movies"); int year = 2015; String title = "The Big New Movie"; UpdateItemSpec updateItemSpec = new UpdateItemSpec() .withPrimaryKey("year", year, "title", title) .withUpdateExpression("set info.rating = info.rating + :val") .withValueMap(new ValueMap() .withNumber(":val", 1)) .withReturnValues(ReturnValue.UPDATED_NEW); try { System.out.println("Incrementing an atomic counter..."); UpdateItemOutcome outcome = table.updateItem(updateItemSpec); System.out.println("UpdateItem succeeded:\n" + outcome.getItem().toJSONPretty()); } catch (Exception e) { System.err.println("Unable to update item: " + year + " " + title); System.err.println(e.getMessage()); } } } 2. コンパイルして、プログラムを実行します。 ステップ 3.5: 項目を更新する (条件付き) 次のプログラムは、条件とともに UpdateItem を使用する方法を示しています。条件が true と評価 された場合、更新は成功します。それ以外の場合、更新は行われません。 その場合、映画項目は 3 人より多い役者がいる場合にのみ更新されます。 1. Java 開発環境に次のプログラムをコピーします。 // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import import import import import import import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.PrimaryKey; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.UpdateItemOutcome; com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec; com.amazonaws.services.dynamodbv2.document.utils.ValueMap; API Version 2012-08-10 16 Amazon DynamoDB 入門ガイド ステップ 3.5: 項目を更新する (条件付き) import com.amazonaws.services.dynamodbv2.model.ReturnValue; public class MoviesItemOps05 { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Movies"); int year = 2015; String title = "The Big New Movie"; UpdateItemSpec updateItemSpec = new UpdateItemSpec() .withPrimaryKey(new PrimaryKey("year", year, "title", title)) .withUpdateExpression("remove info.actors[0]") .withConditionExpression("size(info.actors) > :num") .withValueMap(new ValueMap().withNumber(":num", 3)) .withReturnValues(ReturnValue.UPDATED_NEW); // Conditional update (we expect this to fail) try { System.out.println("Attempting a conditional update..."); UpdateItemOutcome outcome = table.updateItem(updateItemSpec); System.out.println("UpdateItem succeeded:\n" + outcome.getItem().toJSONPretty()); } catch (Exception e) { System.err.println("Unable to update item: " + year + " " + title); System.err.println(e.getMessage()); } } } 2. コンパイルして、プログラムを実行します。 プログラムは次のメッセージで失敗するはずです。 The conditional request failed これは、映画に 3 人の役者が出演しているが、条件は役者が 3 人より多いことをチェックしてい るためです。 3. ConditionExpression が次のようになるようにプログラムを変更します。 .withConditionExpression("size(info.actors) >= :num") 条件が、3 より大きいではなく 3 以上になりました。 4. コンパイルして、プログラムを実行します。これで、UpdateItem オペレーションが成功しま す。 API Version 2012-08-10 17 Amazon DynamoDB 入門ガイド ステップ 3.6: 項目を削除する ステップ 3.6: 項目を削除する プライマリキーを指定することで、deleteItem メソッドを使用して 1 つの項目を削除できます。オ プションで ConditionExpression を指定して、条件を満たさない場合に項目の削除を防ぐことが できます。 次の例では、レーティングが 5 以下の特定の映画項目を削除しようとします。 1. Java 開発環境に次のプログラムをコピーします。 // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import import import import import import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.PrimaryKey; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.spec.DeleteItemSpec; com.amazonaws.services.dynamodbv2.document.utils.ValueMap; public class MoviesItemOps06 { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Movies"); int year = 2015; String title = "The Big New Movie"; DeleteItemSpec deleteItemSpec = new DeleteItemSpec() .withPrimaryKey(new PrimaryKey("year", year, "title", title)) .withConditionExpression("info.rating <= :val") .withValueMap(new ValueMap() .withNumber(":val", 5.0)); // Conditional delete (we expect this to fail) try { System.out.println("Attempting a conditional delete..."); table.deleteItem(deleteItemSpec); System.out.println("DeleteItem succeeded"); } catch (Exception e) { System.err.println("Unable to delete item: " + year + " " + title); System.err.println(e.getMessage()); } } } 2. コンパイルして、プログラムを実行します。 API Version 2012-08-10 18 Amazon DynamoDB 入門ガイド ステップ 4: データをクエリおよびスキャンする プログラムは次のメッセージで失敗するはずです。 The conditional request failed これは、この特定の映画のレーティングが 5 より大きいためです。 3. DeleteItemSpec で条件を削除するようにプログラムを変更します。 DeleteItemSpec deleteItemSpec = new DeleteItemSpec() .withPrimaryKey(new PrimaryKey("year", 2015, "title", "The Big New Movie")); 4. コンパイルして、プログラムを実行します。ここでは、条件を削除したため、削除が成功しま す。 ステップ 4: データをクエリおよびスキャンする query メソッドを使用して、テーブルからデータを取得できます。パーティションのキー値を指定す る必要があります。ソートキーはオプションです。 Movies テーブルのプライマリキーは、以下の内容で構成されます。 • year – パーティションキー。属性タイプは数値です。 • title – ソートキー。属性タイプは文字列です。 1 年間にリリースされたすべての映画を検索するには、year のみ指定する必要があります。title を指定して、いくつかの条件 (ソートキー上) に基づいて映画のサブセットを取得することもできま す。たとえば、2014 年にリリースされて、主題が「A」で始まる映画を探す場合です。 query に加えて、すべてのテーブルデータを取得可能な scan メソッドもあります。 データのクエリとスキャンの詳細については、『Amazon DynamoDB 開発者ガイド』の「クエリおよ びスキャン」を参照してください。 トピック • ステップ 4.1: クエリ (p. 19) • ステップ 4.2: スキャン (p. 21) ステップ 4.1: クエリ このステップに含まれているコードは、以下のクエリを実行します。 • year 1985 にリリースされたすべての映画を取得します。 • year 1992 にリリースされたすべての映画で、title が「A」から「L」で始まるすべての映画を取 得します。 1. Java 開発環境に次のプログラムをコピーします。 // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; API Version 2012-08-10 19 Amazon DynamoDB 入門ガイド ステップ 4.1: クエリ import java.util.HashMap; import java.util.Iterator; import import import import import import import import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.ItemCollection; com.amazonaws.services.dynamodbv2.document.QueryOutcome; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.spec.QuerySpec; com.amazonaws.services.dynamodbv2.document.utils.NameMap; public class MoviesQuery { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Movies"); HashMap<String, String> nameMap = new HashMap<String, String>(); nameMap.put("#yr", "year"); HashMap<String, Object> valueMap = new HashMap<String, Object>(); valueMap.put(":yyyy", 1985); QuerySpec querySpec = new QuerySpec() .withKeyConditionExpression("#yr = :yyyy") .withNameMap(nameMap) .withValueMap(valueMap); ItemCollection<QueryOutcome> items = null; Iterator<Item> iterator = null; Item item = null; try { System.out.println("Movies from 1985"); items = table.query(querySpec); iterator = items.iterator(); while (iterator.hasNext()) { item = iterator.next(); System.out.println(item.getNumber("year") + ": " + item.getString("title")); } } catch (Exception e) { System.err.println("Unable to query movies from 1985"); System.err.println(e.getMessage()); } valueMap.put(":yyyy", 1992); valueMap.put(":letter1", "A"); valueMap.put(":letter2", "L"); querySpec API Version 2012-08-10 20 Amazon DynamoDB 入門ガイド ステップ 4.2: スキャン .withProjectionExpression( "#yr, title, info.genres, info.actors[0]") .withKeyConditionExpression( "#yr = :yyyy and title between :letter1 and :letter2") .withNameMap(nameMap).withValueMap(valueMap); try { System.out .println("Movies from 1992 - titles A-L, with genres and lead actor"); items = table.query(querySpec); iterator = items.iterator(); while (iterator.hasNext()) { item = iterator.next(); System.out.println(item.getNumber("year") + ": " + item.getString("title") + " " + item.getMap("info")); } } catch (Exception e) { System.err.println("Unable to query movies from 1992:"); System.err.println(e.getMessage()); } } } Note • nameMap は、名前を置換します。year は DynamoDB の予約語であるため、これが使 用されます。KeyConditionExpression を含むどの式でも直接使用することはでき ません。これに対処するため、式の属性名 #yr が使用されます。 • valueMap は、値を置換します。KeyConditionExpression を含むどの式にもリ テラルを使用できないため、これが使用されます。これに対処するため、式の属性値 :yyyy が使用されます。 まず、クエリパラメーターを説明する querySpec オブジェクトを作成してから、オブジェクト を query メソッドに受け渡します。 2. コンパイルして、プログラムを実行します。 Note 前のプログラムは、プライマリキーの属性によってテーブルをクエリする方法を示していま す。DynamoDB では、必要に応じて 1 つ以上のセカンダリインデックスをテーブルに作成 し、テーブルをクエリするのと同じ方法でそれらのインデックスをクエリできます。セカン ダリインデックスは非キー属性のクエリを可能にすることで、アプリケーションに追加の柔 軟性を提供します。詳細については、Amazon DynamoDB 開発者ガイドの「セカンダリイン デックス」を参照してください。 ステップ 4.2: スキャン scan メソッドは、テーブル全体のすべての項目を読み込み、テーブルの全データを返します。オプ ションで filter_expression を提供して、条件に一致する項目だけが返されるように指定できま API Version 2012-08-10 21 Amazon DynamoDB 入門ガイド ステップ 4.2: スキャン す。ただし、テーブル全体がスキャンされた後にのみ、フィルタが適用されることに注意してくださ い。 次のプログラムは、約 5,000 項目を含む Movies テーブル全体をスキャンします。スキャンは、1950 年代の映画のみ (約 100 項目) を取得して、残りはすべて破棄するようオプションのフィルタを指定し ます。 1. Java 開発環境に次のプログラムをコピーします。 // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import java.util.Iterator; import import import import import import import import import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.ItemCollection; com.amazonaws.services.dynamodbv2.document.ScanOutcome; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.spec.ScanSpec; com.amazonaws.services.dynamodbv2.document.utils.NameMap; com.amazonaws.services.dynamodbv2.document.utils.ValueMap; public class MoviesScan { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Movies"); ScanSpec scanSpec = new ScanSpec() .withProjectionExpression("#yr, title, info.rating") .withFilterExpression("#yr between :start_yr and :end_yr") .withNameMap(new NameMap().with("#yr", "year")) .withValueMap(new ValueMap().withNumber(":start_yr", 1950).withNumber(":end_yr", 1959)); try { ItemCollection<ScanOutcome> items = table.scan(scanSpec); Iterator<Item> iter = items.iterator(); while (iter.hasNext()) { Item item = iter.next(); System.out.println(item.toString()); } } catch (Exception e) { System.err.println("Unable to scan the table:"); System.err.println(e.getMessage()); } } API Version 2012-08-10 22 Amazon DynamoDB 入門ガイド ステップ 5: (オプション) テーブルを削除する } このコードでは、以下の点に注意してください。 • ProjectionExpression は、スキャン結果に必要な属性を指定します。 • FilterExpression は、条件を満たした項目だけが返されるような条件を指定します。他の すべての項目は破棄されます。 2. コンパイルして、プログラムを実行します。 Note テーブルで作成した任意のセカンダリインデックスで Scan オペレーションを使用すること もできます。詳細については、Amazon DynamoDB 開発者ガイドの「セカンダリインデック ス」を参照してください。 ステップ 5: (オプション) テーブルを削除する Movies テーブルを削除するには: 1. Java 開発環境に次のプログラムをコピーします。 // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.document.DynamoDB; import com.amazonaws.services.dynamodbv2.document.Table; public class MoviesDeleteTable { public static void main(String[] args) throws Exception { AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); DynamoDB dynamoDB = new DynamoDB(client); Table table = dynamoDB.getTable("Movies"); try { System.out.println("Attempting to delete table; please wait..."); table.delete(); table.waitForDelete(); System.out.print("Success."); } catch (Exception e) { System.err.println("Unable to delete table: "); System.err.println(e.getMessage()); } } } API Version 2012-08-10 23 Amazon DynamoDB 入門ガイド 概要 2. コンパイルして、プログラムを実行します。 概要 このチュートリアルでは、ご使用のコンピューターの DynamoDB で Movies テーブルを作成し、 基本的なオペレーションを実行しました。ダウンロード可能なバージョンの DynamoDB は、アプリ ケーションの開発およびテストの際に便利です。ただし、本番環境でアプリケーションを実行する場 合、Amazon DynamoDB ウェブサービスを使用できるようにコードを変更します。 Amazon DynamoDB サービスを使用する Amazon DynamoDB サービスを使用するには、アプリケーションのエンドポイントを変更する必要が あります。これを行うには、プログラムに次のインポートステートメントを追加します。 import com.amazonaws.regions.Regions; 次に、コードの AmazonDynamoDBClient を参照します。 AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withEndpoint("http://localhost:8000"); そして、特定のエンドポイントではなく、AWS リージョンにアクセスするようクライアントを変更し ます。 AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withRegion(Regions.REGION); たとえば、us-west-2 region にアクセスする場合、次のようにします。 AmazonDynamoDBClient client = new AmazonDynamoDBClient() .withRegion(Regions.US_WEST_2); プログラムはコンピュータで DynamoDB を使用する代わりに、米国西部 (オレゴン) で Amazon DynamoDB ウェブサービスエンドポイントを使用します。 Amazon DynamoDB は、世界中の AWS リージョンで利用できます。完全なリストについては、AWS General Referenceの「リージョンとエンドポイント」を参照してください。コードにリージョンお よびエンドポイントを設定するための詳細については、『AWS SDK for Java Developer Guide』の 「AWS リージョンの選択」を参照してください。 最後に、「Amazon DynamoDB 開発者ガイド」を読むことをお勧めします。ここには、サンプルコー ドやベストプラクティスなど、DynamoDB に関するさらに詳しい情報が収められています。 API Version 2012-08-10 24 Amazon DynamoDB 入門ガイド 前提条件 JavaScript と DynamoDB このチュートリアルでは、JavaScript を使用して次の Amazon DynamoDB オペレーションを実行する シンプルなプログラムを作成します。 • Movies というテーブルを作成し、JSON形式のサンプルデータをロードします。 • テーブルで、作成、読み込み、更新、削除のオペレーションを実行します。 • 簡単なクエリを実行します。 このチュートリアルでは、ダウンロード可能なバージョンの DynamoDB を使用します。概 要 (p. 46) では、DynamoDB ウェブサービスに対して同じコードを実行する方法について説明しま す。 参加費: 無料 前提条件 • Read DynamoDB の概念について (p. 1). • DynamoDB をダウンロードしてコンピュータで実行します。詳細については、「DynamoDB のダ ウンロードと実行 (p. 4)」を参照してください。 • AWS SDK for JavaScript をセットアップします。これを行うには、HTML ページに以下のスクリプ トタグを追加または変更します。 <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js"></script> Note AWS SDK for JavaScript のバージョンは更新されている場合があります。最新バージョン については、AWS SDK for JavaScript API Referenceを参照してください。 • CORS (Cross-Origin Resource Sharing) を有効にして、コンピュータのブラウザとダウンロード可 能なバージョンの DynamoDB 間の通信が発生できるようにします。 これを行い、コンピュータでチュートリアルを実行するには: 1. 無料の ModHeader Chrome ブラウザ拡張機能 (または HTTP レスポンスヘッダーを変更できる その他のブラウザ拡張機能) をダウンロードします。 2. ModHeader Chrome ブラウザ拡張機能を実行し、名前を「Access-Control-Allow-Origin」、値 を「null」または「*」に設定して、HTTP レスポンスヘッダーを追加します。 API Version 2012-08-10 25 Amazon DynamoDB 入門ガイド ステップ 1: テーブルを作成する Important この設定は、コンピュータで JavaScript のチュートリアルプログラムを実行するとき のみ必要です。チュートリアルを終了したら、この設定を無効にするか、削除してく ださい。 3. これで、JavaScript チュートリアルプログラムファイルを実行できます。 このチュートリアルを行うときは、『AWS SDK for JavaScript API Reference』を参照できます。 手順を実行する代わりに完全なバージョンの JavaScript チュートリアルを実行する場合は、以下の操 作を行います。 1. MoviesJavaScript.zip ファイルをダウンロードします。 2. アーカイブから MoviesJavaScript.html ファイルを抽出します。 3. エンドポイントを使用するよう MoviesJavaScript.html ファイルを変更します。 4. MoviesJavaScript.html ファイルを実行します。 ステップ 1: テーブルを作成する このステップでは、Movies という名前のテーブルを作成します。テーブルのプライマリキーは、以 下の属性で構成されます。 • year – パーティションキー。AttributeType は、数字 (number) の N です。 • title – ソートキー。AttributeType は、文字列 (string) の S です。 1. 次のプログラムを MoviesCreateTable.html というファイルにコピーします。 <html> <head> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js"></script> <script> AWS.config.update({ region: "us-west-2", endpoint: 'http://localhost:8000', // accessKeyId default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. accessKeyId: "fakeMyKeyId", // secretAccessKey default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. secretAccessKey: "fakeSecretAccessKey" }); var dynamodb = new AWS.DynamoDB(); function createMovies() { var params = { TableName : "Movies", KeySchema: [ API Version 2012-08-10 26 Amazon DynamoDB 入門ガイド ステップ 2: サンプルデータをロードする { AttributeName: "year", KeyType: "HASH"}, { AttributeName: "title", KeyType: "RANGE" } ], AttributeDefinitions: [ { AttributeName: "year", AttributeType: "N" }, { AttributeName: "title", AttributeType: "S" } ], ProvisionedThroughput: { ReadCapacityUnits: 5, WriteCapacityUnits: 5 } }; dynamodb.createTable(params, function(err, data) { if (err) { document.getElementById('textarea').innerHTML = "Unable to create table: " + "\n" + JSON.stringify(err, undefined, 2); } else { document.getElementById('textarea').innerHTML = "Created table: " + "\n" + JSON.stringify(data, undefined, 2); } }); } </script> </head> <body> <input id="createTableButton" type="button" value="Create Table" onclick="createMovies();" /> <br><br> <textarea readonly id= "textarea" style="width:400px; height:800px"></ textarea> </body> </html> Note 2. 3. • エンドポイントを設定して、コンピュータの DynamoDB にテーブルを作成することを 示します。 • createMovies 関数では、テーブル名、プライマリキー属性、およびそのデータ型を 指定します。 • ProvisionedThroughput パラメーターは必須ですが、ダウンロード可能なバージョ ンの DynamoDB では無視されます。(プロビジョニングされたスループットはこの チュートリアルでは扱いません。) ブラウザで MoviesCreateTable.html ファイルを開きます。 [Create Table] を選択します。 テーブルの管理の詳細については、『Amazon DynamoDB 開発者ガイド』の「テーブルの操作」を参 照してください。 ステップ 2: サンプルデータをロードする このステップでは、Movies テーブルにサンプルデータを入力します。 API Version 2012-08-10 27 Amazon DynamoDB 入門ガイド ステップ 2: サンプルデータをロードする トピック • ステップ 2.1: サンプルデータファイルをダウンロードする (p. 29) • ステップ 2.2: 映画テーブルにサンプルデータをロードする (p. 29) サンプルデータファイルには、インターネット映画データベース (IMDb) にある数千におよぶ映 画の情報が格納されています。映画データは、次の例に示すように JSON 形式です。映画ごと に、year、title、および info という JSON マップが設定されています。 [ { "year" : ... , "title" : ... , "info" : { ... } }, { "year" : ..., "title" : ..., "info" : { ... } }, ... ] JSON データで次の点に注意してください。 • year と title を、Movies テーブルのプライマリキー属性値として使用します。 • 残りの info 値は、info という単一の属性に保存されます。このプログラムは、JSON を DynamoDB 属性で保存する方法を示しています。 以下は、映画データの例です。 { "year" : 2013, "title" : "Turn It Down, Or Else!", "info" : { "directors" : [ "Alice Smith", "Bob Jones" ], "release_date" : "2013-01-18T00:00:00Z", "rating" : 6.2, "genres" : [ "Comedy", "Drama" ], "image_url" : "http://ia.media-imdb.com/images/N/ O9ERWAU7FS797AJ7LU8HN09AMUP908RLlo5JF90EWR7LJKQ7@@._V1_SX400_.jpg", "plot" : "A rock band plays their music at high volumes, annoying the neighbors.", "rank" : 11, "running_time_secs" : 5215, "actors" : [ "David Matthewman", API Version 2012-08-10 28 Amazon DynamoDB 入門ガイド ステップ 2.1: サンプルデータ ファイルをダウンロードする "Ann Thomas", "Jonathan G. Neff" ] } } ステップ 2.1: サンプルデータファイルをダウンロー ドする 1. moviedata.zip をクリックして、サンプルデータアーカイブをダウンロードします。 2. アーカイブからデータファイル (moviedata.json) を抽出します。 3. 現在のディレクトリに moviedata.json ファイルをコピーします。 ステップ 2.2: 映画テーブルにサンプルデータをロー ドする サンプルデータをダウンロードすると、次のプログラムを実行して Movies テーブルに入力できま す。 1. 次のプログラムを MoviesLoadData.html というファイルにコピーします。 <html> <head> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js"></script> <script type="text/javascript"> AWS.config.update({ region: "us-west-2", endpoint: 'http://localhost:8000', // accessKeyId default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. accessKeyId: "fakeMyKeyId", // secretAccessKey default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. secretAccessKey: "fakeSecretAccessKey" }); var docClient = new AWS.DynamoDB.DocumentClient(); function processFile(evt) { document.getElementById('textarea').innerHTML = ""; document.getElementById('textarea').innerHTML += "Importing movies into DynamoDB. Please wait..." + "\n"; var file = evt.target.files[0]; if (file) { var r = new FileReader(); r.onload = function(e) { var contents = e.target.result; var allMovies = JSON.parse(contents); API Version 2012-08-10 29 Amazon DynamoDB 入門ガイド ステップ 3: 項目を作成、読み込み、更新、削除する allMovies.forEach(function (movie) { document.getElementById('textarea').innerHTML += "Processing: " + movie.title + "\n"; var params = { TableName: "Movies", Item: { "year": movie.year, "title": movie.title, "info": movie.info } }; docClient.put(params, function (err, data) { if (err) { document.getElementById('textarea').innerHTML += "Unable to add movie: " + count + movie.title + "\n"; document.getElementById('textarea').innerHTML += "Error JSON: " + JSON.stringify(err) + "\n"; } else { document.getElementById('textarea').innerHTML += "PutItem succeeded: " + movie.title + "\n"; textarea.scrollTop = textarea.scrollHeight; } }); }); }; r.readAsText(file); } else { alert("Could not read movie data file"); } } </script> </head> <body> <input type="file" id="fileinput" accept='application/json'/> <br><br> <textarea readonly id= "textarea" style="width:400px; height:800px"></ textarea> <script> document.getElementById('fileinput').addEventListener('change', processFile, false); </script> </body> </html> 2. ブラウザで MoviesLoadData.html ファイルを開きます。 3. [Browse] を選択し、moviedata.json ファイルを読み込みます。 ステップ 3: 項目を作成、読み込み、更新、削除 する このステップでは、Movies テーブルの項目で読み取り/書き込みオペレーションを実行します。 API Version 2012-08-10 30 Amazon DynamoDB 入門ガイド ステップ 3.1: 新しい項目を作成する データの読み取りと書き込みの詳細については、『Amazon DynamoDB 開発者ガイド』の「項目の操 作」を参照してください。 トピック • ステップ 3.1: 新しい項目を作成する (p. 31) • ステップ 3.2: 項目を読み取る (p. 32) • ステップ 3.3: 項目を更新する (p. 33) • ステップ 3.4: アトミックカウンターを増分する (p. 35) • ステップ 3.5: 項目を更新する (条件付き) (p. 37) • ステップ 3.6: 項目を削除する (p. 38) ステップ 3.1: 新しい項目を作成する このステップでは、Movies テーブルに新しい項目を追加します。 1. 次のプログラムを MoviesItemOps01.html というファイルにコピーします。 <html> <head> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js"></script> <script> AWS.config.update({ region: "us-west-2", endpoint: 'http://localhost:8000', // accessKeyId default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. accessKeyId: "fakeMyKeyId", // secretAccessKey default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. secretAccessKey: "fakeSecretAccessKey" }); var docClient = new AWS.DynamoDB.DocumentClient(); function createItem() { var params = { TableName :"Movies", Item:{ "year": 2015, "title": "The Big New Movie", "info":{ "plot": "Nothing happens at all.", "rating": 0 } } }; docClient.put(params, function(err, data) { if (err) { document.getElementById('textarea').innerHTML = "Unable to add item: " + "\n" + JSON.stringify(err, undefined, 2); API Version 2012-08-10 31 Amazon DynamoDB 入門ガイド ステップ 3.2: 項目を読み取る } else { document.getElementById('textarea').innerHTML = "PutItem succeeded: " + "\n" + JSON.stringify(data, undefined, 2); } }); } </script> </head> <body> <input id="createItem" type="button" value="Create Item" onclick="createItem();" /> <br><br> <textarea readonly id= "textarea" style="width:400px; height:800px"></ textarea> </body> </html> Note プライマリキーは必須です。このコードは、プライマリキー (year, title) と info 属 性を持つ項目を追加します。info 属性には、映画についての詳細情報を示すサンプル JSON が保存されます。 2. ブラウザで MoviesItemOps01.html ファイルを開きます。 3. [Create Item] を選択します。 ステップ 3.2: 項目を読み取る 前のプログラムでは、テーブルに次の項目を追加しました。 { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } Movies テーブルから項目を読み取る、get メソッドを使用できます。 プライマリキー値を指定する 必要があります。そうすると year と title がわかれば、Movies から項目を読み込むことができま す。 1. 次のプログラムを MoviesItemOps02.html というファイルにコピーします。 <html> <head> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js"></script> <script> AWS.config.update({ region: "us-west-2", endpoint: 'http://localhost:8000', API Version 2012-08-10 32 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する // accessKeyId default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. accessKeyId: "fakeMyKeyId", // secretAccessKey default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. secretAccessKey: "fakeSecretAccessKey" }); var docClient = new AWS.DynamoDB.DocumentClient(); function readItem() { var table = "Movies"; var year = 2015; var title = "The Big New Movie"; var params = { TableName: table, Key:{ "year": year, "title": title } }; docClient.get(params, function(err, data) { if (err) { document.getElementById('textarea').innerHTML = "Unable to read item: " + "\n" + JSON.stringify(err, undefined, 2); } else { document.getElementById('textarea').innerHTML = "GetItem succeeded: " + "\n" + JSON.stringify(data, undefined, 2); } }); } </script> </head> <body> <input id="readItem" type="button" value="Read Item" onclick="readItem();" /> <br><br> <textarea readonly id= "textarea" style="width:400px; height:800px"></ textarea> </body> </html> 2. ブラウザで MoviesItemOps02.html ファイルを開きます。 3. [Read Item] を選択します。 ステップ 3.3: 項目を更新する update メソッドを使用して項目を変更できます。既存の属性の値の更新、新しい属性の追加、また は属性の削除を行えます。 API Version 2012-08-10 33 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する このチュートリアルでは、次の更新を行います。 • 既存の属性の値を変更します (rating、plot)。 • 新しいリスト属性 (actors) を既存の info マップに追加します。 項目の変更前: { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } 項目の変更後: { year: 2015, title: "The Big New Movie", info: { plot: "Everything happens all at once.", rating: 5.5, actors: ["Larry", "Moe", "Curly"] } } 1. 次のプログラムを MoviesItemOps03.html というファイルにコピーします。 <html> <head> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js"></script> <script> AWS.config.update({ region: "us-west-2", endpoint: 'http://localhost:8000', // accessKeyId default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. accessKeyId: "fakeMyKeyId", // secretAccessKey default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. secretAccessKey: "fakeSecretAccessKey" }); var docClient = new AWS.DynamoDB.DocumentClient(); function updateItem() { var table = "Movies"; var year = 2015; var title = "The Big New Movie"; API Version 2012-08-10 34 Amazon DynamoDB 入門ガイド ステップ 3.4: アトミックカウンターを増分する var params = { TableName:table, Key:{ "year": year, "title": title }, UpdateExpression: "set info.rating = :r, info.plot=:p, info.actors=:a", ExpressionAttributeValues:{ ":r":5.5, ":p":"Everything happens all at once.", ":a":["Larry", "Moe", "Curly"] }, ReturnValues:"UPDATED_NEW" }; docClient.update(params, function(err, data) { if (err) { document.getElementById('textarea').innerHTML = "Unable to update item: " + "\n" + JSON.stringify(err, undefined, 2); } else { document.getElementById('textarea').innerHTML = "UpdateItem succeeded: " + "\n" + JSON.stringify(data, undefined, 2); } }); } </script> </head> <body> <input id="updateItem" type="button" value="Update Item" onclick="updateItem();" /> <br><br> <textarea readonly id= "textarea" style="width:400px; height:800px"></ textarea> </body> </html> Note このプログラムでは、UpdateExpression を使用して、指定された項目で実行するすべ ての更新を記述します。 ReturnValues パラメーターは、DynamoDB に更新された属性 ("UPDATED_NEW") のみ を返すように指示します。 2. ブラウザで MoviesItemOps03.html ファイルを開きます。 3. [Update Item] を選択します。 ステップ 3.4: アトミックカウンターを増分する DynamoDB では、アトミックカウンターがサポートされています。そのため、update メソッドを使 用して、他の書き込みリクエストを妨げることなく属性値をインクリメントまたはデクリメントでき ます。(すべての書き込みリクエストは、受信された順に適用されます)。 API Version 2012-08-10 35 Amazon DynamoDB 入門ガイド ステップ 3.4: アトミックカウンターを増分する 次のプログラムは、映画の rating を増分する方法を示しています。実行するたびに、プログラムは この属性を 1 つ増分します。 1. 次のプログラムを MoviesItemOps04.html というファイルにコピーします。 <html> <head> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js"></script> <script> AWS.config.update({ region: "us-west-2", endpoint: 'http://localhost:8000', // accessKeyId default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. accessKeyId: "fakeMyKeyId", // secretAccessKey default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. secretAccessKey: "fakeSecretAccessKey" }); var docClient = new AWS.DynamoDB.DocumentClient(); function increaseRating() { var table = "Movies"; var year = 2015; var title = "The Big New Movie"; var params = { TableName:table, Key:{ "year": year, "title": title }, UpdateExpression: "set info.rating = info.rating + :val", ExpressionAttributeValues:{ ":val":1 }, ReturnValues:"UPDATED_NEW" }; docClient.update(params, function(err, data) { if (err) { document.getElementById('textarea').innerHTML = "Unable to update rating: " + "\n" + JSON.stringify(err, undefined, 2); } else { document.getElementById('textarea').innerHTML = "Increase Rating succeeded: " + "\n" + JSON.stringify(data, undefined, 2); } }); } </script> </head> API Version 2012-08-10 36 Amazon DynamoDB 入門ガイド ステップ 3.5: 項目を更新する (条件付き) <body> <input id="increaseRating" type="button" value="Increase Rating" onclick="increaseRating();" /> <br><br> <textarea readonly id= "textarea" style="width:400px; height:800px"></ textarea> </body> </html> 2. ブラウザで MoviesItemOps04.html ファイルを開きます。 3. [Increase Rating] を選択します。 ステップ 3.5: 項目を更新する (条件付き) 次のプログラムは、条件とともに UpdateItem を使用する方法を示しています。条件が true と評価 された場合、更新は成功します。それ以外の場合、更新は行われません。 その場合、項目は 3 人より多い役者がいる場合にのみ更新されます。 1. 次のプログラムを MoviesItemOps05.html というファイルにコピーします。 <html> <head> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js"></script> <script> AWS.config.update({ region: "us-west-2", endpoint: 'http://localhost:8000', // accessKeyId default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. accessKeyId: "fakeMyKeyId", // secretAccessKey default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. secretAccessKey: "fakeSecretAccessKey" }); var docClient = new AWS.DynamoDB.DocumentClient(); function conditionalUpdate() { var table = "Movies"; var year = 2015; var title = "The Big New Movie"; // Conditional update (will fail) var params = { TableName:table, Key:{ "year": year, "title": title }, API Version 2012-08-10 37 Amazon DynamoDB 入門ガイド ステップ 3.6: 項目を削除する UpdateExpression: "remove info.actors[0]", ConditionExpression: "size(info.actors) > :num", ExpressionAttributeValues:{ ":num":3 }, ReturnValues:"UPDATED_NEW" }; docClient.update(params, function(err, data) { if (err) { document.getElementById('textarea').innerHTML = "The conditional update failed: " + "\n" + JSON.stringify(err, undefined, 2); } else { document.getElementById('textarea').innerHTML = "The conditional update succeeded: " + "\n" + JSON.stringify(data, undefined, 2); } }); } </script> </head> <body> <input id="conditionalUpdate" type="button" value="Conditional Update" onclick="conditionalUpdate();" /> <br><br> <textarea readonly id= "textarea" style="width:400px; height:800px"></ textarea> </body> </html> 2. ブラウザで MoviesItemOps05.html ファイルを開きます。 3. [Conditional Update] を選択します。 プログラムは次のメッセージで失敗するはずです。 The conditional update failed これは、映画に 3 人の役者が出演しているが、条件は役者が 3 人より多いことをチェックしてい るためです。 4. ConditionExpression が次のようになるようにプログラムを変更します。 ConditionExpression: "size(info.actors) >= :num", 条件が、3 より大きいではなく 3 以上になりました。 5. プログラムを再度実行します。これで、updateItem オペレーションが成功します。 ステップ 3.6: 項目を削除する プライマリキーを指定することで、delete メソッドを使用して 1 つの項目を削除できます。オプ ションで ConditionExpression を指定して、条件を満たさない場合に項目の削除を防ぐことがで きます。 次の例では、レーティングが 5 以下の特定の映画項目を削除しようとします。 API Version 2012-08-10 38 Amazon DynamoDB 入門ガイド ステップ 3.6: 項目を削除する 1. 次のプログラムを MoviesItemOps06.html というファイルにコピーします。 <html> <head> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js"></script> <script> AWS.config.update({ region: "us-west-2", endpoint: 'http://localhost:8000', // accessKeyId default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. accessKeyId: "fakeMyKeyId", // secretAccessKey default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. secretAccessKey: "fakeSecretAccessKey" }); var docClient = new AWS.DynamoDB.DocumentClient(); function conditionalDelete() { var table = "Movies"; var year = 2015; var title = "The Big New Movie"; var params = { TableName:table, Key:{ "year":year, "title":title }, ConditionExpression:"info.rating <= :val", ExpressionAttributeValues: { ":val": 5.0 } }; docClient.delete(params, function(err, data) { if (err) { document.getElementById('textarea').innerHTML = "The conditional delete failed: " + "\n" + JSON.stringify(err, undefined, 2); } else { document.getElementById('textarea').innerHTML = "The conditional delete succeeded: " + "\n" + JSON.stringify(data, undefined, 2); } }); } </script> </head> <body> API Version 2012-08-10 39 Amazon DynamoDB 入門ガイド ステップ 4: データをクエリおよびスキャンする <input id="conditionalDelete" type="button" value="Conditional Delete" onclick="conditionalDelete();" /> <br><br> <textarea readonly id= "textarea" style="width:400px; height:800px"></ textarea> </body> </html> 2. ブラウザで MoviesItemOps06.html ファイルを開きます。 3. [Conditional Delete] を選択します。 プログラムは次のメッセージで失敗するはずです。 The conditional delete failed これは、この特定の映画のレーティングが 5 より大きいためです。 4. params から条件を削除するようにプログラムを変更します。 var params = { TableName:table, Key:{ "title":title, "year":year } }; 5. プログラムを再度実行します。条件を削除したため、削除が成功します。 ステップ 4: データをクエリおよびスキャンする query メソッドを使用して、テーブルからデータを取得できます。パーティションのキー値を指定す る必要があります。ソートキーはオプションです。 Movies テーブルのプライマリキーは、以下の内容で構成されます。 • year – パーティションキー。属性タイプは数値です。 • title – ソートキー。属性タイプは文字列です。 1 年間にリリースされたすべての映画を検索するには、year のみ指定する必要があります。title を指定して、いくつかの条件 (ソートキー上) に基づいて映画のサブセットを取得することもできま す。たとえば、2014 年にリリースされて、主題が「A」で始まる映画を探す場合です。 query に加えて、すべてのテーブルデータを取得可能な scan メソッドもあります。 データのクエリとスキャンの詳細については、『Amazon DynamoDB 開発者ガイド』の「クエリおよ びスキャン」を参照してください。 トピック • ステップ 4.1: クエリ - 1 年間にリリースされたすべての映画 (p. 41) • ステップ 4.2: クエリ - 1 年間にリリースされた特定のタイトルを持つすべての映画 (p. 42) • ステップ 4.3: スキャン (p. 44) API Version 2012-08-10 40 Amazon DynamoDB 入門ガイド ステップ 4.1: クエリ - 1 年間 にリリースされたすべての映画 ステップ 4.1: クエリ - 1 年間にリリースされたすべ ての映画 このステップに含まれているプログラムは、year 1985 にリリースされたすべての映画を取得しま す。 1. 次のプログラムを MoviesQuery01.html というファイルにコピーします。 <html> <head> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js"></script> <script> AWS.config.update({ region: "us-west-2", endpoint: 'http://localhost:8000', // accessKeyId default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. accessKeyId: "fakeMyKeyId", // secretAccessKey default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. secretAccessKey: "fakeSecretAccessKey" }); var docClient = new AWS.DynamoDB.DocumentClient(); function queryData() { document.getElementById('textarea').innerHTML += "Querying for movies from 1985."; var params = { TableName : "Movies", KeyConditionExpression: "#yr = :yyyy", ExpressionAttributeNames:{ "#yr": "year" }, ExpressionAttributeValues: { ":yyyy":1985 } }; docClient.query(params, function(err, data) { if (err) { document.getElementById('textarea').innerHTML += "Unable to query. Error: " + "\n" + JSON.stringify(err, undefined, 2); } else { document.getElementById('textarea').innerHTML += "Querying for movies from 1985: " + "\n" + JSON.stringify(data, undefined, 2); } }); } </script> API Version 2012-08-10 41 Amazon DynamoDB 入門ガイド ステップ 4.2: クエリ - 1 年間にリリース された特定のタイトルを持つすべての映画 </head> <body> <input id="queryData" type="button" value="Query" onclick="queryData();" / > <br><br> <textarea readonly id= "textarea" style="width:400px; height:800px"></ textarea> </body> </html> Note ExpressionAttributeNames は、名前を置換します。year は DynamoDB の予約語で あるため、これが使用されます。KeyConditionExpression を含むどの式でも直接使 用することはできません。このため、式の属性名 #yr が使用されます。 ExpressionAttributeValues は、値を置換します。KeyConditionExpression を 含むどの式にもリテラルを使用できないため、これが使用されます。このため、式の属 性名 :yyyy が使用されます。 2. ブラウザで MoviesQuery01.html ファイルを開きます。 3. [Query] を選択します。 Note 前のプログラムは、プライマリキーの属性によってテーブルをクエリする方法を示していま す。DynamoDB では、必要に応じて 1 つ以上のセカンダリインデックスをテーブルに作成 し、テーブルをクエリするのと同じ方法でそれらのインデックスをクエリできます。セカン ダリインデックスは非キー属性のクエリを可能にすることで、アプリケーションに追加の柔 軟性を提供します。詳細については、Amazon DynamoDB 開発者ガイドの「セカンダリイン デックス」を参照してください。 ステップ 4.2: クエリ - 1 年間にリリースされた特定 のタイトルを持つすべての映画 このステップに含まれているプログラムは、year 1992 にリリースされたすべての映画のう ち、title が「A」~「L」で始まる映画を取得します。 1. 次のプログラムを MoviesQuery02.html というファイルにコピーします。 <html> <head> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js"></script> <script> AWS.config.update({ region: "us-west-2", endpoint: 'http://localhost:8000', // accessKeyId default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. accessKeyId: "fakeMyKeyId", API Version 2012-08-10 42 Amazon DynamoDB 入門ガイド ステップ 4.2: クエリ - 1 年間にリリース された特定のタイトルを持つすべての映画 // secretAccessKey default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. secretAccessKey: "fakeSecretAccessKey" }); var docClient = new AWS.DynamoDB.DocumentClient(); function queryData() { document.getElementById('textarea').innerHTML += "Querying for movies from 1985."; var params = { TableName : "Movies", ProjectionExpression:"#yr, title, info.genres, info.actors[0]", KeyConditionExpression: "#yr = :yyyy and title between :letter1 and :letter2", ExpressionAttributeNames:{ "#yr": "year" }, ExpressionAttributeValues: { ":yyyy":1992, ":letter1": "A", ":letter2": "L" } }; docClient.query(params, function(err, data) { if (err) { document.getElementById('textarea').innerHTML += "Unable to query. Error: " + "\n" + JSON.stringify(err, undefined, 2); } else { document.getElementById('textarea').innerHTML += "Querying for movies from 1992 - titles A-L, with genres and lead actor: " + "\n" + JSON.stringify(data, undefined, 2); } }); } </script> </head> <body> <input id="queryData" type="button" value="Query" onclick="queryData();" / > <br><br> <textarea readonly id= "textarea" style="width:400px; height:800px"></ textarea> </body> </html> 2. ブラウザで MoviesQuery02.html ファイルを開きます。 3. [Query] を選択します。 API Version 2012-08-10 43 Amazon DynamoDB 入門ガイド ステップ 4.3: スキャン ステップ 4.3: スキャン scan メソッドは、テーブル全体のすべての項目を読み込み、テーブルの全データを返します。オプ ションで filter_expression を提供して、条件に一致する項目だけが返されるように指定できま す。ただし、テーブル全体がスキャンされた後にのみ、フィルタが適用されます。 次のプログラムは、約 5,000 項目を含む Movies テーブル全体をスキャンします。スキャンは、1950 年代の映画のみ (約 100 項目) を取得して、残りはすべて破棄するようオプションのフィルタを指定し ます。 1. 次のプログラムを MoviesScan.html というファイルにコピーします。 <html> <head> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js"></script> <script> AWS.config.update({ region: "us-west-2", endpoint: 'http://localhost:8000', // accessKeyId default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. accessKeyId: "fakeMyKeyId", // secretAccessKey default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. secretAccessKey: "fakeSecretAccessKey" }); var docClient = new AWS.DynamoDB.DocumentClient(); function scanData() { document.getElementById('textarea').innerHTML += "Scanning Movies table." + "\n"; var params = { TableName: "Movies", ProjectionExpression: "#yr, title, info.rating", FilterExpression: "#yr between :start_yr and :end_yr", ExpressionAttributeNames: { "#yr": "year", }, ExpressionAttributeValues: { ":start_yr": 1950, ":end_yr": 1959 } }; docClient.scan(params, onScan); function onScan(err, data) { if (err) { document.getElementById('textarea').innerHTML += "Unable to scan the table: " + "\n" + JSON.stringify(err, undefined, 2); } else { API Version 2012-08-10 44 Amazon DynamoDB 入門ガイド ステップ 5: (オプション) テーブルを削除する // Print all the movies document.getElementById('textarea').innerHTML += "Scan succeeded. " + "\n"; data.Items.forEach(function(movie) { document.getElementById('textarea').innerHTML += movie.year + ": " + movie.title + " - rating: " + movie.info.rating + "\n"; }); // Continue scanning if we have more movies (per scan 1MB limitation) document.getElementById('textarea').innerHTML += "Scanning for more..." + "\n"; params.ExclusiveStartKey = data.LastEvaluatedKey; docClient.scan(params, onScan); } } } </script> </head> <body> <input id="scanData" type="button" value="Scan" onclick="scanData();" /> <br><br> <textarea readonly id= "textarea" style="width:400px; height:800px"></ textarea> </body> </html> このコードでは、以下の点に注意してください。 • ProjectionExpression は、スキャン結果に必要な属性を指定します。 • FilterExpression は、条件を満たした項目だけが返されるような条件を指定します。他の すべての項目は破棄されます。 2. ブラウザで MoviesScan.html ファイルを開きます。 3. [Scan] を選択します。 Note テーブルで作成した任意のセカンダリインデックスで Scan オペレーションを使用すること もできます。詳細については、Amazon DynamoDB 開発者ガイドの「セカンダリインデック ス」を参照してください。 ステップ 5: (オプション) テーブルを削除する Movies テーブルを削除するには: 1. 次のプログラムを MoviesDeleteTable.html というファイルにコピーします。 <html> <head> <script src="https://sdk.amazonaws.com/js/aws-sdk-2.7.16.min.js"></script> API Version 2012-08-10 45 Amazon DynamoDB 入門ガイド 概要 <script> AWS.config.update({ region: "us-west-2", endpoint: 'http://localhost:8000', // accessKeyId default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. accessKeyId: "fakeMyKeyId", // secretAccessKey default can be used while using the downloadable version of DynamoDB. // For security reasons, do not store AWS Credentials in your files. Use Amazon Cognito instead. secretAccessKey: "fakeSecretAccessKey" }); var dynamodb = new AWS.DynamoDB(); function deleteMovies() { var params = { TableName : "Movies" }; dynamodb.deleteTable(params, function(err, data) { if (err) { document.getElementById('textarea').innerHTML = "Unable to delete table: " + "\n" + JSON.stringify(err, undefined, 2); } else { document.getElementById('textarea').innerHTML = "Table deleted."; } }); } </script> </head> <body> <input id="deleteTableButton" type="button" value="Delete Table" onclick="deleteMovies();" /> <br><br> <textarea readonly id= "textarea" style="width:400px; height:800px"></ textarea> </body> </html> 2. 3. ブラウザで MoviesDeleteTable.html ファイルを開きます。 [Delete Table] を選択します。 概要 このチュートリアルでは、ご使用のコンピューターの DynamoDB で Movies テーブルを作成し、 基本的なオペレーションを実行しました。ダウンロード可能なバージョンの DynamoDB は、アプリ ケーションの開発およびテストの際に便利です。ただし、本番環境でアプリケーションを実行する場 合、Amazon DynamoDB ウェブサービスを使用できるようにコードを変更します。 API Version 2012-08-10 46 Amazon DynamoDB 入門ガイド AWS 設定リージョンの更新 Amazon DynamoDB サービスを使用するようコードを変更するには、以下の操作を実行します。 1. Amazon Web Services にサインアップし、アクセスキーを作成します。AWS SDK を使用するに は、これらの認証情報が必要です。AWS アカウントを作成するには、https://aws.amazon.com/ にアクセスし、[Create an AWS Account] を選択して、オンラインの手順に従います。 2. AWS 設定リージョンの更新 (p. 47)。 3. AWS CLI のインストールと設定 (p. 47)。 4. Amazon Cognito を使用したファイルでの AWS 認証情報の設定 (p. 47)。 AWS 設定リージョンの更新 Amazon DynamoDB ウェブサービスを使用するには、アプリケーションのリージョンを更新する必要 があります。また、同じリージョンで Amazon Cognito が利用できることを確認し、ブラウザスクリ プトが正常に認証できるようにする必要があります。 AWS.config.update({region: "aws-region"}); たとえば、us-west-2 リージョンを使用する場合、次のリージョンを設定します。 AWS.config.update({region: "us-west-2"}); これで、プログラムは 米国西部 (オレゴン) で Amazon DynamoDB ウェブサービスリージョンを使用 します。 Amazon DynamoDB は、世界中の AWS リージョンで利用できます。完全なリストについては、AWS General Referenceの「リージョンとエンドポイント」を参照してください。コードでのリージョン とエンドポイントの設定に関する詳細については、AWS SDK for JavaScript Getting Started Guideの 「リージョンの設定」を参照してください。 AWS CLI のインストールと設定 AWS アクセスキー ID とシークレットキーを取得した後は、コンピュータで AWS CLI をセットアッ プできます。 AWS CLI をインストールして設定するには 1. AWS Command Line Interface ユーザーガイド に移動します。 2. AWS CLI をインストールし、AWS CLI を設定する手順に従います。 Amazon Cognito を使用したファイルでの AWS 認 証情報の設定 ブラウザスクリプト用に AWS 認証情報を取得する推奨の方法は、Amazon Cognito を使用すること です。Amazon Cognito は、ファイルで AWS 認証情報のハードコーディングを避けるうえで有効で す。Amazon Cognito は IAM ロールを使用して、アプリケーションの認証されたユーザーと認証され ていないユーザーの一時的な認証情報を生成します。 認証されていないロールを使用して、AWS CLI で DynamoDB ウェブサービスにアクセスするよう ファイルを設定するには: 1. 認証されていない ID を許可する Amazon Cognito ID プールを作成します。 API Version 2012-08-10 47 Amazon DynamoDB 入門ガイド Amazon Cognito を使用したファ イルでの AWS 認証情報の設定 aws cognito-identity create-identity-pool --identity-pool-name DynamoPool --allow-unauthenticated-identities --output json { "IdentityPoolId": "us-west-2:12345678-1ab2-123a-1234-a12345ab12", "AllowUnauthenticatedIdentities": true, "IdentityPoolName": "DynamoPool" } 2. 次のポリシーを myCognitoPolicy.json という名前のファイルにコピーします。ID プール ID (us-west-2:12345678-1ab2-123a-1234-a12345ab12) を、前のステップで入手した独自の IdentityPoolId を使用して変更します。 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "cognito-identity.amazonaws.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "cognito-identity.amazonaws.com:aud": "uswest-2:12345678-1ab2-123a-1234-a12345ab12" }, "ForAnyValue:StringLike": { "cognito-identity.amazonaws.com:amr": "unauthenticated" } } } ] } 3. 前のポリシーを引き受ける IAM ロールを作成します。このようにして、Amazon Cognito は Cognito_DynamoPoolUnauth ロールを引き受けることができる信頼済みエンティティになりま す。 aws iam create-role --role-name Cognito_DynamoPoolUnauth --assume-rolepolicy-document file://PathToFile/myCognitoPolicy.json --output json 4. 管理ポリシー (AmazonDynamoDBFullAccess) をアタッチして、DynamoDB サービスへのフル アクセスを Cognito_DynamoPoolUnauth ロールに付与します。 aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/ AmazonDynamoDBFullAccess --role-name Cognito_DynamoPoolUnauth Note または、DynamoDB へのきめ細かなアクセス権を付与できます。詳細については、「詳 細に設定されたアクセスコントロールのための IAM ポリシー条件の使用」を参照してく ださい。 5. IAM ロールの ARN を取得してコピーします。 API Version 2012-08-10 48 Amazon DynamoDB 入門ガイド Amazon Cognito を使用したファ イルでの AWS 認証情報の設定 aws iam get-role --role-name Cognito_DynamoPoolUnauth --output json 6. DynamoPool ID プールに Cognito_DynamoPoolUnauth ロールを追加します。指定するフォー マットは KeyName=string です。ここで KeyName は unauthenticated で、文字列は前のス テップで取得したロールの ARN です。 aws cognito-identity set-identity-pool-roles --identity-pool-id "uswest-2:12345678-1ab2-123a-1234-a12345ab12" --roles unauthenticated=arn:aws:iam::123456789012:role/ Cognito_DynamoPoolUnauth --output json 7. 次のコードを使用して、JavaScript ファイルで Amazon Cognito 認証情報を指定できます。それ に応じて IdentityPoolId および RoleArn を変更します。 AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: "us-west-2:12345678-1ab2-123a-1234-a12345ab12", RoleArn: "arn:aws:iam::123456789012:role/Cognito_DynamoPoolUnauth" }); 8. Amazon Cognito 認証情報を使用して、DynamoDB ウェブサービスに対して JavaScript プログラ ムを実行できます。 詳細については、AWS SDK for JavaScript Getting Started Guideの「ウェブブラウザでの認証情報の 設定」を参照してください。 最後に、「Amazon DynamoDB 開発者ガイド」を読むことをお勧めします。ここには、サンプルコー ドやベストプラクティスなど、DynamoDB に関するさらに詳しい情報が収められています。 API Version 2012-08-10 49 Amazon DynamoDB 入門ガイド 前提条件 Node.js と DynamoDB このチュートリアルでは、AWS SDK for JavaScript を使用して次の Amazon DynamoDB オペレー ションを実行するシンプルなプログラムを作成します。 • Movies というテーブルを作成し、JSON形式のサンプルデータをロードします。 • テーブルで、作成、読み込み、更新、削除のオペレーションを実行します。 • 簡単なクエリを実行します。 このチュートリアルでは、ダウンロード可能なバージョンの DynamoDB を使用します。概 要 (p. 66) では、DynamoDB ウェブサービスに対して同じコードを実行する方法について説明しま す。 参加費: 無料 前提条件 • Read DynamoDB の概念について (p. 1). • DynamoDB をダウンロードしてコンピュータで実行します。詳細については、「DynamoDB のダ ウンロードと実行 (p. 4)」を参照してください。 • Amazon Web Services にサインアップし、アクセスキーを作成します。AWS SDK を使用するに は、これらの認証情報が必要です。AWS アカウントを作成するには、https://aws.amazon.com/ に アクセスし、[Create an AWS Account] を選択して、オンラインの手順に従います。 • アクセスキーを保存するための AWS 認証情報ファイルを作成します。詳細については、AWS SDK for JavaScript 開発者ガイドのLoading Credentials from the Shared Credentials Fileを参照してくだ さい。 • AWS SDK for JavaScript のセットアップ: • http://nodejs.org にアクセスして、Node.js をインストールします。 • https://aws.amazon.com/sdk-for-node-js にアクセスして、AWS SDK for JavaScript をインストー ルします。 詳細については、『AWS SDK for JavaScript Getting Started Guide』を参照してください。 Tip このチュートリアルを行うときは、『AWS SDK for JavaScript API Reference』を参照できま す。 API Version 2012-08-10 50 Amazon DynamoDB 入門ガイド ステップ 1: テーブルを作成する ステップ 1: テーブルを作成する このステップでは、Movies という名前のテーブルを作成します。テーブルのプライマリキーは、以 下の属性で構成されます。 • year – パーティションキー。AttributeType は、数字 (number) の N です。 • title – ソートキー。AttributeType は、文字列 (string) の S です。 1. 次のプログラムを MoviesCreateTable.js というファイルにコピーします。 var AWS = require("aws-sdk"); AWS.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }); var dynamodb = new AWS.DynamoDB(); var params = { TableName : "Movies", KeySchema: [ { AttributeName: "year", KeyType: "HASH"}, //Partition key { AttributeName: "title", KeyType: "RANGE" } //Sort key ], AttributeDefinitions: [ { AttributeName: "year", AttributeType: "N" }, { AttributeName: "title", AttributeType: "S" } ], ProvisionedThroughput: { ReadCapacityUnits: 10, WriteCapacityUnits: 10 } }; dynamodb.createTable(params, function(err, data) { if (err) { console.error("Unable to create table. Error JSON:", JSON.stringify(err, null, 2)); } else { console.log("Created table. Table description JSON:", JSON.stringify(data, null, 2)); } }); Note • エンドポイントを設定して、コンピュータの DynamoDB にテーブルを作成することを 示します。 • createTable 呼び出しでは、テーブル名、プライマリキー属性、そのデータ型を指定 します。 • ProvisionedThroughput パラメーターは必須ですが、ダウンロード可能なバージョ ンの DynamoDB では無視されます。(プロビジョニングされたスループットはこの演 習では扱いません。) 2. 次のコマンドを入力してコマンドを実行します。 API Version 2012-08-10 51 Amazon DynamoDB 入門ガイド ステップ 2: サンプルデータをロードする node MoviesCreateTable.js テーブルの管理の詳細については、『Amazon DynamoDB 開発者ガイド』の「テーブルの操作」を参 照してください。 ステップ 2: サンプルデータをロードする このステップでは、Movies テーブルにサンプルデータを入力します。 トピック • ステップ 2.1: サンプルデータファイルをダウンロードする (p. 53) • ステップ 2.2: 映画テーブルにサンプルデータをロードする (p. 53) サンプルデータファイルには、インターネット映画データベース (IMDb) にある数千におよぶ映 画の情報が格納されています。映画データは、次の例に示すように JSON 形式です。映画ごと に、year、title、および info という JSON マップが設定されています。 [ { "year" : ... , "title" : ... , "info" : { ... } }, { "year" : ..., "title" : ..., "info" : { ... } }, ... ] JSON データで次の点に注意してください。 • year と title を、Movies テーブルのプライマリキー属性値として使用します。 • 残りの info 値は、info という単一の属性に保存されます。このプログラムは、JSON を DynamoDB 属性で保存する方法を示しています。 以下は、映画データの例です。 { "year" : 2013, "title" : "Turn It Down, Or Else!", "info" : { "directors" : [ "Alice Smith", "Bob Jones" ], "release_date" : "2013-01-18T00:00:00Z", "rating" : 6.2, "genres" : [ API Version 2012-08-10 52 Amazon DynamoDB 入門ガイド ステップ 2.1: サンプルデータ ファイルをダウンロードする "Comedy", "Drama" ], "image_url" : "http://ia.media-imdb.com/images/N/ O9ERWAU7FS797AJ7LU8HN09AMUP908RLlo5JF90EWR7LJKQ7@@._V1_SX400_.jpg", "plot" : "A rock band plays their music at high volumes, annoying the neighbors.", "rank" : 11, "running_time_secs" : 5215, "actors" : [ "David Matthewman", "Ann Thomas", "Jonathan G. Neff" ] } } ステップ 2.1: サンプルデータファイルをダウンロー ドする 1. リンク moviedata.zip をクリックして、サンプルデータアーカイブをダウンロードします。 2. アーカイブからデータファイル (moviedata.json) を抽出します。 3. 現在のディレクトリに moviedata.json ファイルをコピーします。 ステップ 2.2: 映画テーブルにサンプルデータをロー ドする サンプルデータをダウンロードすると、次のプログラムを実行して Movies テーブルに入力できま す。 1. 次のプログラムを MoviesLoadData.js というファイルにコピーします。 var AWS = require("aws-sdk"); var fs = require('fs'); AWS.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }); var docClient = new AWS.DynamoDB.DocumentClient(); console.log("Importing movies into DynamoDB. Please wait."); var allMovies = JSON.parse(fs.readFileSync('moviedata.json', 'utf8')); allMovies.forEach(function(movie) { var params = { TableName: "Movies", Item: { "year": movie.year, "title": movie.title, "info": movie.info } API Version 2012-08-10 53 Amazon DynamoDB 入門ガイド ステップ 3: 項目を作成、読み込み、更新、削除する }; docClient.put(params, function(err, data) { if (err) { console.error("Unable to add movie", movie.title, ". Error JSON:", JSON.stringify(err, null, 2)); } else { console.log("PutItem succeeded:", movie.title); } }); }); 2. 次のコマンドを入力してコマンドを実行します。 node MoviesLoadData.js ステップ 3: 項目を作成、読み込み、更新、削除 する このステップでは、Movies テーブルの項目で読み取り/書き込みオペレーションを実行します。 データの読み取りと書き込みの詳細については、『Amazon DynamoDB 開発者ガイド』の「項目の操 作」を参照してください。 トピック • ステップ 3.1: 新しい項目を作成する (p. 54) • ステップ 3.2: 項目を読み取る (p. 55) • ステップ 3.3: 項目を更新する (p. 56) • ステップ 3.4: アトミックカウンターを増分する (p. 58) • ステップ 3.5: 項目を更新する (条件付き) (p. 59) • ステップ 3.6: 項目を削除する (p. 60) ステップ 3.1: 新しい項目を作成する このステップでは、Movies テーブルに新しい項目を追加します。 1. 次のプログラムを MoviesItemOps01.js というファイルにコピーします。 var AWS = require("aws-sdk"); AWS.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }); var docClient = new AWS.DynamoDB.DocumentClient(); var table = "Movies"; var year = 2015; var title = "The Big New Movie"; var params = { API Version 2012-08-10 54 Amazon DynamoDB 入門ガイド ステップ 3.2: 項目を読み取る TableName:table, Item:{ "year": year, "title": title, "info":{ "plot": "Nothing happens at all.", "rating": 0 } } }; console.log("Adding a new item..."); docClient.put(params, function(err, data) { if (err) { console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2)); } else { console.log("Added item:", JSON.stringify(data, null, 2)); } }); Note プライマリキーは必須です。このコードは、プライマリキー (year, title) と info 属 性を持つ項目を追加します。info 属性には、映画についての詳細情報を示すサンプル JSON が保存されます。 2. 次のコマンドを入力してコマンドを実行します。 node MoviesItemOps01.js ステップ 3.2: 項目を読み取る 前のプログラムでは、テーブルに次の項目を追加しました。 { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } Movies テーブルから項目を読み取る、get メソッドを使用できます。 プライマリキー値を指定する 必要があります。そうすると year と title がわかれば、Movies から項目を読み込むことができま す。 1. 次のプログラムを MoviesItemOps02.js というファイルにコピーします。 var AWS = require("aws-sdk"); AWS.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }); API Version 2012-08-10 55 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する var docClient = new AWS.DynamoDB.DocumentClient() var table = "Movies"; var year = 2015; var title = "The Big New Movie"; var params = { TableName: table, Key:{ "year": year, "title": title } }; docClient.get(params, function(err, data) { if (err) { console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2)); } else { console.log("GetItem succeeded:", JSON.stringify(data, null, 2)); } }); 2. 次のコマンドを入力してコマンドを実行します。 node MoviesItemOps02.js ステップ 3.3: 項目を更新する update メソッドを使用して既存の項目を変更できます。既存の属性の値の更新、新しい属性の追 加、または属性の削除を行えます。 このチュートリアルでは、次の更新を行います。 • 既存の属性の値を変更します (rating、plot)。 • 新しいリスト属性 (actors) を既存の info マップに追加します。 項目の変更前: { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } 項目の変更後: { year: 2015, title: "The Big New Movie", info: { plot: "Everything happens all at once.", API Version 2012-08-10 56 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する rating: 5.5, actors: ["Larry", "Moe", "Curly"] } } 1. 次のプログラムを MoviesItemOps03.js というファイルにコピーします。 var AWS = require("aws-sdk"); AWS.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }); var docClient = new AWS.DynamoDB.DocumentClient() var table = "Movies"; var year = 2015; var title = "The Big New Movie"; // Update the item, unconditionally, var params = { TableName:table, Key:{ "year": year, "title": title }, UpdateExpression: "set info.rating = :r, info.plot=:p, info.actors=:a", ExpressionAttributeValues:{ ":r":5.5, ":p":"Everything happens all at once.", ":a":["Larry", "Moe", "Curly"] }, ReturnValues:"UPDATED_NEW" }; console.log("Updating the item..."); docClient.update(params, function(err, data) { if (err) { console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2)); } else { console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2)); } }); Note このプログラムでは、UpdateExpression を使用して、指定された項目で実行するすべ ての更新を記述します。 ReturnValues パラメーターは、DynamoDB に更新された属性 ("UPDATED_NEW") のみ を返すように指示します。 API Version 2012-08-10 57 Amazon DynamoDB 入門ガイド ステップ 3.4: アトミックカウンターを増分する 2. 次のコマンドを入力してコマンドを実行します。 node MoviesItemOps03.js ステップ 3.4: アトミックカウンターを増分する DynamoDB では、アトミックカウンターがサポートされています。そのため、update メソッドを使 用して、他の書き込みリクエストを妨げることなく既存の属性値をインクリメントまたはデクリメン トできます。(すべての書き込みリクエストは、受信された順に適用されます)。 次のプログラムは、映画の rating を増分する方法を示しています。実行するたびに、プログラムは この属性を 1 つ増分します。 1. 次のプログラムを MoviesItemOps04.js というファイルにコピーします。 var AWS = require("aws-sdk"); AWS.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }); var docClient = new AWS.DynamoDB.DocumentClient() var table = "Movies"; var year = 2015; var title = "The Big New Movie"; // Increment an atomic counter var params = { TableName:table, Key:{ "year": year, "title": title }, UpdateExpression: "set info.rating = info.rating + :val", ExpressionAttributeValues:{ ":val":1 }, ReturnValues:"UPDATED_NEW" }; console.log("Updating the item..."); docClient.update(params, function(err, data) { if (err) { console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2)); } else { console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2)); } }); 2. 次のコマンドを入力してコマンドを実行します。 node MoviesItemOps04.js API Version 2012-08-10 58 Amazon DynamoDB 入門ガイド ステップ 3.5: 項目を更新する (条件付き) ステップ 3.5: 項目を更新する (条件付き) 次のプログラムは、条件とともに UpdateItem を使用する方法を示しています。条件が true と評価 された場合、更新は成功します。それ以外の場合、更新は行われません。 その場合、項目は 3 人より多い役者がいる場合にのみ更新されます。 1. 次のプログラムを MoviesItemOps05.js というファイルにコピーします。 var AWS = require("aws-sdk"); AWS.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }); var docClient = new AWS.DynamoDB.DocumentClient() var table = "Movies"; var year = 2015; var title = "The Big New Movie"; // Conditional update (will fail) var params = { TableName:table, Key:{ "year": year, "title": title }, UpdateExpression: "remove info.actors[0]", ConditionExpression: "size(info.actors) > :num", ExpressionAttributeValues:{ ":num":3 }, ReturnValues:"UPDATED_NEW" }; console.log("Attempting a conditional update..."); docClient.update(params, function(err, data) { if (err) { console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2)); } else { console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2)); } }); 2. 次のコマンドを入力してコマンドを実行します。 node MoviesItemOps05.js プログラムは次のメッセージで失敗するはずです。 The conditional request failed API Version 2012-08-10 59 Amazon DynamoDB 入門ガイド ステップ 3.6: 項目を削除する これは、映画に 3 人の役者が出演しているが、条件は役者が 3 人より多いことをチェックしてい るためです。 3. ConditionExpression が次のようになるようにプログラムを変更します。 ConditionExpression: "size(info.actors) >= :num", 条件が、3 より大きいではなく 3 以上になりました。 4. プログラムを再度実行します。これで、updateItem オペレーションが成功します。 ステップ 3.6: 項目を削除する プライマリキーを指定することで、delete メソッドを使用して 1 つの項目を削除できます。オプ ションで ConditionExpression を指定して、条件を満たさない場合に項目の削除を防ぐことがで きます。 次の例では、レーティングが 5 以下の特定の映画項目を削除しようとします。 1. 次のプログラムを MoviesItemOps06.js というファイルにコピーします。 var AWS = require("aws-sdk"); AWS.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }); var docClient = new AWS.DynamoDB.DocumentClient(); var table = "Movies"; var year = 2015; var title = "The Big New Movie"; var params = { TableName:table, Key:{ "year":year, "title":title }, ConditionExpression:"info.rating <= :val", ExpressionAttributeValues: { ":val": 5.0 } }; console.log("Attempting a conditional delete..."); docClient.delete(params, function(err, data) { if (err) { console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2)); } else { console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2)); } API Version 2012-08-10 60 Amazon DynamoDB 入門ガイド ステップ 4: データをクエリおよびスキャンする }); 2. 次のコマンドを入力してコマンドを実行します。 node MoviesItemOps06.js プログラムは次のメッセージで失敗するはずです。 The conditional request failed これは、この特定の映画のレーティングが 5 より大きいためです。 3. params から条件を削除するようにプログラムを変更します。 var params = { TableName:table, Key:{ "title":title, "year":year } }; 4. プログラムを再度実行します。ここでは、条件を削除したため、削除が成功します。 ステップ 4: データをクエリおよびスキャンする query メソッドを使用して、テーブルからデータを取得できます。パーティションのキー値を指定す る必要があります。ソートキーはオプションです。 Movies テーブルのプライマリキーは、以下の内容で構成されます。 • year – パーティションキー。属性タイプは数値です。 • title – ソートキー。属性タイプは文字列です。 1 年間にリリースされたすべての映画を検索するには、year のみ指定する必要があります。title を指定して、いくつかの条件 (ソートキー上) に基づいて映画のサブセットを取得することもできま す。たとえば、2014 年にリリースされて、主題が「A」で始まる映画を探す場合です。 query に加えて、すべてのテーブルデータを取得可能な scan メソッドもあります。 データのクエリとスキャンの詳細については、『Amazon DynamoDB 開発者ガイド』の「クエリおよ びスキャン」を参照してください。 トピック • ステップ 4.1: クエリ - 1 年間にリリースされたすべての映画 (p. 61) • ステップ 4.2: クエリ - 1 年間にリリースされた特定のタイトルを持つすべての映画 (p. 63) • ステップ 4.3: スキャン (p. 64) ステップ 4.1: クエリ - 1 年間にリリースされたすべ ての映画 このステップに含まれているプログラムは、year 1985 にリリースされたすべての映画を取得しま す。 API Version 2012-08-10 61 Amazon DynamoDB 入門ガイド ステップ 4.1: クエリ - 1 年間 にリリースされたすべての映画 1. 次のプログラムを MoviesQuery01.js というファイルにコピーします。 var AWS = require("aws-sdk"); AWS.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }); var docClient = new AWS.DynamoDB.DocumentClient(); console.log("Querying for movies from 1985."); var params = { TableName : "Movies", KeyConditionExpression: "#yr = :yyyy", ExpressionAttributeNames:{ "#yr": "year" }, ExpressionAttributeValues: { ":yyyy":1985 } }; docClient.query(params, function(err, data) { if (err) { console.error("Unable to query. Error:", JSON.stringify(err, null, 2)); } else { console.log("Query succeeded."); data.Items.forEach(function(item) { console.log(" -", item.year + ": " + item.title); }); } }); Note ExpressionAttributeNames は、名前を置換します。year は DynamoDB の予約語で あるため、これが使用されます。KeyConditionExpression を含むどの式でも直接使 用することはできません。これに対処するため、式の属性名 #yr が使用されます。 ExpressionAttributeValues は、値を置換します。KeyConditionExpression を 含むどの式にもリテラルを使用できないため、これが使用されます。これに対処するた め、式の属性値 :yyyy が使用されます。 2. 次のコマンドを入力してコマンドを実行します。 node MoviesQuery01.js Note 前のプログラムは、プライマリキーの属性によってテーブルをクエリする方法を示していま す。DynamoDB では、必要に応じて 1 つ以上のセカンダリインデックスをテーブルに作成 し、テーブルをクエリするのと同じ方法でそれらのインデックスをクエリできます。セカン ダリインデックスは非キー属性のクエリを可能にすることで、アプリケーションに追加の柔 軟性を提供します。詳細については、Amazon DynamoDB 開発者ガイドの「セカンダリイン デックス」を参照してください。 API Version 2012-08-10 62 Amazon DynamoDB 入門ガイド ステップ 4.2: クエリ - 1 年間にリリース された特定のタイトルを持つすべての映画 ステップ 4.2: クエリ - 1 年間にリリースされた特定 のタイトルを持つすべての映画 このステップに含まれているプログラムは、year 1992 にリリースされたすべての映画のう ち、title が「A」~「L」で始まる映画を取得します。 1. 次のプログラムを MoviesQuery02.js というファイルにコピーします。 var AWS = require("aws-sdk"); AWS.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }); var docClient = new AWS.DynamoDB.DocumentClient(); console.log("Querying for movies from 1992 - titles A-L, with genres and lead actor"); var params = { TableName : "Movies", ProjectionExpression:"#yr, title, info.genres, info.actors[0]", KeyConditionExpression: "#yr = :yyyy and title between :letter1 and :letter2", ExpressionAttributeNames:{ "#yr": "year" }, ExpressionAttributeValues: { ":yyyy":1992, ":letter1": "A", ":letter2": "L" } }; docClient.query(params, function(err, data) { if (err) { console.log("Unable to query. Error:", JSON.stringify(err, null, 2)); } else { console.log("Query succeeded."); data.Items.forEach(function(item) { console.log(" -", item.year + ": " + item.title + " ... " + item.info.genres + " ... " + item.info.actors[0]); }); } }); 2. 次のコマンドを入力してコマンドを実行します。 node MoviesQuery02.js API Version 2012-08-10 63 Amazon DynamoDB 入門ガイド ステップ 4.3: スキャン ステップ 4.3: スキャン scan メソッドは、テーブル全体のすべての項目を読み込み、テーブルの全データを返します。オプ ションで filter_expression を提供して、条件に一致する項目だけが返されるように指定できま す。ただし、テーブル全体がスキャンされた後にのみ、フィルタが適用されることに注意してくださ い。 次のプログラムは、約 5,000 項目を含む Movies テーブル全体をスキャンします。スキャンは、1950 年代の映画のみ (約 100 項目) を取得して、残りはすべて破棄するようオプションのフィルタを指定し ます。 1. 次のプログラムを MoviesScan.js というファイルにコピーします。 var AWS = require("aws-sdk"); AWS.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }); var docClient = new AWS.DynamoDB.DocumentClient(); var params = { TableName: "Movies", ProjectionExpression: "#yr, title, info.rating", FilterExpression: "#yr between :start_yr and :end_yr", ExpressionAttributeNames: { "#yr": "year", }, ExpressionAttributeValues: { ":start_yr": 1950, ":end_yr": 1959 } }; console.log("Scanning Movies table."); docClient.scan(params, onScan); function onScan(err, data) { if (err) { console.error("Unable to scan the table. Error JSON:", JSON.stringify(err, null, 2)); } else { // print all the movies console.log("Scan succeeded."); data.Items.forEach(function(movie) { console.log( movie.year + ": ", movie.title, "- rating:", movie.info.rating); }); // continue scanning if we have more movies, because // scan can retrieve a maximum of 1MB of data if (typeof data.LastEvaluatedKey != "undefined") { console.log("Scanning for more..."); params.ExclusiveStartKey = data.LastEvaluatedKey; docClient.scan(params, onScan); } API Version 2012-08-10 64 Amazon DynamoDB 入門ガイド ステップ 5: (オプション) テーブルを削除する } } このコードでは、以下の点に注意してください。 • ProjectionExpression は、スキャン結果に必要な属性を指定します。 • FilterExpression は、条件を満たした項目だけが返されるような条件を指定します。他の すべての項目は破棄されます。 2. 次のコマンドを入力してコマンドを実行します。 node MoviesScan.js Note テーブルで作成した任意のセカンダリインデックスで Scan オペレーションを使用すること もできます。詳細については、Amazon DynamoDB 開発者ガイドの「セカンダリインデック ス」を参照してください。 ステップ 5: (オプション) テーブルを削除する Movies テーブルを削除するには: 1. 次のプログラムを MoviesDeleteTable.js というファイルにコピーします。 var AWS = require("aws-sdk"); AWS.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }); var dynamodb = new AWS.DynamoDB(); var params = { TableName : "Movies" }; dynamodb.deleteTable(params, function(err, data) { if (err) { console.error("Unable to delete table. Error JSON:", JSON.stringify(err, null, 2)); } else { console.log("Deleted table. Table description JSON:", JSON.stringify(data, null, 2)); } }); 2. 次のコマンドを入力してコマンドを実行します。 node MoviesDeleteTable.js API Version 2012-08-10 65 Amazon DynamoDB 入門ガイド 概要 概要 このチュートリアルでは、ご使用のコンピューターの DynamoDB で Movies テーブルを作成し、 基本的なオペレーションを実行しました。ダウンロード可能なバージョンの DynamoDB は、アプリ ケーションの開発およびテストの際に便利です。ただし、本番環境でアプリケーションを実行する場 合、Amazon DynamoDB ウェブサービスを使用できるようにコードを変更します。 Amazon DynamoDB サービスを使用する Amazon DynamoDB サービスを使用するには、アプリケーションのエンドポイントを変更する必要が あります。それには、コードを次のように変更します。 AWS.config.update({endpoint: "https://dynamodb.aws-region.amazonaws.com"}); たとえば、us-west-2 リージョンを使用する場合、次のエンドポイントを設定します。 AWS.config.update({endpoint: "https://dynamodb.us-west-2.amazonaws.com"}); プログラムはコンピュータで DynamoDB を使用する代わりに、米国西部 (オレゴン) で Amazon DynamoDB ウェブサービスエンドポイントを使用します。 Amazon DynamoDB は、世界中の AWS リージョンで利用できます。完全なリストについては、AWS General Referenceの「リージョンとエンドポイント」を参照してください。コードにリージョンとエ ンドポイントを設定するための詳細については、AWS SDK for JavaScript 開発者ガイドの「リージョ ンの設定」を参照してください。 最後に、「Amazon DynamoDB 開発者ガイド」を読むことをお勧めします。ここには、サンプルコー ドやベストプラクティスなど、DynamoDB に関するさらに詳しい情報が収められています。 API Version 2012-08-10 66 Amazon DynamoDB 入門ガイド 前提条件 .NET と DynamoDB このチュートリアルでは、AWS SDK for .NET を使用して次の Amazon DynamoDB オペレーションを 実行するシンプルなプログラムを作成します。 • C# で記述されたユーティリティプログラムを使って Movies という名前のテーブルを作成し、サン プルデータを JSON 形式で読み込みます。 • テーブルで、作成、読み込み、更新、削除のオペレーションを実行します。 • 簡単なクエリを実行します。 AWS SDK for .NET の DynamoDB モジュールは、異なるユースケースでいくつかのプログラミングモ デルを提供します。この演習では、C# コードはドキュメントモデル (便利な抽象化レベルを提供) と 低レベル API (入れ子の属性をより効果的に処理) の両方を使用します。ドキュメントモデル API の詳 細については、「.NET ドキュメントモデル」を参照してください。また、低レベル API の詳細につ いては、「AWS SDK for .NET の低レベル API を使用した、テーブルの操作」を参照してください。 このチュートリアルでは、ダウンロード可能なバージョンの DynamoDB を使用します。「概 要 (p. 95)」では、クラウド内の DynamoDB サービスで同じコードを実行する方法について説明し ます。 参加費: 無料 前提条件 • Microsoft Windows の最近のバージョンおよび Microsoft Visual Studio の最新バージョンを実行す るコンピュータをご使用ください。Visual Studio をまだインストールしていない場合は、Visual Studio のウェブサイトから無料の Community Edition をダウンロードできます。 • Read DynamoDB の概念について (p. 1). • DynamoDB Local をダウンロードして実行します。詳細については、「コンピュータでの DynamoDB の実行」を参照してください。 • Amazon Web Services にサインアップし、アクセスキーを作成します。AWS SDK を使用するに は、これらの認証情報が必要です。AWS アカウントを作成するには、https://aws.amazon.com/ に アクセスし、[Create an AWS Account] を選択して、オンラインの手順に従います。 • Visual Studio で DynamoDB 向けのセキュリティプロファイルを設定します。手順については、 「AWS SDK for .NET を使用した、サンプルテーブルの作成とデータのアップロード」を参照して ください。 • Visual Studio で、Installed/Templates/Visual C#/ ノードにある Console Application テンプレートを 使って DynamoDB_intro という名前の新しいプロジェクトを作成します。これは開始方法チュー トリアル全体で使用するプロジェクトとなります。 API Version 2012-08-10 67 Amazon DynamoDB 入門ガイド ステップ 1: テーブルを作成する Note 以下のチュートリアルは、同期メソッドをサポートしていないため、.NET Core には適用 されません。詳細については、「AWS の .NET 用非同期 API」を参照してください。 • AWS SDK for .NET バージョン 3 の DynamoDB モジュール用の NuGet パッケージを新しい DynamoDB_intro プロジェクトにインストールします。これを行うには、Visual Studio の [Tools] メニューから NuGet パッケージマネージャコンソールを開き、PM> プロンプトで次のコマンドを入 力します。 PM> Install-Package AWSSDK.DynamoDBv2 ステップ 1: テーブルを作成する AWS SDK for .NET のドキュメントモデルでは、テーブルは作成できないため、低レベル API (「 AWS SDK for .NET の低レベル API を使用した、テーブルの操作」を参照してください) を使用する必 要があります。 このステップでは、Movies という名前のテーブルを作成します。テーブルのプライマリキーは、以 下の属性で構成されます。 • year – パーティションキー。AttributeType は、数字 (number) の N です。 • title – ソートキー。AttributeType は、文字列 (string) の S です。 1. 次のプログラムを Program.cs ファイルにコピーして、現在のコンテンツと置き換えます。 using using using using System; System.Collections.Generic; System.IO; System.Text; using using using using Amazon; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { public static void Main( string[ ] args ) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig( ); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient( ddbConfig ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to create a DynamoDB client; " + ex.Message ); goto PauseForDebugWindow; } // Build a 'CreateTableRequest' for the new table API Version 2012-08-10 68 Amazon DynamoDB 入門ガイド ステップ 1: テーブルを作成する CreateTableRequest createRequest = new CreateTableRequest { TableName = "Movies", AttributeDefinitions = new List<AttributeDefinition>( ) { new AttributeDefinition { AttributeName = "year", AttributeType = "N" }, new AttributeDefinition { AttributeName = "title", AttributeType = "S" } }, KeySchema = new List<KeySchemaElement>( ) { new KeySchemaElement { AttributeName = "year", KeyType = "HASH" }, new KeySchemaElement { AttributeName = "title", KeyType = "RANGE" } }, }; // Provisioned-throughput settings are required even though // the local test version of DynamoDB ignores them createRequest.ProvisionedThroughput = new ProvisionedThroughput( 1, 1 ); // Using the DynamoDB client, make a synchronous CreateTable request CreateTableResponse createResponse; try { createResponse = client.CreateTable( createRequest ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to create the new table; " + ex.Message ); goto PauseForDebugWindow; } // Report the status of the new table... Console.WriteLine( "\n\n Created the \"Movies\" table successfully!\n Status of the new table: '{0}'", createResponse.TableDescription.TableStatus ); // Keep the console open if in Debug mode... PauseForDebugWindow: Console.Write( "\n\n ...Press any key to continue" ); Console.ReadKey( ); Console.WriteLine( ); } } API Version 2012-08-10 69 Amazon DynamoDB 入門ガイド ステップ 2: サンプルデータをロードする } Note • AmazonDynamoDBConfig で、ServiceURL を「http://localhost:8000」に設定して、 コンピュータで実行している DynamoDB のダウンロード可能なテストバージョンで テーブルを作成します。 • CreateTableRequest で、テーブル名およびプライマリキー属性とそのデータ型を指 定します。 • DynamoDB が項目を格納する論理パーティションを決定するプライマリキーのパー ティションキー部分は、CreateTableRequest の KeySchemaElement で KeyType 「HASH」があることで識別されます。 • 同じパーティションキー値がある項目の順序を決定するプライマリキーのソートキー 部分は、CreateTableRequest の KeySchemaElement で KeyType 「RANGE」が あることで識別されます。 • ProvisionedThroughput フィールドは、DynamoDB のダウンロード可能なテスト バージョンに無視されますが必要です。 2. コンパイルして、プログラムを実行します。 テーブルの管理の詳細については、『Amazon DynamoDB 開発者ガイド』の「テーブルの操作」を参 照してください。 ステップ 2: サンプルデータをロードする このステップでは、Movies テーブルにサンプルデータを入力します。 トピック • ステップ 2.1: サンプルデータファイルをダウンロードする (p. 71) • ステップ 2.2: 映画テーブルにサンプルデータをロードする (p. 71) サンプルデータファイルには、インターネット映画データベース (IMDb) にある数千におよぶ映画の情 報が格納されています。 映画データは JSON としてエンコードされています。各映画で、JSON は year の名前と値のペ ア、title の名前と値のペア、および複雑な info オブジェクトを定義します。その例を以下に示し ます。 { "year" : 2013, "title" : "Turn It Down, Or Else!", "info" : { "directors" : [ "Alice Smith", "Bob Jones" ], "release_date" : "2013-01-18T00:00:00Z", "rating" : 6.2, "genres" : [ "Comedy", "Drama" ], API Version 2012-08-10 70 Amazon DynamoDB 入門ガイド ステップ 2.1: サンプルデータ ファイルをダウンロードする "image_url" : "http://ia.media-imdb.com/images/N/ O9ERWAU7FS797AJ7LU8HN09AMUP908RLlo5JF90EWR7LJKQ7@@._V1_SX400_.jpg", "plot" : "A rock band plays their music at high volumes, annoying the neighbors.", "rank" : 11, "running_time_secs" : 5215, "actors" : [ "David Matthewman", "Ann Thomas", "Jonathan G. Neff" ] } } ステップ 2.1: サンプルデータファイルをダウンロー ドする 1. リンク moviedata.zip をクリックして、サンプルデータアーカイブをダウンロードします。 2. アーカイブからデータファイル (moviedata.json) を抽出します。 3. moviedata.json ファイル を DynamoDB_intro Visual Studio プロジェクトの bin/Debug フォ ルダーにコピーします。 ステップ 2.2: 映画テーブルにサンプルデータをロー ドする 開始方法のステップ 1 で作成したテーブルに映画データを読み込むプログラムを構築します。 1. このプログラムはオープンソース Newtonsoft Json.NET ライブラリを使用して JSON データを 逆シリアル化します。これは MIT License (MIT) でライセンス化されています (https://github.com/ JamesNK/Newtonsoft.Json/blob/master/LICENSE.md を参照)。 Json.NET ライブラリをプロジェクトに読み込みます。これを行うには、Visual Studio の [Tools] メニューから NuGet パッケージマネージャコンソールを開き、PM> プロンプトで次のコマンドを 入力します。 PM> Install-Package Newtonsoft.Json 2. 次のプログラムを Program.cs ファイルにコピーして、現在のコンテンツと置き換えます。 using using using using using System; System.Collections.Generic; System.IO; System.Linq; System.Text; using using using using Amazon; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.DynamoDBv2.DocumentModel; using Newtonsoft; using Newtonsoft.Json; API Version 2012-08-10 71 Amazon DynamoDB 入門ガイド ステップ 2.2: 映画テーブルに サンプルデータをロードする using Newtonsoft.Json.Linq; namespace DynamoDB_intro { class Program { public static Table GetTableObject( string tableName ) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig( ); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient( ddbConfig ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to create a DynamoDB client; " + ex.Message ); return( null ); } // Now, create a Table object for the specified table Table table; try { table = Table.LoadTable( client, tableName ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to load the 'Movies' table; " + ex.Message ); return ( null ); } return ( table ); } public static void Main( string[ ] args ) { // First, read in the JSON data from the moviedate.json file StreamReader sr = null; JsonTextReader jtr = null ; JArray movieArray = null; try { sr = new StreamReader( "moviedata.json" ); jtr = new JsonTextReader( sr ); movieArray = (JArray) JToken.ReadFrom( jtr ); } catch( Exception ex ) { Console.WriteLine( "\n Error: could not read from the 'moviedata.json' file, because: " + ex.Message ); goto PauseForDebugWindow; } finally { if( jtr != null ) jtr.Close( ); if( sr != null ) sr.Close( ); } // Get a Table object for the table that you created in Step 1 API Version 2012-08-10 72 Amazon DynamoDB 入門ガイド ステップ 3: 項目を作成、読み込み、更新、削除する Table table = GetTableObject( "Movies" ); if( table == null ) goto PauseForDebugWindow; // Load the movie data into the table (this could take some time) Console.Write( "\n Now writing {0:#,##0} movie records from moviedata.json (might take 15 minutes)...\n ...completed: ", movieArray.Count ); for( int i = 0, j = 99; i < movieArray.Count; i++ ) { try { string itemJson = movieArray[i].ToString( ); Document doc = Document.FromJson( itemJson ); table.PutItem( doc); } catch( Exception ex ) { Console.WriteLine( "\nError: Could not write the movie record #{0:#,##0}, because {1}", i, ex.Message ); goto PauseForDebugWindow; } if( i >= j ) { j++; Console.Write( "{0,5:#,##0}, ", j ); if( j % 1000 == 0 ) Console.Write( "\n " ); j += 99; } } Console.WriteLine( "\n Finished writing all movie records to DynamoDB!" ); // Keep the console open if in Debug mode... PauseForDebugWindow: Console.Write( "\n\n ...Press any key to continue" ); Console.ReadKey( ); Console.WriteLine( ); } } } 3. ここでプロジェクトをコンパイルし、デバッグモードにしたまま実行します。 ステップ 3: 項目を作成、読み込み、更新、削除 する このステップでは、Movies テーブルの項目で読み取り/書き込みオペレーションを実行します。 データの読み取りと書き込みの詳細については、『Amazon DynamoDB 開発者ガイド』の「項目の操 作」を参照してください。 トピック • ステップ 3.1: 新しい項目を作成する (p. 74) • ステップ 3.2: 項目を読み取る (p. 75) API Version 2012-08-10 73 Amazon DynamoDB 入門ガイド ステップ 3.1: 新しい項目を作成する • ステップ 3.3: 項目を更新する (p. 77) • ステップ 3.4: アトミックカウンターを増分する (p. 80) • ステップ 3.5: 項目を更新する (条件付き) (p. 82) • ステップ 3.6: 項目を削除する (p. 84) ステップ 3.1: 新しい項目を作成する このステップでは、Movies テーブルに新しい項目を追加します。 1. 次のプログラムを Program.cs ファイルにコピーして、現在のコンテンツと置き換えます。 using using using using System; System.Collections.Generic; System.Linq; System.Text; using using using using Amazon; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static void Main(string[] args) { // Get a Table object for the table that you created in Step 1 Table table = GetTableObject("Movies"); if (table == null) goto PauseForDebugWindow; // Create a Document representing the movie item to be written to the table Document document = new Document(); document["year"] = 2015; document["title"] = "The Big New Movie"; document["info"] = Document.FromJson("{\"plot\" : \"Nothing happens at all.\",\"rating\" : 0}"); // Use Table.PutItem to write the document item to the table try { table.PutItem(document); Console.WriteLine("\nPutItem succeeded.\n"); } catch (Exception ex) { Console.WriteLine("\n Error: Table.PutItem failed because: " + ex.Message); goto PauseForDebugWindow; } // Keep the console open if in Debug mode... PauseForDebugWindow: Console.Write("\n\n ...Press any key to continue"); Console.ReadKey(); API Version 2012-08-10 74 Amazon DynamoDB 入門ガイド ステップ 3.2: 項目を読み取る Console.WriteLine(); } public static Table GetTableObject(string tableName) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig(); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient(ddbConfig); } catch (Exception ex) { Console.WriteLine("\n Error: failed to create a DynamoDB client; " + ex.Message); return (null); } // Now, create a Table object for the specified table Table table = null; try { table = Table.LoadTable(client, tableName); } catch (Exception ex) { Console.WriteLine("\n Error: failed to load the 'Movies' table; " + ex.Message); return (null); } return (table); } } } Note プライマリキーは必須です。このテーブルでは、プライマリキーはパーティションキー 属性 (year) およびソートキー属性 (title) の両方の複合です。 このコードでは、2 つのプライマリキー属性 (year + title) の両方、および映画に関す る詳細を保存する複雑な info 属性を持つ項目をテーブルに書き込みます。 2. コンパイルして、プログラムを実行します。 ステップ 3.2: 項目を読み取る 前のプログラムでは、テーブルに次の項目を追加しました。 { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } Movies テーブルから項目を読み取る、GetItem メソッドを使用できます。 プライマリキー値を指定 する必要があります。そうすると year と title がわかれば、Movies から項目を読み込むことがで きます。 API Version 2012-08-10 75 Amazon DynamoDB 入門ガイド ステップ 3.2: 項目を読み取る 1. 次のプログラムを Program.cs ファイルにコピーして、現在のコンテンツと置き換えます。 using using using using System; System.Collections.Generic; System.Linq; System.Text; using using using using Amazon; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static void Main(string[] args) { // Get a Table object for the table that you created in Step 1 Table table = GetTableObject("Movies"); if (table == null) goto PauseForDebugWindow; try { Document document = table.GetItem(2015, "The Big New Movie"); if (document != null) Console.WriteLine("\nGetItem succeeded: \n" + document.ToJsonPretty()); else Console.WriteLine("\nGetItem succeeded, but the item was not found"); } catch (Exception e) { Console.WriteLine(e.Message); } // Keep the console open if in Debug mode... PauseForDebugWindow: Console.Write("\n\n ...Press any key to continue"); Console.ReadKey(); Console.WriteLine(); } public static Table GetTableObject(string tableName) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig(); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient(ddbConfig); } catch (Exception ex) { Console.WriteLine("\n Error: failed to create a DynamoDB client; " + ex.Message); return (null); } // Now, create a Table object for the specified table API Version 2012-08-10 76 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する Table table = null; try { table = Table.LoadTable(client, tableName); } catch (Exception ex) { Console.WriteLine("\n Error: failed to load the 'Movies' table; " + ex.Message); return (null); } return (table); } } } 2. コンパイルして、プログラムを実行します。 ステップ 3.3: 項目を更新する UpdateItem メソッドを使用して既存の項目を変更できます。既存の属性の値の更新、新しい属性の 追加、または属性の削除を行えます。 このチュートリアルでは、次の更新を行います。 • 既存の属性の値を変更します (rating、plot)。 • 新しいリスト属性 (actors) を既存の info マップに追加します。 項目の変更前: { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } 項目の変更後: { year: 2015, title: "The Big New Movie", info: { plot: "Everything happens all at once.", rating: 5.5, actors: ["Larry", "Moe", "Curly"] } } 1. 次のプログラムを Program.cs ファイルにコピーして、現在のコンテンツと置き換えます。 using using using using using System; System.Collections.Generic; System.Linq; System.Text; System.Threading.Tasks; API Version 2012-08-10 77 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する using using using using Amazon; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static void Main( string[ ] args ) { // Get an AmazonDynamoDBClient for the local database AmazonDynamoDBClient client = GetLocalClient( ); if( client == null ) goto PauseForDebugWindow; // Create an UpdateItemRequest to modify two existing nested attributes // and add a new one UpdateItemRequest updateRequest = new UpdateItemRequest( ) { TableName = "Movies", Key = new Dictionary<string, AttributeValue> { { "year", new AttributeValue { N = "2015" } }, { "title", new AttributeValue { S = "The Big New Movie"}} }, ExpressionAttributeValues = new Dictionary<string, AttributeValue> { { ":r", new AttributeValue { N = "5.5" } }, { ":p", new AttributeValue { S = "Everything happens all at once!" } }, { ":a", new AttributeValue { SS = { "Larry","Moe","Curly" } } } }, UpdateExpression = "SET info.rating = :r, info.plot = :p, info.actors = :a", ReturnValues = "UPDATED_NEW" }; // Use AmazonDynamoDBClient.UpdateItem to update the specified attributes UpdateItemResponse uir = null; try { uir = client.UpdateItem( updateRequest ); } catch( Exception ex ) { Console.WriteLine( "\nError: UpdateItem failed, because: " + ex.Message ); if( uir != null ) Console.WriteLine( " Status code was " + uir.HttpStatusCode.ToString( ) ); goto PauseForDebugWindow; } // Get the item from the table and display it to validate that the update succeeded DisplayMovieItem( client, "2015", "The Big New Movie" ); // Keep the console open if in Debug mode... API Version 2012-08-10 78 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する PauseForDebugWindow: Console.Write( "\n\n ...Press any key to continue" ); Console.ReadKey( ); Console.WriteLine( ); } public static AmazonDynamoDBClient GetLocalClient( ) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig( ); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient( ddbConfig ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to create a DynamoDB client; " + ex.Message ); return ( null ); } return ( client ); } public static void DisplayMovieItem( AmazonDynamoDBClient client, string year, string title ) { // Create Primitives for the HASH and RANGE portions of the primary key Primitive hash = new Primitive( year, true ); Primitive range = new Primitive( title, false ); Table table = null; try { table = Table.LoadTable( client, "Movies" ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to load the 'Movies' table; " + ex.Message ); return; } Document document = table.GetItem( hash, range ); Console.WriteLine( "\n The movie record looks like this: \n" + document.ToJsonPretty( ) ); } } } Note AWS SDK for .NET のドキュメントモデルは入れ子属性の更新をサポートしないため、 トップレベルの info 属性にある属性を更新するには、Table.UpdateItem ではな く、AmazonDynamoDBClient.UpdateItem API を使用する必要があります。 これを行うには、更新する項目と設定する新しい値を指定する UpdateItemRequest を 作成します。 • UpdateExpression は、指定した項目に対するすべての更新を定義します。 • ReturnValues フィールドを "UPDATED_NEW" に設定することで、DynamoDB に対し て更新された属性だけを応答で返すようリクエストします。 2. コンパイルして、プログラムを実行します。 API Version 2012-08-10 79 Amazon DynamoDB 入門ガイド ステップ 3.4: アトミックカウンターを増分する ステップ 3.4: アトミックカウンターを増分する DynamoDB はアトミックカウンタをサポートします。ここでは、UpdateItem メソッドを使用して、 他の書き込みリクエストに干渉することなく既存の属性の値を増やすまたは減らすことができます。 次のプログラムは、映画の rating を増分します。実行するたびに、プログラムはこの属性を 1 つ増 分します。ここでも、UpdateExpression が動作を決定します。 UpdateExpression = "SET info.rating = info.rating + :inc", 1. 次のプログラムを Program.cs ファイルにコピーして、現在のコンテンツと置き換えます。 using using using using using System; System.Collections.Generic; System.Linq; System.Text; System.Threading.Tasks; using using using using Amazon; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static void Main( string[ ] args ) { // Get an AmazonDynamoDBClient for the local database AmazonDynamoDBClient client = GetLocalClient( ); if( client == null ) goto PauseForDebugWindow; // Create an UpdateItemRequest to modify two existing nested attributes // and add a new one UpdateItemRequest updateRequest = new UpdateItemRequest( ) { TableName = "Movies", Key = new Dictionary<string, AttributeValue> { { "year", new AttributeValue { N = "2015" } }, { "title", new AttributeValue { S = "The Big New Movie"}} }, ExpressionAttributeValues = new Dictionary<string, AttributeValue> { { ":inc", new AttributeValue { N = "1" } } }, UpdateExpression = "SET info.rating = info.rating + :inc", ReturnValues = "UPDATED_NEW" }; // Use AmazonDynamoDBClient.UpdateItem to update the specified attributes UpdateItemResponse uir = null; try { uir = client.UpdateItem( updateRequest ); } API Version 2012-08-10 80 Amazon DynamoDB 入門ガイド ステップ 3.4: アトミックカウンターを増分する catch( Exception ex ) { Console.WriteLine( "\nError: UpdateItem failed, because " + ex.Message ); if( uir != null ) Console.WriteLine( " Status code was: " + uir.HttpStatusCode.ToString( ) ); goto PauseForDebugWindow; } // Get the item from the table and display it to validate that the update succeeded DisplayMovieItem( client, "2015", "The Big New Movie" ); // Keep the console open if in Debug mode... PauseForDebugWindow: Console.Write( "\n\n ...Press any key to continue" ); Console.ReadKey( ); Console.WriteLine( ); } public static AmazonDynamoDBClient GetLocalClient( ) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig( ); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient( ddbConfig ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to create a DynamoDB client; " + ex.Message ); return ( null ); } return ( client ); } public static void DisplayMovieItem( AmazonDynamoDBClient client, string year, string title ) { // Create Primitives for the HASH and RANGE portions of the primary key Primitive hash = new Primitive( year, true ); Primitive range = new Primitive( title, false ); Table table = null; try { table = Table.LoadTable( client, "Movies" ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to load the 'Movies' table; " + ex.Message ); return; } Document document = table.GetItem( hash, range ); Console.WriteLine( "\n The movie record looks like this: \n" + document.ToJsonPretty( ) ); } } API Version 2012-08-10 81 Amazon DynamoDB 入門ガイド ステップ 3.5: 項目を更新する (条件付き) } 2. コンパイルして、プログラムを実行します。 ステップ 3.5: 項目を更新する (条件付き) 次のプログラムは、条件とともに UpdateItem を使用する方法を示しています。条件が true と評価 された場合、更新は成功します。それ以外の場合、更新は行われません。 その場合、項目は 3 人より多い役者がいる場合にのみ更新されます。 1. 次のプログラムを Program.cs ファイルにコピーして、現在のコンテンツと置き換えます。 using using using using using System; System.Collections.Generic; System.Linq; System.Text; System.Threading.Tasks; using using using using Amazon; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static void Main( string[ ] args ) { // Get an AmazonDynamoDBClient for the local database AmazonDynamoDBClient client = GetLocalClient( ); if( client == null ) goto PauseForDebugScreen; // Create an UpdateItemRequest to modify two existing nested attributes // and add a new one UpdateItemRequest updateRequest = new UpdateItemRequest( ) { TableName = "Movies", Key = new Dictionary<string, AttributeValue> { { "year", new AttributeValue { N = "2015" } }, { "title", new AttributeValue { S = "The Big New Movie"} } }, ExpressionAttributeValues = new Dictionary<string, AttributeValue> { { ":n", new AttributeValue { N = "3" } } }, ConditionExpression = "size(info.actors) > :n", UpdateExpression = "REMOVE info.actors", ReturnValues = "UPDATED_NEW" }; // Use AmazonDynamoDBClient.UpdateItem to update the specified attributes UpdateItemResponse uir = null; API Version 2012-08-10 82 Amazon DynamoDB 入門ガイド ステップ 3.5: 項目を更新する (条件付き) try { uir = client.UpdateItem( updateRequest ); } catch( Exception ex ) { Console.WriteLine( "\nError: UpdateItem failed, because:\n ex.Message ); if( uir != null ) Console.WriteLine( " Status code was " + uir.HttpStatusCode.ToString( ) ); goto PauseForDebugScreen; } if( uir.HttpStatusCode != System.Net.HttpStatusCode.OK ) { goto PauseForDebugScreen; } " + // Get the item from the table and display it to validate that the update succeeded DisplayMovieItem( client, "2015", "The Big New Movie" ); // Keep the console open if running in Debug mode... PauseForDebugScreen: Console.Write( "\n\n ...Press any key to continue" ); Console.ReadKey( ); Console.WriteLine( ); } public static AmazonDynamoDBClient GetLocalClient( ) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig( ); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient( ddbConfig ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to create a DynamoDB client; " + ex.Message ); return ( null ); } return ( client ); } public static void DisplayMovieItem( AmazonDynamoDBClient client, string year, string title ) { // Create Primitives for the HASH and RANGE portions of the primary key Primitive hash = new Primitive( year, true ); Primitive range = new Primitive( title, false ); Table table = null; try { table = Table.LoadTable( client, "Movies" ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to load the 'Movies' table; " + ex.Message ); return; } Document document = table.GetItem( hash, range ); API Version 2012-08-10 83 Amazon DynamoDB 入門ガイド ステップ 3.6: 項目を削除する Console.WriteLine( "\n The movie record looks like this: \n" + document.ToJsonPretty( ) ); } } } 2. コンパイルして、プログラムを実行します。 プログラムは次のメッセージで失敗するはずです。 The conditional request failed これは、映画に 3 人の役者が出演しているが、条件は役者が 3 人より多いことをチェックしてい るためです。 3. ConditionExpression が使用する役者の人数が 3 人ではなく 2 人になるようにプログラムを変 更します。 { ":n", new AttributeValue { N = "2" } } これにより、この条件は役者の人数が 2 人より大きくなる必要があることを指定します。 4. プログラムをコンパイルして実行すると、UpdateItem オペレーションは成功するはずです。 ステップ 3.6: 項目を削除する プライマリキーを指定することで、Table.DeleteItem オペレーションを使用して項目を削除でき ます。またオプションとして、DeleteItemOperationConfig パラメーターに条件を指定し、条件 が満たされない場合に項目が削除されるのを防ぐことができます。 次の例では、レーティングが 5 以下の特定の映画項目を削除しようとします。 1. 次のプログラムを Program.cs ファイルにコピーして、現在のコンテンツと置き換えます。 using using using using using System; System.Collections.Generic; System.Linq; System.Text; System.Threading.Tasks; using using using using Amazon; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static void Main( string[ ] args ) { // Get a Table object for the table that you created in Step 1 Table table = GetTableObject( "Movies" ); if( table == null ) return; // Create the condition API Version 2012-08-10 84 Amazon DynamoDB 入門ガイド ステップ 3.6: 項目を削除する DeleteItemOperationConfig opConfig = new DeleteItemOperationConfig( ); opConfig.ConditionalExpression = new Expression( ); opConfig.ConditionalExpression.ExpressionAttributeValues[":val"] = "5.0"; opConfig.ConditionalExpression.ExpressionStatement = "info.rating <= :val"; // Delete this item try { table.DeleteItem( 2015, "The Big New Movie", opConfig ); } catch( Exception ex ) { Console.WriteLine( "\n Error: Could not delete the movie item with year={0}, title=\"{1}\"\n Reason: {2}.", 2015, "The Big New Movie", ex.Message ); } // Try to retrieve it, to see if it has been deleted Document document = table.GetItem( 2015, "The Big New Movie" ); if( document == null ) Console.WriteLine( "\n The movie item with year={0}, title=\"{1}\" has been deleted.", 2015, "The Big New Movie" ); else Console.WriteLine( "\nRead back the item: \n" + document.ToJsonPretty( ) ); // Keep the console open if in Debug mode... Console.Write( "\n\n ...Press any key to continue" ); Console.ReadKey( ); Console.WriteLine( ); } public static Table GetTableObject( string tableName ) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig( ); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient( ddbConfig ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to create a DynamoDB client; " + ex.Message ); return ( null ); } // Now, create a Table object for the specified table Table table = null; try { table = Table.LoadTable( client, tableName ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to load the 'Movies' table; " + ex.Message ); return ( null ); } return ( table ); } } API Version 2012-08-10 85 Amazon DynamoDB 入門ガイド ステップ 4: データをクエリおよびスキャンする } 2. コンパイルして、プログラムを実行します。 プログラムは次のメッセージで失敗するはずです。 The conditional request failed 3. これは、この特定の映画のレーティングが 5 より大きいためです。 table.DeleteItem への呼び出しで opConfig という名前の DeleteItemOperationConfig を削除するためにプログラムを変更します。 try { table.DeleteItem( 2015, "The Big New Movie" ); } 4. コンパイルして、プログラムを実行します。ここでは、条件を削除したため、削除が成功しま す。 ステップ 4: データをクエリおよびスキャンする Query メソッドを使用して、テーブルからデータを取得できます。パーティションのキー値を指定す る必要があります。ソートキーはオプションです。 Movies テーブルのプライマリキーは、以下の内容で構成されます。 • year – パーティションキー。属性タイプは数値です。 • title – ソートキー。属性タイプは文字列です。 ある年にリリースされたすべての映画を見つけるには、year パーティションキー属性のみを指定する 必要があります。title ソートキー属性を追加して、ある条件 (ソートキー属性上) に基づいた映画の サブセットを取得することができます。たとえば、2014 年にリリースされた、主題が「A」で始まる 映画を見つける場合などです。 Query に加えて、すべてのテーブルデータを取得可能な Scan メソッドもあります。 データのクエリとスキャンの詳細については、『Amazon DynamoDB 開発者ガイド』の「クエリおよ びスキャン」を参照してください。 トピック • ステップ 4.1: クエリ (p. 86) • ステップ 4.2: スキャン (p. 91) ステップ 4.1: クエリ このステップに含まれている C# コードは、以下のクエリを実行します。 • year 1985 にリリースされたすべての映画を取得します。 • year 1992 にリリースされたすべての映画で、title が「A」から「L」で始まるすべての映画を取 得します。 1. 次のプログラムを Program.cs ファイルにコピーして、現在のコンテンツと置き換えます。 using System; using System.Collections.Generic; using System.Linq; API Version 2012-08-10 86 Amazon DynamoDB 入門ガイド ステップ 4.1: クエリ using System.Text; using System.Threading.Tasks; using using using using Amazon; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static string commaSep = ", "; static string movieFormatString = " genres: {2}"; \"{0}\", lead actor: {1}, static void Main( string[ ] args ) { // Get an AmazonDynamoDBClient for the local DynamoDB database AmazonDynamoDBClient client = GetLocalClient( ); // Get a Table object for the table that you created in Step 1 Table table = GetTableObject( client, "Movies" ); if( table == null ) goto PauseForDebugWindow; / *----------------------------------------------------------------------* 4.1.1: Call Table.Query to initiate a query for all movies with * year == 1985, using an empty filter expression. *----------------------------------------------------------------------*/ Search search; try { search = table.Query( 1985, new Expression( ) ); } catch( Exception ex ) { Console.WriteLine( "\n Error: 1985 query failed because: " + ex.Message ); goto PauseForDebugWindow; } // Display the titles of the movies returned by this query List<Document> docList = new List<Document>( ); Console.WriteLine( "\n All movies released in 1985:" + "\n-----------------------------------------------" ); do { try { docList = search.GetNextSet( ); } catch( Exception ex ) { Console.WriteLine( "\n Error: Search.GetNextStep failed because: " + ex.Message ); break; } foreach( var doc in docList ) Console.WriteLine( " " + doc["title"] ); } while( !search.IsDone ); API Version 2012-08-10 87 Amazon DynamoDB 入門ガイド ステップ 4.1: クエリ / *----------------------------------------------------------------------* 4.1.2a: Call Table.Query to initiate a query for all movies where * year equals 1992 AND title is between "B" and "Hzzz", * returning the lead actor and genres of each. *----------------------------------------------------------------------*/ Primitive y_1992 = new Primitive( "1992", true ); QueryOperationConfig config = new QueryOperationConfig( ); config.Filter = new QueryFilter( ); config.Filter.AddCondition( "year", QueryOperator.Equal, new DynamoDBEntry[ ] { 1992 } ); config.Filter.AddCondition( "title", QueryOperator.Between, new DynamoDBEntry[ ] { "B", "Hzz" } ); config.AttributesToGet = new List<string> { "title", "info" }; config.Select = SelectValues.SpecificAttributes; try { search = table.Query( config ); } catch( Exception ex ) { Console.WriteLine( "\n Error: 1992 query failed because: " + ex.Message ); goto PauseForDebugWindow; } // Display the movie information returned by this query Console.WriteLine( "\n\n Movies released in 1992 with titles between \"B\" and \"Hzz\" (Document Model):" + "\n-----------------------------------------------------------------------------" ); docList = new List<Document>( ); Document infoDoc; do { try { docList = search.GetNextSet( ); } catch( Exception ex ) { Console.WriteLine( "\n Error: Search.GetNextStep failed because: " + ex.Message ); break; } foreach( var doc in docList ) { infoDoc = doc["info"].AsDocument( ); Console.WriteLine( movieFormatString, doc["title"], infoDoc["actors"].AsArrayOfString( )[0], string.Join( commaSep, infoDoc["genres"].AsArrayOfString( ) ) ); } } while( !search.IsDone ); / *----------------------------------------------------------------------API Version 2012-08-10 88 Amazon DynamoDB 入門ガイド ステップ 4.1: クエリ * 4.1.2b: Call AmazonDynamoDBClient.Query to initiate a query for all * and Tzz, * movies where year equals 1992 AND title is between M returning the genres and the lead actor of each. *----------------------------------------------------------------------*/ QueryRequest qRequest = new QueryRequest { TableName = "Movies", ExpressionAttributeNames = new Dictionary<string,string> { { "#yr", "year" } }, ExpressionAttributeValues = new Dictionary<string,AttributeValue> { { ":y_1992", new AttributeValue { N = "1992" } }, { ":M", new AttributeValue { S = "M" } }, { ":Tzz", new AttributeValue { S = "Tzz" } } }, KeyConditionExpression = "#yr = :y_1992 and title between :M and :Tzz", ProjectionExpression = "title, info.actors[0], info.genres" }; QueryResponse qResponse; try { qResponse = client.Query( qRequest ); } catch( Exception ex ) { Console.WriteLine( "\n Error: Low-level query failed, because: " + ex.Message ); goto PauseForDebugWindow; } // Display the movie information returned by this query Console.WriteLine( "\n\n Movies released in 1992 with titles between \"M\" and \"Tzz\" (low-level):" + "\n-------------------------------------------------------------------------" ); foreach( Dictionary<string, AttributeValue> item in qResponse.Items) { Dictionary<string,AttributeValue> info = item["info"].M; Console.WriteLine( movieFormatString, item["title"].S, info["actors"].L[0].S, GetDdbListAsString( info["genres"].L ) ); } // Keep the console open if in Debug mode... PauseForDebugWindow: Console.Write( "\n\n ...Press any key to continue" ); Console.ReadKey( ); Console.WriteLine( ); } public static string GetDdbListAsString( List<AttributeValue> strList ) { API Version 2012-08-10 89 Amazon DynamoDB 入門ガイド ステップ 4.1: クエリ StringBuilder sb = new StringBuilder( ); string str = null; AttributeValue av; for( int i = 0; i < strList.Count; i++ ) { av = strList[i]; if( av.S != null ) str = av.S; else if( av.N != null ) str = av.N; else if( av.SS != null ) str = string.Join( commaSep, av.SS.ToArray( ) ); else if( av.NS != null ) str = string.Join( commaSep, av.NS.ToArray( ) ); if( str != null ) { if( i > 0 ) sb.Append( commaSep ); sb.Append( str ); } } return( sb.ToString( ) ); } public static AmazonDynamoDBClient GetLocalClient( ) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig( ); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient( ddbConfig ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to create a DynamoDB client; " + ex.Message ); return ( null ); } return ( client ); } public static Table GetTableObject( AmazonDynamoDBClient client, string tableName ) { Table table = null; try { table = Table.LoadTable( client, tableName ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to load the 'Movies' table; " + ex.Message ); return ( null ); } return ( table ); } } } API Version 2012-08-10 90 Amazon DynamoDB 入門ガイド ステップ 4.2: スキャン Note • 最初のクエリでは、1985 年にリリースされたすべての映画について、空の文字列はプ ライマリキーのソートキー部分のフィルタリングが望まれないことを示しています。 • 2 つ目のクエリでは、AWS SDK for .NET ドキュメントモデルを使用して 1992 年にリ リースされたすべての映画で、主題が「A」から「L」で始まる映画をクエリしていま す。ここではトップレベルの属性しかクエリできないため、info 属性すべてを取得す る必要があります。その後、表示コードは対象となる入れ子属性にアクセスします。 • 3 つ目のクエリでは、何が返されるかをより詳細に制御できる低レベル AWS SDK for .NET API を使用しています。ここでは、対象となる info 属性内の入れ子属性、つ まり info.genres および info.actors[0] のみを取得できます。 2. コンパイルして、プログラムを実行します。 Note 前のプログラムは、プライマリキーの属性によってテーブルをクエリする方法を示していま す。DynamoDB では、必要に応じて 1 つ以上のセカンダリインデックスをテーブルに作成 し、テーブルをクエリするのと同じ方法でそれらのインデックスをクエリすることもできま す。セカンダリインデックスは非キー属性のクエリを可能にすることで、アプリケーション に追加の柔軟性を提供します。詳細については、Amazon DynamoDB 開発者ガイドの「セカ ンダリインデックス」を参照してください。 ステップ 4.2: スキャン Scan メソッドは、テーブル全体のすべての項目を読み込み、テーブルの全データを返します。オプ ションで filter_expression を提供して、条件に一致する項目だけが返されるように指定できま す。ただし、テーブル全体がスキャンされた後にのみ、フィルタが適用されることに注意してくださ い。 次のプログラムは、約 5,000 項目を含む Movies テーブル全体をスキャンします。スキャンは、1950 年代の映画のみ (約 100 項目) を取得して、残りはすべて破棄するようオプションのフィルタを指定し ます。 1. 次のプログラムを Program.cs ファイルにコピーして、現在のコンテンツと置き換えます。 using using using using using System; System.Collections.Generic; System.Linq; System.Text; System.Threading.Tasks; using using using using Amazon; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.DynamoDBv2.DocumentModel; namespace DynamoDB_intro { class Program { static void Main( string[ ] args ) { // Get an AmazonDynamoDBClient for the local DynamoDB database AmazonDynamoDBClient client = GetLocalClient( ); API Version 2012-08-10 91 Amazon DynamoDB 入門ガイド ステップ 4.2: スキャン // Get a Table object for the table that you created in Step 1 Table table = GetTableObject( client, "Movies" ); if( table == null ) goto PauseForDebugWindow; / *----------------------------------------------------------------------* 4.2a: Call Table.Scan to return the movies released in the 1950's, * displaying title, year, lead actor and lead director. *----------------------------------------------------------------------*/ ScanFilter filter = new ScanFilter( ); filter.AddCondition( "year", ScanOperator.Between, new DynamoDBEntry[ ] { 1950, 1959 } ); ScanOperationConfig config = new ScanOperationConfig { AttributesToGet = new List<string> { "year, title, info" }, Filter = filter }; Search search = table.Scan( filter ); // Display the movie information returned by this query Console.WriteLine( "\n\n Movies released in the 1950's (Document Model):" + "\n--------------------------------------------------" ); List<Document> docList = new List<Document>( ); Document infoDoc; string movieFormatString = " \"{0}\" ({1})-- lead actor: {2}, lead director: {3}"; do { try { docList = search.GetNextSet( ); } catch( Exception ex ) { Console.WriteLine( "\n Error: Search.GetNextStep failed because: " + ex.Message ); break; } foreach( var doc in docList ) { infoDoc = doc["info"].AsDocument( ); Console.WriteLine( movieFormatString, doc["title"], doc["year"], infoDoc["actors"].AsArrayOfString( )[0], infoDoc["directors"].AsArrayOfString( )[0] ); } } while( !search.IsDone ); / *----------------------------------------------------------------------* 4.2b: Call AmazonDynamoDBClient.Scan to return all movies released * in the 1960's, only downloading the title, year, lead API Version 2012-08-10 92 Amazon DynamoDB 入門ガイド ステップ 4.2: スキャン * actor and lead director attributes. *----------------------------------------------------------------------*/ ScanRequest sRequest = new ScanRequest { TableName = "Movies", ExpressionAttributeNames = new Dictionary<string, string> { { "#yr", "year" } }, ExpressionAttributeValues = new Dictionary<string, AttributeValue> { { ":y_a", new AttributeValue { N = "1960" } }, { ":y_z", new AttributeValue { N = "1969" } }, }, FilterExpression = "#yr between :y_a and :y_z", ProjectionExpression = "#yr, title, info.actors[0], info.directors[0]" }; ScanResponse sResponse; try { sResponse = client.Scan( sRequest ); } catch( Exception ex ) { Console.WriteLine( "\n Error: Low-level scan failed, because: " + ex.Message ); goto PauseForDebugWindow; } // Display the movie information returned by this scan Console.WriteLine( "\n\n Movies released in the 1960's (low-level):" + "\n-------------------------------------------" ); foreach( Dictionary<string, AttributeValue> item in sResponse.Items ) { Dictionary<string,AttributeValue> info = item["info"].M; Console.WriteLine( movieFormatString, item["title"].S, item["year"].N, info["actors"].L[0].S, info["directors"].L[0].S ); } // Keep the console open if in Debug mode... PauseForDebugWindow: Console.Write( "\n\n ...Press any key to continue" ); Console.ReadKey( ); Console.WriteLine( ); } public static AmazonDynamoDBClient GetLocalClient( ) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig( ); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient( ddbConfig ); } API Version 2012-08-10 93 Amazon DynamoDB 入門ガイド ステップ 5: (オプション) テーブルを削除する catch( Exception ex ) { Console.WriteLine( "\n Error: failed to create a DynamoDB client; " + ex.Message ); return ( null ); } return ( client ); } public static Table GetTableObject( AmazonDynamoDBClient client, string tableName ) { Table table = null; try { table = Table.LoadTable( client, tableName ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to load the 'Movies' table; " + ex.Message ); return ( null ); } return ( table ); } } } このコードでは、以下の点に注意してください。 • 最初のスキャンでは、AWS SDK for .NET ドキュメントモデルを使用して Movies テー ブルをスキャンし、1950 年代にリリースされた映画を返します。ドキュメントモデルは AttributesToGet フィールドで入れ子属性をサポートしないため、主演男優と映画監督にア クセスするには info 属性全体をダウンロードする必要があります。 • 2 つ目のスキャンでは、AWS SDK for .NET の低レベル API を使用して Movies テーブルをス キャンし、1960 年代にリリースされた映画を返します。この場合、対象となる info の属性 値、つまり info.actors[0] および info.directors[0] のみをダウンロードできます。 2. コンパイルして、プログラムを実行します。 Note テーブルで作成した任意のセカンダリインデックスで Scan オペレーションを使用すること もできます。詳細については、Amazon DynamoDB 開発者ガイドの「セカンダリインデック ス」を参照してください。 ステップ 5: (オプション) テーブルを削除する Movies テーブルを削除するには: 1. 次のプログラムを Program.cs ファイルにコピーして、現在のコンテンツと置き換えます。 using System; using System.Text; using Amazon.DynamoDBv2; using Amazon.DynamoDBv2.Model; API Version 2012-08-10 94 Amazon DynamoDB 入門ガイド 概要 namespace DynamoDB_intro { class Program { static void Main( string[ ] args ) { // Get an AmazonDynamoDBClient for the local DynamoDB database AmazonDynamoDBClient client = GetLocalClient( ); try { client.DeleteTable( "Movies" ); } catch( Exception ex ) { Console.WriteLine( "\n Error: the \'Movies\" table could not be deleted!\n Reason: " + ex.Message ); goto PauseForDebugWindow; } Console.WriteLine( "\n Deleted the \'Movies\" table successfully!" ); // Keep the console open if in Debug mode... PauseForDebugWindow: Console.Write( "\n\n ...Press any key to continue" ); Console.ReadKey( ); Console.WriteLine( ); } public static AmazonDynamoDBClient GetLocalClient( ) { // First, set up a DynamoDB client for DynamoDB Local AmazonDynamoDBConfig ddbConfig = new AmazonDynamoDBConfig( ); ddbConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client; try { client = new AmazonDynamoDBClient( ddbConfig ); } catch( Exception ex ) { Console.WriteLine( "\n Error: failed to create a DynamoDB client; " + ex.Message ); return ( null ); } return ( client ); } } } 2. コンパイルして、プログラムを実行します。 概要 このチュートリアルでは、ご使用のコンピューターの DynamoDB で Movies テーブルを作成し、基 本的なオペレーションを実行しました。DynamoDB Local はアプリケーションの開発とテストにおい て役立ちます。ただし、本番環境でアプリケーションを実行する場合、Amazon DynamoDB サービス を使用できるようにコードを変更します。 Amazon DynamoDB サービスを使用する Amazon DynamoDB サービスを使用するには、アプリケーションのエンドポイントを変更する必要が あります。これを行うには、まず次の行を削除します。 API Version 2012-08-10 95 Amazon DynamoDB 入門ガイド Amazon DynamoDB サービスを使用する ddbConfig.ServiceURL = "http://localhost:8000"; 次に、アクセスする AWS リージョンを指定する新しい行を追加します。 ddbConfig.RegionEndpoint = RegionEndpoint.REGION; たとえば、us-west-2 region にアクセスする場合、次のようにします。 ddbConfig.RegionEndpoint = RegionEndpoint.USWest2; 次に、プログラムは DynamoDB Local を使用する代わりに、米国西部 (オレゴン) の DynamoDB サー ビスエンドポイントを使用します。 Amazon DynamoDB は、世界中の AWS リージョンで利用できます。完全なリストについては、AWS General Referenceの「リージョンとエンドポイント」を参照してください。コードにリージョンおよ びエンドポイントを設定するための詳細については、『AWS SDK for .NET 開発者ガイド』の「AWS リージョンの選択」を参照してください。 最後に、「Amazon DynamoDB 開発者ガイド」を読むことをお勧めします。ここには、サンプルコー ドやベストプラクティスなど、DynamoDB に関するさらに詳しい情報が収められています。 API Version 2012-08-10 96 Amazon DynamoDB 入門ガイド 前提条件 PHP および DynamoDB このチュートリアルでは、AWS SDK for PHP を使用して次の Amazon DynamoDB オペレーションを 実行するシンプルなプログラムを作成します。 • Movies というテーブルを作成し、JSON形式のサンプルデータをロードします。 • テーブルで、作成、読み込み、更新、削除のオペレーションを実行します。 • 簡単なクエリを実行します。 このチュートリアルでは、ダウンロード可能なバージョンの DynamoDB を使用します。概 要 (p. 116) では、DynamoDB サービスに対して同じコードを実行する方法について説明します。 参加費: 無料 前提条件 • Read DynamoDB の概念について (p. 1). • DynamoDB をダウンロードしてコンピュータで実行します。詳細については、「DynamoDB のダ ウンロードと実行 (p. 4)」を参照してください。 • Amazon Web Services にサインアップし、アクセスキーを作成します。AWS SDK を使用するに は、これらの認証情報が必要です。AWS アカウントを作成するには、https://aws.amazon.com/ に アクセスし、[Create an AWS Account] を選択して、オンラインの手順に従います。 • AWS 認証情報ファイルを作成します。詳細については、『AWS SDK for PHP Getting Started Guide』の「Using the AWS credentials file and credential profiles」を参照してください。 • AWS SDK for PHP のセットアップ: • http://php.net にアクセスし、PHP をインストールします。 • https://aws.amazon.com/sdk-for-php にアクセスし、AWS SDK for PHP をインストールします。 詳細については、AWS SDK for PHP Getting Started Guide の Getting Started を参照してくださ い。 Tip このチュートリアルを行うときは、『AWS SDK for PHP Developer Guide』を参照でき ます。『AWS SDK for PHP API Reference』の「Amazon DynamoDB セクション」で は、DynamoDB オペレーションのパラメーターと結果について説明されています。 API Version 2012-08-10 97 Amazon DynamoDB 入門ガイド ステップ 1: テーブルを作成する ステップ 1: テーブルを作成する このステップでは、Movies という名前のテーブルを作成します。テーブルのプライマリキーは、以 下の 2 つの属性で構成されます。 • year – パーティションキー。AttributeType は、数字 (number) の N です。 • title – ソートキー。AttributeType は、文字列 (string) の S です。 1. 次のプログラムを MoviesCreateTable.php というファイルにコピーします。 <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $params = [ 'TableName' => 'Movies', 'KeySchema' => [ [ 'AttributeName' => 'year', 'KeyType' => 'HASH' //Partition key ], [ 'AttributeName' => 'title', 'KeyType' => 'RANGE' //Sort key ] ], 'AttributeDefinitions' => [ [ 'AttributeName' => 'year', 'AttributeType' => 'N' ], [ 'AttributeName' => 'title', 'AttributeType' => 'S' ], ], 'ProvisionedThroughput' => [ 'ReadCapacityUnits' => 10, 'WriteCapacityUnits' => 10 ] ]; try { $result = $dynamodb->createTable($params); API Version 2012-08-10 98 Amazon DynamoDB 入門ガイド ステップ 2: サンプルデータをロードする echo 'Created table. Status: ' . $result['TableDescription']['TableStatus'] ."\n"; } catch (DynamoDbException $e) { echo "Unable to create table:\n"; echo $e->getMessage() . "\n"; } ?> Note • エンドポイントを設定して、コンピュータの DynamoDB にテーブルを作成することを 示します。 • createTable 呼び出しでは、テーブル名、プライマリキー属性、そのデータ型を指定 します。 • ProvisionedThroughput パラメーターは必須ですが、ダウンロード可能なバージョ ンの DynamoDB では無視されます。(プロビジョニングされたスループットはこの演 習では扱いません。) 2. 次のコマンドを入力してコマンドを実行します。 php MoviesCreateTable.php テーブルの管理の詳細については、『Amazon DynamoDB 開発者ガイド』の「テーブルの操作」を参 照してください。 ステップ 2: サンプルデータをロードする このステップでは、Movies テーブルにサンプルデータを入力します。 トピック • ステップ 2.1: サンプルデータファイルをダウンロードする (p. 100) • ステップ 2.2: 映画テーブルにサンプルデータをロードする (p. 100) サンプルデータファイルには、インターネット映画データベース (IMDb) にある数千におよぶ映 画の情報が格納されています。映画データは、次の例に示すように JSON 形式です。映画ごと に、year、title、および info という JSON マップが設定されています。 [ { "year" : ... , "title" : ... , "info" : { ... } }, { "year" : ..., "title" : ..., "info" : { ... } }, ... ] API Version 2012-08-10 99 Amazon DynamoDB 入門ガイド ステップ 2.1: サンプルデータ ファイルをダウンロードする JSON データで次の点に注意してください。 • year と title を、Movies テーブルのプライマリキー属性値として使用します。 • 残りの info 値は、info という単一の属性に保存されます。このプログラムは、JSON を DynamoDB 属性で保存する方法を示しています。 以下は、映画データの例です。 { "year" : 2013, "title" : "Turn It Down, Or Else!", "info" : { "directors" : [ "Alice Smith", "Bob Jones" ], "release_date" : "2013-01-18T00:00:00Z", "rating" : 6.2, "genres" : [ "Comedy", "Drama" ], "image_url" : "http://ia.media-imdb.com/images/N/ O9ERWAU7FS797AJ7LU8HN09AMUP908RLlo5JF90EWR7LJKQ7@@._V1_SX400_.jpg", "plot" : "A rock band plays their music at high volumes, annoying the neighbors.", "rank" : 11, "running_time_secs" : 5215, "actors" : [ "David Matthewman", "Ann Thomas", "Jonathan G. Neff" ] } } ステップ 2.1: サンプルデータファイルをダウンロー ドする 1. リンク moviedata.zip をクリックして、サンプルデータアーカイブをダウンロードします。 2. アーカイブからデータファイル (moviedata.json) を抽出します。 3. 現在のディレクトリに moviedata.json ファイルをコピーします。 ステップ 2.2: 映画テーブルにサンプルデータをロー ドする サンプルデータをダウンロードすると、次のプログラムを実行して Movies テーブルに入力できま す。 1. 次のプログラムを MoviesLoadData.php というファイルにコピーします。 API Version 2012-08-10 100 Amazon DynamoDB 入門ガイド ステップ 2.2: 映画テーブルに サンプルデータをロードする <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; use Aws\DynamoDb\Marshaler; $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $marshaler = new Marshaler(); $tableName = 'Movies'; $movies = json_decode(file_get_contents('moviedata.json'), true); foreach ($movies as $movie) { $year = $movie['year']; $title = $movie['title']; $info = $movie['info']; $json = json_encode([ 'year' => $year, 'title' => $title, 'info' => $info ]); $params = [ 'TableName' => $tableName, 'Item' => $marshaler->marshalJson($json) ]; try { $result = $dynamodb->putItem($params); echo "Added movie: " . $movie['year'] . " " . $movie['title'] . "\n"; } catch (DynamoDbException $e) { echo "Unable to add movie:\n"; echo $e->getMessage() . "\n"; break; } } ?> Note DynamoDB マーシャラークラスには、JSON ドキュメントと PHP 配列を DynamoDB 形式に変換するメソッドが用意されています。このプログラムでは、$marshaler- API Version 2012-08-10 101 Amazon DynamoDB 入門ガイド ステップ 3: 項目を作成、読み込み、更新、削除する >marshalJson($json) は JSON ドキュメントを取得して DynamoDB 項目に変換しま す。 2. 次のコマンドを入力してコマンドを実行します。 php MoviesLoadData.php ステップ 3: 項目を作成、読み込み、更新、削除 する このステップでは、Movies テーブルの項目で読み取り/書き込みオペレーションを実行します。 データの読み取りと書き込みの詳細については、『Amazon DynamoDB 開発者ガイド』の「項目の操 作」を参照してください。 トピック • ステップ 3.1: 新しい項目を作成する (p. 102) • ステップ 3.2: 項目を読み取る (p. 103) • ステップ 3.3: 項目を更新する (p. 104) • ステップ 3.4: アトミックカウンターを増分する (p. 106) • ステップ 3.5: 項目を更新する (条件付き) (p. 107) • ステップ 3.6: 項目を削除する (p. 109) ステップ 3.1: 新しい項目を作成する このステップでは、Movies テーブルに新しい項目を追加します。 1. 次のプログラムを MoviesItemOps01.php というファイルにコピーします。 <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; use Aws\DynamoDb\Marshaler; $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $marshaler = new Marshaler(); $tableName = 'Movies'; $year = 2015; $title = 'The Big New Movie'; $item = $marshaler->marshalJson(' { "year": ' . $year . ', API Version 2012-08-10 102 Amazon DynamoDB 入門ガイド ステップ 3.2: 項目を読み取る "title": "' . $title . '", "info": { "plot": "Nothing happens at all.", "rating": 0 } } '); $params = [ 'TableName' => 'Movies', 'Item' => $item ]; try { $result = $dynamodb->putItem($params); echo "Added item: $year - $title\n"; } catch (DynamoDbException $e) { echo "Unable to add item:\n"; echo $e->getMessage() . "\n"; } ?> Note 2. プライマリキーは必須です。このコードは、プライマリキー (year, title) と info 属 性を持つ項目を追加します。info 属性には、映画についての詳細情報を示すマップが保 存されます。 次のコマンドを入力してコマンドを実行します。 php MoviesItemOps01.php ステップ 3.2: 項目を読み取る 前のプログラムでは、テーブルに次の項目を追加しました。 { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } Movies テーブルから項目を読み取る、getItem メソッドを使用できます。 プライマリキー値を指定 する必要があります。そうすると year と title がわかれば、Movies から項目を読み込むことがで きます。 1. 次のプログラムを MoviesItemOps02.php というファイルにコピーします。 <?php require 'vendor/autoload.php'; API Version 2012-08-10 103 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; use Aws\DynamoDb\Marshaler; $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $marshaler = new Marshaler(); $tableName = 'Movies'; $year = 2015; $title = 'The Big New Movie'; $key = $marshaler->marshalJson(' { "year": ' . $year . ', "title": "' . $title . '" } '); $params = [ 'TableName' => $tableName, 'Key' => $key ]; try { $result = $dynamodb->getItem($params); print_r($result["Item"]); } catch (DynamoDbException $e) { echo "Unable to get item:\n"; echo $e->getMessage() . "\n"; } ?> 2. 次のコマンドを入力してコマンドを実行します。 php MoviesItemOps02.php ステップ 3.3: 項目を更新する updateItem メソッドを使用して既存の項目を変更できます。既存の属性の値の更新、新しい属性の 追加、または属性の削除を行えます。 このチュートリアルでは、次の更新を行います。 • 既存の属性の値を変更します (rating、plot)。 • 新しいリスト属性 (actors) を既存の info マップに追加します。 項目の変更前: API Version 2012-08-10 104 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } 項目の変更後: { year: 2015, title: "The Big New Movie", info: { plot: "Everything happens all at once.", rating: 5.5, actors: ["Larry", "Moe", "Curly"] } } 1. 次のプログラムを MoviesItemOps03.php というファイルにコピーします。 <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; use Aws\DynamoDb\Marshaler; $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $marshaler = new Marshaler(); $tableName = 'Movies'; $year = 2015; $title = 'The Big New Movie'; $key = $marshaler->marshalJson(' { "year": ' . $year . ', "title": "' . $title . '" } '); $eav = $marshaler->marshalJson(' { ":r": 5.5 , ":p": "Everything happens all at once.", API Version 2012-08-10 105 Amazon DynamoDB 入門ガイド ステップ 3.4: アトミックカウンターを増分する ":a": [ "Larry", "Moe", "Curly" ] } '); $params = [ 'TableName' => $tableName, 'Key' => $key, 'UpdateExpression' => 'set info.rating = :r, info.plot=:p, info.actors=:a', 'ExpressionAttributeValues'=> $eav, 'ReturnValues' => 'UPDATED_NEW' ]; try { $result = $dynamodb->updateItem($params); echo "Updated item.\n"; print_r($result['Attributes']); } catch (DynamoDbException $e) { echo "Unable to update item:\n"; echo $e->getMessage() . "\n"; } ?> Note このプログラムでは、UpdateExpression を使用して、指定された項目で実行するすべ ての更新を記述します。 ReturnValues パラメーターは、DynamoDB に更新された属性 (UPDATED_NEW) のみを 返すように指示します。 2. 次のコマンドを入力してコマンドを実行します。 php MoviesItemOps03.php ステップ 3.4: アトミックカウンターを増分する DynamoDB では、アトミックカウンターがサポートされています。そのため、updateItem メソッド を使用して、他の書き込みリクエストを妨げることなく既存の属性値をインクリメントまたはデクリ メントできます。(すべての書き込みリクエストは、受信された順に適用されます)。 次のプログラムは、映画の rating を増分する方法を示しています。実行するたびに、プログラムは この属性を 1 つ増分します。 1. 次のプログラムを MoviesItemOps04.php というファイルにコピーします。 <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; use Aws\DynamoDb\Marshaler; $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', API Version 2012-08-10 106 Amazon DynamoDB 入門ガイド ステップ 3.5: 項目を更新する (条件付き) 'region' 'version' => 'us-west-2', => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $marshaler = new Marshaler(); $tableName = 'Movies'; $year = 2015; $title = 'The Big New Movie'; $key = $marshaler->marshalJson(' { "year": ' . $year . ', "title": "' . $title . '" } '); $eav = $marshaler->marshalJson(' { ":val": 1 } '); $params = [ 'TableName' => $tableName, 'Key' => $key, 'UpdateExpression' => 'set info.rating = info.rating + :val', 'ExpressionAttributeValues'=> $eav, 'ReturnValues' => 'UPDATED_NEW' ]; try { $result = $dynamodb->updateItem($params); echo "Updated item. ReturnValues are:\n"; print_r($result['Attributes']); } catch (DynamoDbException $e) { echo "Unable to update item:\n"; echo $e->getMessage() . "\n"; } ?> 2. 次のコマンドを入力してコマンドを実行します。 php MoviesItemOps04.php ステップ 3.5: 項目を更新する (条件付き) 次のプログラムは、条件とともに UpdateItem を使用する方法を示しています。条件が true と評価 された場合、更新は成功します。それ以外の場合、更新は行われません。 その場合、項目は 3 人より多い役者がいる場合にのみ更新されます。 1. 次のプログラムを MoviesItemOps05.php というファイルにコピーします。 API Version 2012-08-10 107 Amazon DynamoDB 入門ガイド ステップ 3.5: 項目を更新する (条件付き) <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; use Aws\DynamoDb\Marshaler; $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $marshaler = new Marshaler(); $tableName = 'Movies'; $year = 2015; $title = 'The Big New Movie'; $key = $marshaler->marshalJson(' { "year": ' . $year . ', "title": "' . $title . '" } '); $eav = $marshaler->marshalJson(' { ":num": 3 } '); $params = [ 'TableName' => $tableName, 'Key' => $key, 'UpdateExpression' => 'remove info.actors[0]', 'ConditionExpression' => 'size(info.actors) > :num', 'ExpressionAttributeValues'=> $eav, 'ReturnValues' => 'UPDATED_NEW' ]; try { $result = $dynamodb->updateItem($params); echo "Updated item. ReturnValues are:\n"; print_r($result['Attributes']); } catch (DynamoDbException $e) { echo "Unable to update item:\n"; echo $e->getMessage() . "\n"; } ?> 2. 次のコマンドを入力してコマンドを実行します。 API Version 2012-08-10 108 Amazon DynamoDB 入門ガイド ステップ 3.6: 項目を削除する php MoviesItemOps05.php プログラムは次のメッセージで失敗するはずです。 The conditional request failed これは、映画に 3 人の役者が出演しているが、条件は役者が 3 人より多いことをチェックしてい るためです。 3. ConditionExpression が次のようになるようにプログラムを変更します。 ConditionExpression="size(info.actors) >= :num", 条件が、3 より大きいではなく 3 以上になりました。 4. プログラムを再度実行します。これで、UpdateItem オペレーションが成功します。 ステップ 3.6: 項目を削除する プライマリキーを指定することで、deleteItem メソッドを使用して 1 つの項目を削除できます。オ プションで ConditionExpression を指定して、条件を満たさない場合に項目の削除を防ぐことが できます。 次の例では、レーティングが 5 以下の特定の映画項目を削除しようとします。 1. 次のプログラムを MoviesItemOps06.php というファイルにコピーします。 <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; use Aws\DynamoDb\Marshaler; $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $marshaler = new Marshaler(); $tableName = 'Movies'; $year = 2015; $title = 'The Big New Movie'; $key = $marshaler->marshalJson(' { "year": ' . $year . ', "title": "' . $title . '" } '); $eav = $marshaler->marshalJson(' API Version 2012-08-10 109 Amazon DynamoDB 入門ガイド ステップ 4: データをクエリおよびスキャンする { ":val": 5 } '); $params = [ 'TableName' => $tableName, 'Key' => $key, 'ConditionExpression' => 'info.rating <= :val', 'ExpressionAttributeValues'=> $eav ]; try { $result = $dynamodb->deleteItem($params); echo "Deleted item.\n"; } catch (DynamoDbException $e) { echo "Unable to delete item:\n"; echo $e->getMessage() . "\n"; } ?> 2. 次のコマンドを入力してコマンドを実行します。 php MoviesItemOps06.php プログラムは次のメッセージで失敗するはずです。 The conditional request failed これは、この特定の映画のレーティングが 5 より大きいためです。 3. 条件を削除するようにプログラムを変更します。 $params = [ 'TableName' => $tableName, 'Key' => $key ]; 4. プログラムを実行します。ここでは、条件を削除したため、削除が成功します。 ステップ 4: データをクエリおよびスキャンする query メソッドを使用して、テーブルからデータを取得できます。パーティションのキー値を指定す る必要があります。ソートキーはオプションです。 Movies テーブルのプライマリキーは、以下の内容で構成されます。 • year – パーティションキー。属性タイプは数値です。 • title – ソートキー。属性タイプは文字列です。 1 年間にリリースされたすべての映画を検索するには、year のみ指定する必要があります。title を指定して、いくつかの条件 (ソートキー上) に基づいて映画のサブセットを取得することもできま す。たとえば、2014 年にリリースされて、主題が「A」で始まる映画を探す場合です。 query に加えて、すべてのテーブルデータを取得可能な scan メソッドもあります。 API Version 2012-08-10 110 Amazon DynamoDB 入門ガイド ステップ 4.1: クエリ - 1 年間 にリリースされたすべての映画 データのクエリとスキャンの詳細については、『Amazon DynamoDB 開発者ガイド』の「クエリおよ びスキャン」を参照してください。 トピック • ステップ 4.1: クエリ - 1 年間にリリースされたすべての映画 (p. 111) • ステップ 4.2: クエリ - 1 年間にリリースされた特定のタイトルを持つすべての映画 (p. 112) • ステップ 4.3: スキャン (p. 113) ステップ 4.1: クエリ - 1 年間にリリースされたすべ ての映画 このステップに含まれているプログラムは、year 1985 にリリースされたすべての映画を取得しま す。 1. 次のプログラムを MoviesQuery01.php というファイルにコピーします。 <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; use Aws\DynamoDb\Marshaler; $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $marshaler = new Marshaler(); $tableName = 'Movies'; $eav = $marshaler->marshalJson(' { ":yyyy": 1985 } '); $params = [ 'TableName' => $tableName, 'KeyConditionExpression' => '#yr = :yyyy', 'ExpressionAttributeNames'=> [ '#yr' => 'year' ], 'ExpressionAttributeValues'=> $eav ]; echo "Querying for movies from 1985.\n"; try { $result = $dynamodb->query($params); echo "Query succeeded.\n"; API Version 2012-08-10 111 Amazon DynamoDB 入門ガイド ステップ 4.2: クエリ - 1 年間にリリース された特定のタイトルを持つすべての映画 foreach ($result['Items'] as $movie) { echo $marshaler->unmarshalValue($movie['year']) . ': ' . $marshaler->unmarshalValue($movie['title']) . "\n"; } } catch (DynamoDbException $e) { echo "Unable to query:\n"; echo $e->getMessage() . "\n"; } ?> Note • ExpressionAttributeNames は、名前を置換します。year は DynamoDB の予約 語であるため、これが使用されます。KeyConditionExpression を含むどの式でも 直接使用することはできません。これに対処するため、式の属性名 #yr が使用されま す。 • ExpressionAttributeValues は、値を置換します。KeyConditionExpression を含むどの式にもリテラルを使用できないため、これが使用されます。これに対処す るため、式の属性値 :yyyy が使用されます。 2. 次のコマンドを入力してコマンドを実行します。 php MoviesItemQuery01.php Note 前のプログラムは、プライマリキーの属性によってテーブルをクエリする方法を示していま す。DynamoDB では、必要に応じて 1 つ以上のセカンダリインデックスをテーブルに作成 し、テーブルをクエリするのと同じ方法でそれらのインデックスをクエリできます。セカン ダリインデックスは非キー属性のクエリを可能にすることで、アプリケーションに追加の柔 軟性を提供します。詳細については、Amazon DynamoDB 開発者ガイドの「セカンダリイン デックス」を参照してください。 ステップ 4.2: クエリ - 1 年間にリリースされた特定 のタイトルを持つすべての映画 このステップに含まれているプログラムは、year 1992 にリリースされたすべての映画のう ち、title が「A」~「L」で始まる映画を取得します。 1. 次のプログラムを MoviesQuery02.php というファイルにコピーします。 <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; use Aws\DynamoDb\Marshaler; $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', 'region' => 'us-west-2', 'version' => 'latest' API Version 2012-08-10 112 Amazon DynamoDB 入門ガイド ステップ 4.3: スキャン ]); $dynamodb = $sdk->createDynamoDb(); $marshaler = new Marshaler(); $tableName = 'Movies'; $eav = $marshaler->marshalJson(' { ":yyyy":1992, ":letter1": "A", ":letter2": "L" } '); $params = [ 'TableName' => $tableName, 'ProjectionExpression' => '#yr, title, info.genres, info.actors[0]', 'KeyConditionExpression' => '#yr = :yyyy and title between :letter1 and :letter2', 'ExpressionAttributeNames'=> [ '#yr' => 'year' ], 'ExpressionAttributeValues'=> $eav ]; echo "Querying for movies from 1992 - titles A-L, with genres and lead actor\n"; try { $result = $dynamodb->query($params); echo "Query succeeded.\n"; foreach ($result['Items'] as $i) { $movie = $marshaler->unmarshalItem($i); print $movie['year'] . ': ' . $movie['title'] . ' ... '; foreach ($movie['info']['genres'] as $gen) { print $gen . ' '; } echo ' ... ' . $movie['info']['actors'][0] . "\n"; } } catch (DynamoDbException $e) { echo "Unable to query:\n"; echo $e->getMessage() . "\n"; } ?> 2. 次のコマンドを入力してコマンドを実行します。 php MoviesQuery02.php ステップ 4.3: スキャン scan メソッドは、テーブル全体のすべての項目を読み込み、テーブルの全データを返します。オプ ションで filter_expression を提供して、条件に一致する項目だけが返されるように指定できま API Version 2012-08-10 113 Amazon DynamoDB 入門ガイド ステップ 4.3: スキャン す。ただし、テーブル全体がスキャンされた後にのみ、フィルタが適用されることに注意してくださ い。 次のプログラムは、約 5,000 項目を含む Movies テーブル全体をスキャンします。スキャンは、1950 年代の映画のみ (約 100 項目) を取得して、残りはすべて破棄するようオプションのフィルタを指定し ます。 1. 次のプログラムを MoviesScan.php というファイルにコピーします。 <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; use Aws\DynamoDb\Marshaler; $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $marshaler = new Marshaler(); //Expression attribute values $eav = $marshaler->marshalJson(' { ":start_yr": 1950, ":end_yr": 1959 } '); $params = [ 'TableName' => 'Movies', 'ProjectionExpression' => '#yr, title, info.rating', 'FilterExpression' => '#yr between :start_yr and :end_yr', 'ExpressionAttributeNames'=> [ '#yr' => 'year' ], 'ExpressionAttributeValues'=> $eav ]; echo "Scanning Movies table.\n"; try { while (true) { $result = $dynamodb->scan($params); foreach ($result['Items'] as $i) { $movie = $marshaler->unmarshalItem($i); echo $movie['year'] . ': ' . $movie['title']; echo ' ... ' . $movie['info']['rating'] . "\n"; } if (isset($result['LastEvaluatedKey'])) { $params['ExclusiveStartKey'] = $result['LastEvaluatedKey']; } else { API Version 2012-08-10 114 Amazon DynamoDB 入門ガイド ステップ 5: (オプション) テーブルを削除する break; } } } catch (DynamoDbException $e) { echo "Unable to scan:\n"; echo $e->getMessage() . "\n"; } ?> このコードでは、以下の点に注意してください。 • ProjectionExpression は、スキャン結果に必要な属性を指定します。 • FilterExpression は、条件を満たした項目だけが返されるような条件を指定します。他の すべての項目は破棄されます。 2. 次のコマンドを入力してコマンドを実行します。 php MoviesScan.php Note テーブルで作成した任意のセカンダリインデックスで Scan オペレーションを使用すること もできます。詳細については、Amazon DynamoDB 開発者ガイドの「セカンダリインデック ス」を参照してください。 ステップ 5: (オプション) テーブルを削除する Movies テーブルを削除するには: 1. 次のプログラムを MoviesDeleteTable.php というファイルにコピーします。 <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $params = [ 'TableName' => 'Movies' ]; try { $result = $dynamodb->deleteTable($params); echo "Deleted table.\n"; API Version 2012-08-10 115 Amazon DynamoDB 入門ガイド 概要 } catch (DynamoDbException $e) { echo "Unable to delete table:\n"; echo $e->getMessage() . "\n"; } ?> 2. 次のコマンドを入力してコマンドを実行します。 php MoviesDeleteTable.php 概要 このチュートリアルでは、ご使用のコンピューターの DynamoDB で Movies テーブルを作成し、 基本的なオペレーションを実行しました。ダウンロード可能なバージョンの DynamoDB は、アプリ ケーションの開発およびテストの際に便利です。ただし、本番環境でアプリケーションを実行する場 合、Amazon DynamoDB ウェブサービスを使用できるようにコードを変更します。 Amazon DynamoDB サービスを使用する Amazon DynamoDB サービスを使用するには、アプリケーションのエンドポイントを変更する必要が あります。そのためには、コードで次の行を見つけます。 $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', 'region' => 'us-west-2', 'version' => 'latest' ]); ここで、endpoint パラメーターを削除してコードを次のようにします。 $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); この行を削除すると、コードは設定値 region で指定されたリージョン内の DynamoDB サービスに アクセスできます。たとえば、次の行は、米国西部 (オレゴン) リージョンを使用することを指定しま す。 'region' => 'us-west-2', プログラムはコンピュータで DynamoDB を使用する代わりに、米国西部 (オレゴン) で DynamoDB サービスエンドポイントを使用します。 Amazon DynamoDB は、世界中の AWS リージョンで利用できます。完全なリストについては、AWS General Referenceの「リージョンとエンドポイント」を参照してください。コードにリージョンお よびエンドポイントを設定するための詳細については、「boto: A Python interface to Amazon Web Services」を参照してください。 最後に、「Amazon DynamoDB 開発者ガイド」を読むことをお勧めします。ここには、サンプルコー ドやベストプラクティスなど、DynamoDB に関するさらに詳しい情報が収められています。 API Version 2012-08-10 116 Amazon DynamoDB 入門ガイド 前提条件 Python および DynamoDB このチュートリアルでは、AWS SDK for Python (Boto 3) を使用して次の Amazon DynamoDB オペ レーションを実行するシンプルなプログラムを記述します。 • Movies というテーブルを作成し、JSON形式のサンプルデータをロードします。 • テーブルで、作成、読み込み、更新、削除のオペレーションを実行します。 • 簡単なクエリを実行します。 このチュートリアルでは、ダウンロード可能なバージョンの DynamoDB を使用します。概 要 (p. 133) では、DynamoDB ウェブサービスに対して同じコードを実行する方法について説明しま す。 参加費: 無料 前提条件 • Read DynamoDB の概念について (p. 1). • DynamoDB をダウンロードしてコンピュータで実行します。詳細については、「DynamoDB のダ ウンロードと実行 (p. 4)」を参照してください。 • Amazon Web Services にサインアップし、アクセスキーを作成します。AWS SDK を使用するに は、これらの認証情報が必要です。AWS アカウントを作成するには、https://aws.amazon.com/ に アクセスし、[Create an AWS Account] を選択して、オンラインの手順に従います。 • AWS 認証情報ファイルを作成します。詳細については、Boto 3 ドキュメントの「設定」を参照し てください。 • Python 2.6 以降をインストールします。詳細については、https://www.python.org/downloads を参照 してください。 手順については、Boto 3 ドキュメントの「クイックスタート」を参照してください。 Tip このチュートリアルを行なうときは、http://boto.readthedocs.org/en/latest/のドキュメンテー ションを参照できます。以下のセクションは、DynamoDB に固有の内容です。 • DynamoDB チュートリアル API Version 2012-08-10 117 Amazon DynamoDB 入門ガイド ステップ 1: テーブルを作成する • DynamoDB 低レベルクライアント ステップ 1: テーブルを作成する このステップでは、Movies という名前のテーブルを作成します。テーブルのプライマリキーは、以 下の属性で構成されます。 • year – パーティションキー。AttributeType は、数字 (number) の N です。 • title – ソートキー。AttributeType は、文字列 (string) の S です。 1. 次のプログラムを MoviesCreateTable.py というファイルにコピーします。 from __future__ import print_function # Python 2/3 compatibility import boto3 dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.create_table( TableName='Movies', KeySchema=[ { 'AttributeName': 'year', 'KeyType': 'HASH' #Partition key }, { 'AttributeName': 'title', 'KeyType': 'RANGE' #Sort key } ], AttributeDefinitions=[ { 'AttributeName': 'year', 'AttributeType': 'N' }, { 'AttributeName': 'title', 'AttributeType': 'S' }, ], ProvisionedThroughput={ 'ReadCapacityUnits': 10, 'WriteCapacityUnits': 10 } ) print("Table status:", table.table_status) Note • エンドポイントを設定して、コンピュータの DynamoDB にテーブルを作成することを 示します。 API Version 2012-08-10 118 Amazon DynamoDB 入門ガイド ステップ 2: サンプルデータをロードする • create_table 呼び出しでは、テーブル名、プライマリキー属性、そのデータ型を指 定します。 • ProvisionedThroughput パラメーターは必須ですが、ダウンロード可能なバージョ ンの DynamoDB では無視されます。(プロビジョニングされたスループットはこの演 習では扱いません。) • これらの例では、Python 3 スタイルの print 関数を使用します。行 from __future__ import print_function では、Python 2.6 以降での Python 3 出力が 有効になります。 2. 次のコマンドを入力してコマンドを実行します。 python MoviesCreateTable.py テーブルの管理の詳細については、『Amazon DynamoDB 開発者ガイド』の「テーブルの操作」を参 照してください。 ステップ 2: サンプルデータをロードする このステップでは、Movies テーブルにサンプルデータを入力します。 トピック • ステップ 2.1: サンプルデータファイルをダウンロードする (p. 120) • ステップ 2.2: 映画テーブルにサンプルデータをロードする (p. 120) サンプルデータファイルには、インターネット映画データベース (IMDb) にある数千におよぶ映 画の情報が格納されています。映画データは、次の例に示すように JSON 形式です。映画ごと に、year、title、および info という JSON マップが設定されています。 [ { "year" : ... , "title" : ... , "info" : { ... } }, { "year" : ..., "title" : ..., "info" : { ... } }, ... ] JSON データで次の点に注意してください。 • year と title を、Movies テーブルのプライマリキー属性値として使用します。 • 残りの info 値は、info という単一の属性に保存されます。このプログラムは、JSON を DynamoDB 属性で保存する方法を示しています。 以下は、映画データの例です。 API Version 2012-08-10 119 Amazon DynamoDB 入門ガイド ステップ 2.1: サンプルデータ ファイルをダウンロードする { "year" : 2013, "title" : "Turn It Down, Or Else!", "info" : { "directors" : [ "Alice Smith", "Bob Jones" ], "release_date" : "2013-01-18T00:00:00Z", "rating" : 6.2, "genres" : [ "Comedy", "Drama" ], "image_url" : "http://ia.media-imdb.com/images/N/ O9ERWAU7FS797AJ7LU8HN09AMUP908RLlo5JF90EWR7LJKQ7@@._V1_SX400_.jpg", "plot" : "A rock band plays their music at high volumes, annoying the neighbors.", "rank" : 11, "running_time_secs" : 5215, "actors" : [ "David Matthewman", "Ann Thomas", "Jonathan G. Neff" ] } } ステップ 2.1: サンプルデータファイルをダウンロー ドする 1. リンク moviedata.zip をクリックして、サンプルデータアーカイブをダウンロードします。 2. アーカイブからデータファイル (moviedata.json) を抽出します。 3. 現在のディレクトリに moviedata.json ファイルをコピーします。 ステップ 2.2: 映画テーブルにサンプルデータをロー ドする サンプルデータをダウンロードすると、次のプログラムを実行して Movies テーブルに入力できま す。 1. 次のプログラムを MoviesLoadData.py というファイルにコピーします。 from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') API Version 2012-08-10 120 Amazon DynamoDB 入門ガイド ステップ 3: 項目を作成、読み込み、更新、削除する with open("moviedata.json") as json_file: movies = json.load(json_file, parse_float = decimal.Decimal) for movie in movies: year = int(movie['year']) title = movie['title'] info = movie['info'] print("Adding movie:", year, title) table.put_item( Item={ 'year': year, 'title': title, 'info': info, } ) 2. 次のコマンドを入力してコマンドを実行します。 python MoviesLoadData.py ステップ 3: 項目を作成、読み込み、更新、削除 する このステップでは、Movies テーブルの項目で読み取り/書き込みオペレーションを実行します。 データの読み取りと書き込みの詳細については、『Amazon DynamoDB 開発者ガイド』の「項目の操 作」を参照してください。 トピック • ステップ 3.1: 新しい項目を作成する (p. 121) • ステップ 3.2: 項目を読み取る (p. 122) • ステップ 3.3: 項目を更新する (p. 123) • ステップ 3.4: アトミックカウンターを増分する (p. 125) • ステップ 3.5: 項目を更新する (条件付き) (p. 126) • ステップ 3.6: 項目を削除する (p. 127) ステップ 3.1: 新しい項目を作成する このステップでは、Movies テーブルに新しい項目を追加します。 1. 次のプログラムを MoviesItemOps01.py というファイルにコピーします。 from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: API Version 2012-08-10 121 Amazon DynamoDB 入門ガイド ステップ 3.2: 項目を読み取る return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') title = "The Big New Movie" year = 2015 response = table.put_item( Item={ 'year': year, 'title': title, 'info': { 'plot':"Nothing happens at all.", 'rating': decimal.Decimal(0) } } ) print("PutItem succeeded:") print(json.dumps(response, indent=4, cls=DecimalEncoder)) Note • プライマリキーは必須です。このコードは、プライマリキー (year、title) と info 属性を持つ項目を追加します。info 属性には、映画についての詳細情報を示すサンプ ル JSON が保存されます。 • DecimalEncoder クラスは、Decimal クラスを使用して保存された数値を出力するた めに使用されます。Boto SDK は、Decimal クラスを使用して DynamoDB の数値を保 持します。 2. 次のコマンドを入力してコマンドを実行します。 python MoviesItemOps01.py ステップ 3.2: 項目を読み取る 前のプログラムでは、テーブルに次の項目を追加しました。 { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } Movies テーブルから項目を読み取る、get_item メソッドを使用できます。 プライマリキー値を指 定する必要があります。そうすると year と title がわかれば、Movies から項目を読み込むことが できます。 API Version 2012-08-10 122 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する 1. 次のプログラムを MoviesItemOps02.py というファイルにコピーします。 from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal from boto3.dynamodb.conditions import Key, Attr from botocore.exceptions import ClientError # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource("dynamodb", region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') title = "The Big New Movie" year = 2015 try: response = table.get_item( Key={ 'year': year, 'title': title } ) except ClientError as e: print(e.response['Error']['Message']) else: item = response['Item'] print("GetItem succeeded:") print(json.dumps(item, indent=4, cls=DecimalEncoder)) 2. 次のコマンドを入力してコマンドを実行します。 python MoviesItemOps02.py ステップ 3.3: 項目を更新する update_item メソッドを使用して既存の項目を変更できます。既存の属性の値の更新、新しい属性 の追加、または属性の削除を行えます。 このチュートリアルでは、次の更新を行います。 • 既存の属性の値を変更します (rating、plot)。 • 新しいリスト属性 (actors) を既存の info マップに追加します。 項目の変更前: API Version 2012-08-10 123 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } 項目の変更後: { year: 2015, title: "The Big New Movie", info: { plot: "Everything happens all at once.", rating: 5.5, actors: ["Larry", "Moe", "Curly"] } } 1. 次のプログラムを MoviesItemOps03.py というファイルにコピーします。 from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') title = "The Big New Movie" year = 2015 response = table.update_item( Key={ 'year': year, 'title': title }, UpdateExpression="set info.rating = :r, info.plot=:p, info.actors=:a", ExpressionAttributeValues={ ':r': decimal.Decimal(5.5), ':p': "Everything happens all at once.", ':a': ["Larry", "Moe", "Curly"] }, API Version 2012-08-10 124 Amazon DynamoDB 入門ガイド ステップ 3.4: アトミックカウンターを増分する ReturnValues="UPDATED_NEW" ) print("UpdateItem succeeded:") print(json.dumps(response, indent=4, cls=DecimalEncoder)) Note このプログラムでは、UpdateExpression を使用して、指定された項目で実行するすべ ての更新を記述します。 ReturnValues パラメーターは、DynamoDB に更新された属性 (UPDATED_NEW) のみを 返すように指示します。 2. 次のコマンドを入力してコマンドを実行します。 python MoviesItemOps03.py ステップ 3.4: アトミックカウンターを増分する DynamoDB では、アトミックカウンターがサポートされています。そのため、update_item メソッ ドを使用して、他の書き込みリクエストを妨げることなく既存の属性値をインクリメントまたはデク リメントできます。(すべての書き込みリクエストは、受信された順に適用されます)。 次のプログラムは、映画の rating を増分する方法を示しています。実行するたびに、プログラムは この属性を 1 つ増分します。 1. 次のプログラムを MoviesItemOps04.py というファイルにコピーします。 from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') title = "The Big New Movie" year = 2015 response = table.update_item( Key={ 'year': year, 'title': title }, UpdateExpression="set info.rating = info.rating + :val", API Version 2012-08-10 125 Amazon DynamoDB 入門ガイド ステップ 3.5: 項目を更新する (条件付き) ExpressionAttributeValues={ ':val': decimal.Decimal(1) }, ReturnValues="UPDATED_NEW" ) print("UpdateItem succeeded:") print(json.dumps(response, indent=4, cls=DecimalEncoder)) 2. 次のコマンドを入力してコマンドを実行します。 python MoviesItemOps04.py ステップ 3.5: 項目を更新する (条件付き) 次のプログラムは、条件とともに UpdateItem を使用する方法を示しています。条件が true と評価 された場合、更新は成功します。それ以外の場合、更新は行われません。 その場合、項目は 3 人より多い役者がいる場合にのみ更新されます。 1. 次のプログラムを MoviesItemOps05.py というファイルにコピーします。 from __future__ import print_function # Python 2/3 compatibility import boto3 from botocore.exceptions import ClientError import json import decimal # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') title = "The Big New Movie" year = 2015 # Conditional update (will fail) print("Attempting conditional update...") try: response = table.update_item( Key={ 'year': year, 'title': title }, UpdateExpression="remove info.actors[0]", ConditionExpression="size(info.actors) > :num", API Version 2012-08-10 126 Amazon DynamoDB 入門ガイド ステップ 3.6: 項目を削除する ExpressionAttributeValues={ ':num': 3 }, ReturnValues="UPDATED_NEW" ) except ClientError as e: if e.response['Error']['Code'] == "ConditionalCheckFailedException": print(e.response['Error']['Message']) else: raise else: print("UpdateItem succeeded:") print(json.dumps(response, indent=4, cls=DecimalEncoder)) 2. 次のコマンドを入力してコマンドを実行します。 python MoviesItemOps05.py プログラムは次のメッセージで失敗するはずです。 The conditional request failed これは、映画に 3 人の役者が出演しているが、条件は役者が 3 人より多いことをチェックしてい るためです。 3. ConditionExpression が次のようになるようにプログラムを変更します。 ConditionExpression="size(info.actors) >= :num", 条件が、3 より大きいではなく 3 以上になりました。 4. プログラムを再度実行します。これで、UpdateItem オペレーションが成功します。 ステップ 3.6: 項目を削除する プライマリキーを指定することで、delete_item メソッドを使用して 1 つの項目を削除できます。 オプションで ConditionExpression を指定して、条件を満たさない場合に項目の削除を防ぐこと ができます。 次の例では、レーティングが 5 以下の特定の映画項目を削除しようとします。 1. 次のプログラムを MoviesItemOps06.py というファイルにコピーします。 from __future__ import print_function # Python 2/3 compatibility import boto3 from botocore.exceptions import ClientError import json import decimal # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) API Version 2012-08-10 127 Amazon DynamoDB 入門ガイド ステップ 4: データをクエリおよびスキャンする dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') title = "The Big New Movie" year = 2015 print("Attempting a conditional delete...") try: response = table.delete_item( Key={ 'year': year, 'title': title }, ConditionExpression="info.rating <= :val", ExpressionAttributeValues= { ":val": decimal.Decimal(5) } ) except ClientError as e: if e.response['Error']['Code'] == "ConditionalCheckFailedException": print(e.response['Error']['Message']) else: raise else: print("DeleteItem succeeded:") print(json.dumps(response, indent=4, cls=DecimalEncoder)) 2. 次のコマンドを入力してコマンドを実行します。 python MoviesItemOps06.py プログラムは次のメッセージで失敗するはずです。 The conditional request failed これは、この特定の映画のレーティングが 5 より大きいためです。 3. ここで、table.delete_item で条件を削除するようにプログラムを変更します。 response = table.delete_item( Key={ 'year': year, 'title': title } ) 4. プログラムを実行します。ここでは、条件を削除したため、削除が成功します。 ステップ 4: データをクエリおよびスキャンする query メソッドを使用して、テーブルからデータを取得できます。パーティションのキー値を指定す る必要があります。ソートキーはオプションです。 Movies テーブルのプライマリキーは、以下の内容で構成されます。 API Version 2012-08-10 128 Amazon DynamoDB 入門ガイド ステップ 4.1: クエリ - 1 年間 にリリースされたすべての映画 • year – パーティションキー。属性タイプは数値です。 • title – ソートキー。属性タイプは文字列です。 1 年間にリリースされたすべての映画を検索するには、year のみ指定する必要があります。title を指定して、いくつかの条件 (ソートキー上) に基づいて映画のサブセットを取得することもできま す。たとえば、2014 年にリリースされて、主題が「A」で始まる映画を探す場合です。 query に加えて、すべてのテーブルデータを取得可能な scan メソッドもあります。 データのクエリとスキャンの詳細については、『Amazon DynamoDB 開発者ガイド』の「クエリおよ びスキャン」を参照してください。 トピック • ステップ 4.1: クエリ - 1 年間にリリースされたすべての映画 (p. 129) • ステップ 4.2: クエリ - 1 年間にリリースされた特定のタイトルを持つすべての映画 (p. 130) • ステップ 4.3: スキャン (p. 131) ステップ 4.1: クエリ - 1 年間にリリースされたすべ ての映画 このステップに含まれているプログラムは、year 1985 にリリースされたすべての映画を取得しま す。 1. 次のプログラムを MoviesQuery01.py というファイルにコピーします。 from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal from boto3.dynamodb.conditions import Key, Attr # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') print("Movies from 1985") response = table.query( KeyConditionExpression=Key('year').eq(1985) ) for i in response['Items']: print(i['year'], ":", i['title']) API Version 2012-08-10 129 Amazon DynamoDB 入門ガイド ステップ 4.2: クエリ - 1 年間にリリース された特定のタイトルを持つすべての映画 Note Key からインポートされた Attr 関数と boto3.dynamodb.conditions 関数 を使用すると、Boto 3 SDK により ConditionExpression が自動的に作成されま す。ConditionExpression を文字列として指定することもできます。 DynamoDB の使用可能な条件のリストについては、AWS SDK for Python (Boto 3) の使用 開始の「DynamoDB の条件」を参照してください。 詳細については、『Amazon DynamoDB 開発者ガイド』の「条件式」を参照してくださ い。 2. 次のコマンドを入力してコマンドを実行します。 python MoviesQuery01.py Note 前のプログラムは、プライマリキーの属性によってテーブルをクエリする方法を示していま す。DynamoDB では、必要に応じて 1 つ以上のセカンダリインデックスをテーブルに作成 し、テーブルをクエリするのと同じ方法でそれらのインデックスをクエリできます。セカン ダリインデックスは非キー属性のクエリを可能にすることで、アプリケーションに追加の柔 軟性を提供します。詳細については、Amazon DynamoDB 開発者ガイドの「セカンダリイン デックス」を参照してください。 ステップ 4.2: クエリ - 1 年間にリリースされた特定 のタイトルを持つすべての映画 このステップに含まれているプログラムは、year 1992 にリリースされたすべての映画のう ち、title が「A」~「L」で始まる映画を取得します。 1. 次のプログラムを MoviesQuery02.py というファイルにコピーします。 from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal from boto3.dynamodb.conditions import Key, Attr # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): return str(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') print("Movies from 1992 - titles A-L, with genres and lead actor") response = table.query( ProjectionExpression="#yr, title, info.genres, info.actors[0]", API Version 2012-08-10 130 Amazon DynamoDB 入門ガイド ステップ 4.3: スキャン ExpressionAttributeNames={ "#yr": "year" }, # Expression Attribute Names for Projection Expression only. KeyConditionExpression=Key('year').eq(1992) & Key('title').between('A', 'L') ) for i in response[u'Items']: print(json.dumps(i, cls=DecimalEncoder)) 2. 次のコマンドを入力してコマンドを実行します。 python MoviesQuery02.py ステップ 4.3: スキャン scan メソッドは、テーブル全体のすべての項目を読み込み、テーブルの全データを返します。オプ ションで filter_expression を提供して、条件に一致する項目だけが返されるように指定できま す。ただし、テーブル全体がスキャンされた後にのみ、フィルタが適用されることに注意してくださ い。 次のプログラムは、約 5,000 項目を含む Movies テーブル全体をスキャンします。スキャンは、1950 年代の映画のみ (約 100 項目) を取得して、残りはすべて破棄するようオプションのフィルタを指定し ます。 1. 次のプログラムを MoviesScan.py というファイルにコピーします。 from __future__ import print_function # Python 2/3 compatibility import boto3 import json import decimal from boto3.dynamodb.conditions import Key, Attr # Helper class to convert a DynamoDB item to JSON. class DecimalEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, decimal.Decimal): if o % 1 > 0: return float(o) else: return int(o) return super(DecimalEncoder, self).default(o) dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') fe = Key('year').between(1950, 1959); pe = "#yr, title, info.rating" # Expression Attribute Names for Projection Expression only. ean = { "#yr": "year", } esk = None response = table.scan( FilterExpression=fe, ProjectionExpression=pe, ExpressionAttributeNames=ean API Version 2012-08-10 131 Amazon DynamoDB 入門ガイド ステップ 5: (オプション) テーブルを削除する ) for i in response['Items']: print(json.dumps(i, cls=DecimalEncoder)) while 'LastEvaluatedKey' in response: response = table.scan( ProjectionExpression=pe, FilterExpression=fe, ExpressionAttributeNames= ean, ExclusiveStartKey=response['LastEvaluatedKey'] ) for i in response['Items']: print(json.dumps(i, cls=DecimalEncoder)) このコードでは、以下の点に注意してください。 • ProjectionExpression は、スキャン結果に必要な属性を指定します。 • FilterExpression は、条件を満たした項目だけが返されるような条件を指定します。他の すべての項目は破棄されます。 • scan メソッドは、ページという項目のサブセットを毎回返します。次に、応答の LastEvaluatedKey 値が、ExclusiveStartKey パラメーター経由で scan メソッドに渡さ れます。最後のページが返されると、LastEvaluatedKey は応答の一部ではなくなります。 Note • ExpressionAttributeNames は、名前を置換します。year は DynamoDB の予約 語であるため、これが使用されます。KeyConditionExpression を含むどの式でも 直接使用することはできません。これに対処するため、式の属性名 #yr が使用されま す。 • ExpressionAttributeValues は、値を置換します。KeyConditionExpression を含むどの式にもリテラルを使用できないため、これが使用されます。これに対処す るため、式の属性値 :yyyy が使用されます。 2. 次のコマンドを入力してコマンドを実行します。 python MoviesScan.py Note テーブルで作成した任意のセカンダリインデックスで Scan オペレーションを使用すること もできます。詳細については、Amazon DynamoDB 開発者ガイドの「セカンダリインデック ス」を参照してください。 ステップ 5: (オプション) テーブルを削除する Movies テーブルを削除するには: 1. 次のプログラムを MoviesDeleteTable.py というファイルにコピーします。 from __future__ import print_function # Python 2/3 compatibility import boto3 API Version 2012-08-10 132 Amazon DynamoDB 入門ガイド 概要 dynamodb = boto3.resource('dynamodb', region_name='us-west-2', endpoint_url="http://localhost:8000") table = dynamodb.Table('Movies') table.delete() 2. 次のコマンドを入力してコマンドを実行します。 python MoviesDeleteTable.py 概要 このチュートリアルでは、ご使用のコンピューターの DynamoDB で Movies テーブルを作成し、 基本的なオペレーションを実行しました。ダウンロード可能なバージョンの DynamoDB は、アプリ ケーションの開発およびテストの際に便利です。ただし、本番環境でアプリケーションを実行する場 合、Amazon DynamoDB ウェブサービスを使用できるようにコードを変更します。 Amazon DynamoDB サービスへの移動 Amazon DynamoDB サービスを使用するには、アプリケーションのエンドポイントを変更する必要が あります。これを行うには、次の行を変更します。 dynamodb = boto3.resource('dynamodb',endpoint_url="http://localhost:8000") たとえば、us-west-2 リージョンを使用する場合: dynamodb = boto3.resource('dynamodb',region_name='us-west-2') ここで、プログラムはコンピュータで DynamoDB を使用する代わりに、米国西部 (オレゴン) で DynamoDB サービスを使用します。 Amazon DynamoDB は、世界中の AWS リージョンで利用できます。完全なリストについては、AWS General Referenceの「リージョンとエンドポイント」を参照してください。コードにリージョンお よびエンドポイントを設定するための詳細については、『AWS SDK for Java Developer Guide』の 「AWS リージョンの選択」を参照してください。 最後に、「Amazon DynamoDB 開発者ガイド」を読むことをお勧めします。ここには、サンプルコー ドやベストプラクティスなど、DynamoDB に関するさらに詳しい情報が収められています。 API Version 2012-08-10 133 Amazon DynamoDB 入門ガイド 前提条件 Ruby および DynamoDB このチュートリアルでは、AWS SDK for Ruby を使用して次の Amazon DynamoDB オペレーションを 実行するシンプルなプログラムを作成します。 • Movies というテーブルを作成し、JSON形式のサンプルデータをロードします。 • テーブルで、作成、読み込み、更新、削除のオペレーションを実行します。 • 簡単なクエリを実行します。 このチュートリアルでは、ダウンロード可能なバージョンの DynamoDB を使用します。概 要 (p. 150) では、DynamoDB サービスに対して同じコードを実行する方法について説明します。 参加費: 無料 前提条件 • Read DynamoDB の概念について (p. 1). • DynamoDB をダウンロードしてコンピュータで実行します。詳細については、「DynamoDB のダ ウンロードと実行 (p. 4)」を参照してください。 • Amazon Web Services にサインアップし、アクセスキーを作成します。AWS SDK を使用するに は、これらの認証情報が必要です。AWS アカウントを作成するには、https://aws.amazon.com/ に アクセスし、[Create an AWS Account] を選択して、オンラインの手順に従います。 • AWS 認証情報ファイルを作成します。詳細については、『AWS SDK for Ruby API Reference』の 「設定」を参照してください。 • AWS SDK for Ruby を以下のようにセットアップします。 • https://www.ruby-lang.org/en/documentation/installation/ にアクセスし、Ruby をインストールし ます。 • https://aws.amazon.com/sdk-for-ruby にアクセスし、AWS SDK for Ruby をインストールします。 詳細については、『AWS SDK for Ruby API Reference』の「インストール」を参照してください。 Tip このチュートリアルを行うときは、『AWS SDK for Ruby API Reference』を参照できま す。DynamoDBセクションでは、DynamoDB オペレーションのパラメーターと結果について 説明しています。 API Version 2012-08-10 134 Amazon DynamoDB 入門ガイド ステップ 1: テーブルを作成する ステップ 1: テーブルを作成する このステップでは、Movies という名前のテーブルを作成します。テーブルのプライマリキーは、以 下の 2 つの属性で構成されます。 • year – パーティションキー。attribute_type は、数字 (number) の N です。 • title – ソートキー。attribute_type は、文字列 (string) の S です。 1. 次のプログラムを MoviesCreateTable.rb というファイルにコピーします。 require "aws-sdk-core" Aws.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }) dynamodb = Aws::DynamoDB::Client.new params = { table_name: "Movies", key_schema: [ { attribute_name: "year", key_type: "HASH" #Partition key }, { attribute_name: "title", key_type: "RANGE" #Sort key } ], attribute_definitions: [ { attribute_name: "year", attribute_type: "N" }, { attribute_name: "title", attribute_type: "S" }, ], provisioned_throughput: { read_capacity_units: 10, write_capacity_units: 10 } } begin result = dynamodb.create_table(params) puts "Created table. Status: " + result.table_description.table_status; rescue Aws::DynamoDB::Errors::ServiceError => error puts "Unable to create table:" puts "#{error.message}" API Version 2012-08-10 135 Amazon DynamoDB 入門ガイド ステップ 2: サンプルデータをロードする end Note • エンドポイントを設定して、コンピュータの DynamoDB にテーブルを作成することを 示します。 • create_table 呼び出しでは、テーブル名、プライマリキー属性、そのデータ型を指 定します。 • provisioned_throughput パラメーターは必須ですが、ダウンロード可能なバー ジョンの DynamoDB では無視されます。(プロビジョニングされたスループットはこ の演習では扱いません。) 2. 次のコマンドを入力してコマンドを実行します。 ruby MoviesCreateTable.rb テーブルの管理の詳細については、『Amazon DynamoDB 開発者ガイド』の「テーブルの操作」を参 照してください。 ステップ 2: サンプルデータをロードする このステップでは、Movies テーブルにサンプルデータを入力します。 トピック • ステップ 2.1: サンプルデータファイルをダウンロードする (p. 137) • ステップ 2.2: 映画テーブルにサンプルデータをロードする (p. 137) サンプルデータファイルには、インターネット映画データベース (IMDb) にある数千におよぶ映 画の情報が格納されています。映画データは、次の例に示すように JSON 形式です。映画ごと に、year、title、および info という JSON マップが設定されています。 [ { "year" : ... , "title" : ... , "info" : { ... } }, { "year" : ..., "title" : ..., "info" : { ... } }, ... ] JSON データで次の点に注意してください。 • year と title を、Movies テーブルのプライマリキー属性値として使用します。 • 残りの info 値は、info という単一の属性に保存されます。このプログラムは、JSON を DynamoDB 属性で保存する方法を示しています。 API Version 2012-08-10 136 Amazon DynamoDB 入門ガイド ステップ 2.1: サンプルデータ ファイルをダウンロードする 以下は、映画データの例です。 { "year" : 2013, "title" : "Turn It Down, Or Else!", "info" : { "directors" : [ "Alice Smith", "Bob Jones" ], "release_date" : "2013-01-18T00:00:00Z", "rating" : 6.2, "genres" : [ "Comedy", "Drama" ], "image_url" : "http://ia.media-imdb.com/images/N/ O9ERWAU7FS797AJ7LU8HN09AMUP908RLlo5JF90EWR7LJKQ7@@._V1_SX400_.jpg", "plot" : "A rock band plays their music at high volumes, annoying the neighbors.", "rank" : 11, "running_time_secs" : 5215, "actors" : [ "David Matthewman", "Ann Thomas", "Jonathan G. Neff" ] } } ステップ 2.1: サンプルデータファイルをダウンロー ドする 1. リンク moviedata.zip をクリックして、サンプルデータアーカイブをダウンロードします。 2. アーカイブからデータファイル (moviedata.json) を抽出します。 3. 現在のディレクトリに moviedata.json ファイルをコピーします。 ステップ 2.2: 映画テーブルにサンプルデータをロー ドする サンプルデータをダウンロードすると、次のプログラムを実行して Movies テーブルに入力できま す。 1. 次のプログラムを MoviesLoadData.rb というファイルにコピーします。 require "aws-sdk-core" require "json" Aws.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }) API Version 2012-08-10 137 Amazon DynamoDB 入門ガイド ステップ 3: 項目を作成、読み込み、更新、削除する dynamodb = Aws::DynamoDB::Client.new tableName = 'Movies' file = File.read('moviedata.json') movies = JSON.parse(file) movies.each{|movie| params = { table_name: tableName, item: movie } begin result = dynamodb.put_item(params) puts "Added movie: #{movie["year"]} #{movie["title"]}" rescue Aws::DynamoDB::Errors::ServiceError => error puts "Unable to add movie:" puts "#{error.message}" end } 2. 次のコマンドを入力してコマンドを実行します。 ruby MoviesLoadData.rb ステップ 3: 項目を作成、読み込み、更新、削除 する このステップでは、Movies テーブルの項目で読み取り/書き込みオペレーションを実行します。 データの読み取りと書き込みの詳細については、『Amazon DynamoDB 開発者ガイド』の「項目の操 作」を参照してください。 トピック • ステップ 3.1: 新しい項目を作成する (p. 138) • ステップ 3.2: 項目を読み取る (p. 139) • ステップ 3.3: 項目を更新する (p. 140) • ステップ 3.4: アトミックカウンターを増分する (p. 142) • ステップ 3.5: 項目を更新する (条件付き) (p. 143) • ステップ 3.6: 項目を削除する (p. 144) ステップ 3.1: 新しい項目を作成する このステップでは、テーブルに新しい項目を追加します。 1. 次のプログラムを MoviesItemOps01.rb というファイルにコピーします。 require "aws-sdk-core" API Version 2012-08-10 138 Amazon DynamoDB 入門ガイド ステップ 3.2: 項目を読み取る Aws.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }) dynamodb = Aws::DynamoDB::Client.new tableName = 'Movies' year = 2015 title = "The Big New Movie" item = { year: year, title: title, info: { plot: "Nothing happens at all.", rating: 0 } } params = { table_name: "Movies", item: item } begin result = dynamodb.put_item(params) puts "Added item: #{year} - #{title}" rescue Aws::DynamoDB::Errors::ServiceError => error puts "Unable to add item:" puts "#{error.message}" end Note プライマリキーは必須です。このコードは、プライマリキー (year, title) と info 属 性を持つ項目を追加します。info 属性には、映画についての詳細情報を示すマップが保 存されます。 2. 次のコマンドを入力してコマンドを実行します。 ruby MoviesItemOps01.rb ステップ 3.2: 項目を読み取る 前のプログラムでは、テーブルに次の項目を追加しました。 { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } API Version 2012-08-10 139 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する Movies テーブルから項目を読み取る、get_item メソッドを使用できます。 プライマリキー値を指 定する必要があります。そうすると year と title がわかれば、Movies から項目を読み込むことが できます。 1. 次のプログラムを MoviesItemOps02.rb というファイルにコピーします。 require "aws-sdk-core" Aws.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }) dynamodb = Aws::DynamoDB::Client.new tableName = 'Movies' year = 2015 title = "The Big New Movie" key = { year: year, title: title } params = { table_name: "Movies", key: { year: year, title: title } } begin result = dynamodb.get_item(params) printf "%i - %s\n%s\n%d\n", result.item["year"], result.item["title"], result.item["info"]["plot"], result.item["info"]["rating"] rescue Aws::DynamoDB::Errors::ServiceError => error puts "Unable to read item:" puts "#{error.message}" end 2. 次のコマンドを入力してコマンドを実行します。 ruby MoviesItemOps02.rb ステップ 3.3: 項目を更新する update_item メソッドを使用して既存の項目を変更できます。既存の属性の値の更新、新しい属性 の追加、または属性の削除を行えます。 このチュートリアルでは、次の更新を行います。 • 既存の属性の値を変更します (rating、plot)。 API Version 2012-08-10 140 Amazon DynamoDB 入門ガイド ステップ 3.3: 項目を更新する • 新しいリスト属性 (actors) を既存の info マップに追加します。 項目の変更前: { year: 2015, title: "The Big New Movie", info: { plot: "Nothing happens at all.", rating: 0 } } 項目の変更後: { year: 2015, title: "The Big New Movie", info: { plot: "Everything happens all at once.", rating: 5.5, actors: ["Larry", "Moe", "Curly"] } } 1. 次のプログラムを MoviesItemOps03.rb というファイルにコピーします。 require "aws-sdk-core" Aws.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }) dynamodb = Aws::DynamoDB::Client.new tableName = 'Movies' year = 2015 title = "The Big New Movie" params = { table_name: "Movies", key: { year: year, title: title }, update_expression: "set info.rating = :r, info.plot=:p, info.actors=:a", expression_attribute_values: { ":r" => 5.5, ":p" => "Everything happens all at once.", # value <Hash,Array,String,Numeric,Boolean,IO,Set,nil> ":a" => ["Larry", "Moe", "Curly"] }, return_values: "UPDATED_NEW" API Version 2012-08-10 141 Amazon DynamoDB 入門ガイド ステップ 3.4: アトミックカウンターを増分する } begin result = dynamodb.update_item(params) puts "Added item: #{year} - #{title}" rescue Aws::DynamoDB::Errors::ServiceError => error puts "Unable to add item:" puts "#{error.message}" end Note このプログラムでは、update_expression を使用して、指定された項目で実行するす べての更新を記述します。 return_values パラメーターは、DynamoDB に更新された属性 (UPDATED_NEW) のみ を返すように指示します。 2. 次のコマンドを入力してコマンドを実行します。 ruby MoviesItemOps03.rb ステップ 3.4: アトミックカウンターを増分する DynamoDB では、アトミックカウンターがサポートされています。そのため、update_item メソッ ドを使用して、他の書き込みリクエストを妨げることなく既存の属性値をインクリメントまたはデク リメントできます。(すべての書き込みリクエストは、受信された順に適用されます)。 次のプログラムは、映画の rating を増分する方法を示しています。実行するたびに、プログラムは この属性を 1 つ増分します。 1. 次のプログラムを MoviesItemOps04.rb というファイルにコピーします。 require "aws-sdk-core" Aws.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }) dynamodb = Aws::DynamoDB::Client.new tableName = 'Movies' year = 2015 title = "The Big New Movie" params = { table_name: "Movies", key: { year: year, title: title }, update_expression: "set info.rating = info.rating + :val", expression_attribute_values: { ":val" => 1 }, API Version 2012-08-10 142 Amazon DynamoDB 入門ガイド ステップ 3.5: 項目を更新する (条件付き) return_values: "UPDATED_NEW" } begin result = dynamodb.update_item(params) puts "Updated item. ReturnValues are:" result.attributes["info"].each do |key, value| if key == "rating" puts "#{key}: #{value.to_f}" else puts "#{key}: #{value}" end end rescue Aws::DynamoDB::Errors::ServiceError => error puts "Unable to update item:" puts "#{error.message}" end 2. 次のコマンドを入力してコマンドを実行します。 ruby MoviesItemOps04.rb ステップ 3.5: 項目を更新する (条件付き) 次のプログラムは、条件とともに update_item を使用する方法を示しています。条件が true と評価 された場合、更新は成功します。それ以外の場合、更新は行われません。 その場合、項目は 3 人より多い役者がいる場合にのみ更新されます。 1. 次のプログラムを MoviesItemOps05.rb というファイルにコピーします。 require "aws-sdk-core" Aws.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }) dynamodb = Aws::DynamoDB::Client.new tableName = 'Movies' year = 2015 title = "The Big New Movie" params = { table_name: "Movies", key: { year: year, title: title }, update_expression: "remove info.actors[0]", condition_expression: "size(info.actors) > :num", expression_attribute_values: { ":num" => 3 }, return_values: "UPDATED_NEW" } API Version 2012-08-10 143 Amazon DynamoDB 入門ガイド ステップ 3.6: 項目を削除する begin result = dynamodb.update_item(params) puts "Updated item. ReturnValues are:" result.attributes["info"].each do |key, value| if key == "rating" puts "#{key}: #{value.to_f}" else puts "#{key}: #{value}" end end rescue Aws::DynamoDB::Errors::ServiceError => error puts "Unable to update item:" puts "#{error.message}" end 2. 次のコマンドを入力してコマンドを実行します。 ruby MoviesItemOps05.rb プログラムは次のメッセージで失敗するはずです。 The conditional request failed これは、映画に 3 人の役者が出演しているが、条件は役者が 3 人より多いことをチェックしてい るためです。 3. ConditionExpression が次のようになるようにプログラムを変更します。 condition_expression: "size(info.actors) >= :num", 条件が、3 より大きいではなく 3 以上になりました。 4. プログラムを再度実行します。update_item メソッドは成功します。 ステップ 3.6: 項目を削除する プライマリキーを指定することで、delete_item メソッドを使用して 1 つの項目を削除できます。 オプションで condition_expression を指定して、条件を満たさない場合に項目の削除を防ぐこと ができます。 次の例では、レーティングが 5 以下の特定の映画項目を削除しようとします。 1. 次のプログラムを MoviesItemOps06.rb というファイルにコピーします。 require "aws-sdk-core" Aws.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }) dynamodb = Aws::DynamoDB::Client.new tableName = 'Movies' year = 2015 API Version 2012-08-10 144 Amazon DynamoDB 入門ガイド ステップ 4: データをクエリおよびスキャンする title = "The Big New Movie" params = { table_name: "Movies", key: { year: year, title: title }, condition_expression: "info.rating <= :val", expression_attribute_values: { ":val" => 5 } } begin result = dynamodb.delete_item(params) puts "Deleted item." rescue Aws::DynamoDB::Errors::ServiceError => error puts "Unable to update item:" puts "#{error.message}" end 2. 次のコマンドを入力してコマンドを実行します。 ruby MoviesItemOps06.rb プログラムは次のメッセージで失敗するはずです。 The conditional request failed これは、この特定の映画のレーティングが 5 より大きいためです。 3. 条件を削除するようにプログラムを変更します。 params = { table_name: "Movies", key: { year: year, title: title } } 4. プログラムを実行します。ここでは、条件を削除したため、削除が成功します。 ステップ 4: データをクエリおよびスキャンする query メソッドを使用して、テーブルからデータを取得できます。パーティションのキー値を指定す る必要があります。ソートキーはオプションです。 Movies テーブルのプライマリキーは、以下の内容で構成されます。 • year – パーティションキー。属性タイプは数値です。 • title – ソートキー。属性タイプは文字列です。 1 年間にリリースされたすべての映画を検索するには、year のみ指定する必要があります。title を指定して、いくつかの条件 (ソートキー上) に基づいて映画のサブセットを取得することもできま す。たとえば、2014 年にリリースされて、主題が「A」で始まる映画を探す場合です。 API Version 2012-08-10 145 Amazon DynamoDB 入門ガイド ステップ 4.1: クエリ - 1 年間 にリリースされたすべての映画 query に加えて、すべてのテーブルデータを取得可能な scan メソッドもあります。 データのクエリとスキャンの詳細については、『Amazon DynamoDB 開発者ガイド』の「クエリおよ びスキャン」を参照してください。 トピック • ステップ 4.1: クエリ - 1 年間にリリースされたすべての映画 (p. 146) • ステップ 4.2: クエリ - 1 年間にリリースされた特定のタイトルを持つすべての映画 (p. 147) • ステップ 4.3: スキャン (p. 148) ステップ 4.1: クエリ - 1 年間にリリースされたすべ ての映画 次のプログラムでは、year が 1985 にリリースされたすべての映画を取得します。 1. 次のプログラムを MoviesQuery01.rb というファイルにコピーします。 require "aws-sdk-core" Aws.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }) dynamodb = Aws::DynamoDB::Client.new tableName = "Movies" params = { table_name: tableName, key_condition_expression: "#yr = :yyyy", expression_attribute_names: { "#yr" => "year" }, expression_attribute_values: { ":yyyy" => 1985 } } puts "Querying for movies from 1985."; begin result = dynamodb.query(params) puts "Query succeeded." result.items.each{|movie| puts "#{movie["year"].to_i} #{movie["title"]}" } rescue Aws::DynamoDB::Errors::ServiceError => error puts "Unable to query table:" puts "#{error.message}" end API Version 2012-08-10 146 Amazon DynamoDB 入門ガイド ステップ 4.2: クエリ - 1 年間にリリース された特定のタイトルを持つすべての映画 Note • expression_attribute_names は、名前を置換します。year は DynamoDB の予約 語であるため、これが使用されます。KeyConditionExpression を含むどの式でも 直接使用することはできません。これに対処するため、式の属性名 #yr が使用されま す。 • expression_attribute_values は、値を置換しま す。key_condition_expression を含むどの式にもリテラルを使用できないため、 これが使用されます。これに対処するため、式の属性値 :yyyy が使用されます。 2. 次のコマンドを入力してコマンドを実行します。 ruby MoviesItemQuery01.rb Note 前のプログラムは、プライマリキーの属性によってテーブルをクエリする方法を示していま す。DynamoDB では、必要に応じて 1 つ以上のセカンダリインデックスをテーブルに作成 し、テーブルをクエリするのと同じ方法でそれらのインデックスをクエリできます。セカン ダリインデックスは非キー属性のクエリを可能にすることで、アプリケーションに追加の柔 軟性を提供します。詳細については、Amazon DynamoDB 開発者ガイドの「セカンダリイン デックス」を参照してください。 ステップ 4.2: クエリ - 1 年間にリリースされた特定 のタイトルを持つすべての映画 次のプログラムは、year が 1992 に公開されたすべての映画から、文字 "A" から文字 "L" までで始ま る title を取得します。 1. 次のプログラムを MoviesQuery02.rb というファイルにコピーします。 require "aws-sdk-core" Aws.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }) dynamodb = Aws::DynamoDB::Client.new tableName = "Movies" params = { table_name: tableName, projection_expression: "#yr, title, info.genres, info.actors[0]", key_condition_expression: "#yr = :yyyy and title between :letter1 and :letter2", expression_attribute_names: { "#yr" => "year" }, expression_attribute_values: { ":yyyy" => 1992, ":letter1" => "A", ":letter2" => "L" } API Version 2012-08-10 147 Amazon DynamoDB 入門ガイド ステップ 4.3: スキャン } puts "Querying for movies from 1992 - titles A-L, with genres and lead actor"; begin result = dynamodb.query(params) puts "Query succeeded." result.items.each{|movie| print "#{movie["year"].to_i}: #{movie["title"]} ... " movie['info']['genres'].each{|gen| print gen + " " } print " ... #{movie["info"]["actors"][0]}\n" } rescue Aws::DynamoDB::Errors::ServiceError => error puts "Unable to query table:" puts "#{error.message}" end 2. 次のコマンドを入力してコマンドを実行します。 ruby MoviesQuery02.rb ステップ 4.3: スキャン scan メソッドは、テーブル全体のすべての項目を読み込み、テーブルの全データを返します。オプ ションで filter_expression を提供して、条件に一致する項目だけが返されるように指定できま す。ただし、テーブル全体がスキャンされた後にのみ、フィルタが適用されることに注意してくださ い。 次のプログラムは、約 5,000 項目を含む Movies テーブル全体をスキャンします。スキャンは、1950 年代の映画のみ (約 100 項目) を取得して、残りはすべて破棄するようオプションのフィルタを指定し ます。 1. 次のプログラムを MoviesScan.rb というファイルにコピーします。 require "aws-sdk-core" Aws.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }) dynamodb = Aws::DynamoDB::Client.new tableName = "Movies" params = { table_name: tableName, projection_expression: "#yr, title, info.rating", filter_expression: "#yr between :start_yr and :end_yr", expression_attribute_names: {"#yr"=> "year"}, expression_attribute_values: { API Version 2012-08-10 148 Amazon DynamoDB 入門ガイド ステップ 5: (オプション) テーブルを削除する ":start_yr" => 1950, ":end_yr" => 1959 } } puts "Scanning Movies table." begin loop do result = dynamodb.scan(params) result.items.each{|movie| puts "#{movie["year"].to_i}: " + "#{movie["title"]} ... " + "#{movie["info"]["rating"].to_f}" } break if result.last_evaluated_key.nil? puts "Scanning for more..." params[:exclusive_start_key] = result.last_evaluated_key end rescue Aws::DynamoDB::Errors::ServiceError => error puts "Unable to scan:" puts "#{error.message}" end このコードでは、以下の点に注意してください。 • projection_expression は、スキャン結果に必要な属性を指定します。 • filter_expression は、条件を満たした項目だけが返されるような条件を指定します。他の すべての項目は破棄されます。 2. 次のコマンドを入力してコマンドを実行します。 ruby MoviesScan.rb Note テーブルで作成した任意のセカンダリインデックスで scan メソッドを使用することもできま す。詳細については、Amazon DynamoDB 開発者ガイドの「セカンダリインデックス」を参 照してください。 ステップ 5: (オプション) テーブルを削除する Movies テーブルを削除するには: 1. 次のプログラムを MoviesDeleteTable.rb というファイルにコピーします。 require "aws-sdk-core" Aws.config.update({ region: "us-west-2", endpoint: "http://localhost:8000" }) API Version 2012-08-10 149 Amazon DynamoDB 入門ガイド 概要 dynamodb = Aws::DynamoDB::Client.new params = { table_name: "Movies" } begin result = dynamodb.delete_table(params) puts "Deleted table." rescue Aws::DynamoDB::Errors::ServiceError => error puts "Unable to delete table:" puts "#{error.message}" end 2. 次のコマンドを入力してコマンドを実行します。 ruby MoviesDeleteTable.rb 概要 このチュートリアルでは、ご使用のコンピューターの DynamoDB で Movies テーブルを作成し、 基本的なオペレーションを実行しました。ダウンロード可能なバージョンの DynamoDB は、アプリ ケーションの開発およびテストの際に便利です。ただし、本番環境でアプリケーションを実行する場 合、Amazon DynamoDB ウェブサービスを使用できるようにコードを変更します。 Amazon DynamoDB サービスを使用する Amazon DynamoDB サービスを使用するには、アプリケーションのエンドポイントを変更する必要が あります。そのためには、コードで次の行を見つけます。 $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', 'region' => 'us-west-2', 'version' => 'latest' ]); ここで、endpoint パラメーターを削除してコードを次のようにします。 $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); この行を削除すると、コードは設定値 region で指定されたリージョン内の DynamoDB サービスに アクセスできます。たとえば、次の行は、米国西部 (オレゴン) リージョンを使用することを指定しま す。 'region' => 'us-west-2', プログラムはコンピュータで DynamoDB を使用する代わりに、米国西部 (オレゴン) で DynamoDB サービスエンドポイントを使用します。 API Version 2012-08-10 150 Amazon DynamoDB 入門ガイド Amazon DynamoDB サービスを使用する Amazon DynamoDB は、世界中の AWS リージョンで利用できます。完全なリストについては、AWS General Referenceの「リージョンとエンドポイント」を参照してください。詳細については、 「AWS SDK for Ruby 入門ガイド」を参照してください。 最後に、「Amazon DynamoDB 開発者ガイド」を読むことをお勧めします。ここには、サンプルコー ドやベストプラクティスなど、DynamoDB に関するさらに詳しい情報が収められています。 API Version 2012-08-10 151
© Copyright 2025 Paperzz