

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Amazon OpenSearch Service のチュートリアル
<a name="tutorials"></a>

この章には、サービスへの移行、簡単な検索アプリケーションの構築、OpenSearch Dashboards での可視化の作成など、Amazon OpenSearch Service を使用するための全般的なチュートリアルがいくつか含まれています。

**Topics**
+ [チュートリアル: Amazon OpenSearch Service でドキュメントを作成および検索する](quick-start.md)
+ [チュートリアル: Amazon OpenSearch Service への移行](migration.md)
+ [チュートリアル: Amazon OpenSearch Service を用いて検索アプリケーションを作成する](search-example.md)
+ [チュートリアル: OpenSearch Service と OpenSearch Dashboards によるカスタマーサポートへの問い合わせを可視化する](walkthrough.md)

# チュートリアル: Amazon OpenSearch Service でドキュメントを作成および検索する
<a name="quick-start"></a>

このチュートリアルでは、Amazon OpenSearch Service でドキュメントを作成および検索する方法を説明します。データを JSON ドキュメント形式でインデックスに追加します。OpenSearch Service は、追加した最初のドキュメントに関するインデックスを作成します。

このチュートリアルでは、HTTP リクエストを実行してドキュメントを作成し、ドキュメントの ID を自動的に生成し、ドキュメントに対して基本的な検索および高度な検索を実行する方法を説明します。

**注記**  
このチュートリアルでは、オープンアクセスを持つドメインを使用します。最高レベルのセキュリティを実現するため、仮想プライベートクラウド (VPC) 内にドメインを配置することをお勧めします。

## 前提条件
<a name="quick-start-prereqs"></a>

このチュートリアルには、次のような前提条件があります。
+ が必要です AWS アカウント。
+ アクティブな OpenSearch Service のドメインが必要です。

## ドキュメントのインデックスへの追加
<a name="quick-start-create"></a>

ドキュメントをインデックスに追加するために、[Postman](https://www.getpostman.com/)、cURL、または OpenSearch Dashboards コンソールなどの任意の HTTP ツールを使用できます。これらの例は、OpenSearch Dashboards でデベロッパーコンソールを使用していることを前提としています。別のツールを使用している場合は、必要に応じて完全な URL と認証情報を入力して、適宜調整してください。

**ドキュメントをインデックスに追加するには**

1. 使用しているドメインの OpenSearch Dashboards URL に移動します。この URL は、OpenSearch Service コンソールのドメインダッシュボードに表示されています。URL はこの形式に従います。

   ```
   domain-endpoint/_dashboards/
   ```

1. プライマリユーザー名とパスワードを使ってサインインします。

1. 左側のナビゲーションパネルを開き、**[Dev Tools]** (開発ツール) を選択します。

1. 新しいリソースを作成するための HTTP 動詞は PUT です。これは、新しいドキュメントとインデックスの作成に使用します。コンソールに次のコマンドを入力します。

   ```
   PUT fruit/_doc/1
   {
     "name":"strawberry",
     "color":"red"
   }
   ```

   `PUT` リクエストは、fruit という名前のインデックスを作成し、ID が 1 である単一のドキュメントをインデックスに追加します。次のレスポンスが生成されます。

   ```
   {
     "_index" : "fruit",
     "_type" : "_doc",
     "_id" : "1",
     "_version" : 1,
     "result" : "created",
     "_shards" : {
       "total" : 2,
       "successful" : 2,
       "failed" : 0
     },
     "_seq_no" : 0,
     "_primary_term" : 1
   }
   ```

## 自動的に生成される ID の作成
<a name="quick-start-id"></a>

OpenSearch Service は、ドキュメントの ID を自動的に生成できます。ID を生成するコマンドは、PUT リクエストの代わりに POST リクエストを使用し、(前のリクエストと比較して) ドキュメント ID を必要としません。

デベロッパーコンソールに次のリクエストを入力します。

```
POST veggies/_doc
{
  "name":"beet",
  "color":"red",
  "classification":"root"
}
```

このリクエストは、veggies という名前のインデックスを作成し、ドキュメントをインデックスに追加します。次のレスポンスが生成されます。

```
{
  "_index" : "veggies",
  "_type" : "_doc",
  "_id" : "3WgyS4IB5DLqbRIvLxtF",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}
```

レスポンスの追加 `_id` フィールドに注意してください。これは、ID が自動的に作成されたことを示します。

**注記**  
URL の `_doc` の後には何も入力しません。ここには通常 ID が挿入されます。生成される ID を使用してドキュメントを作成しようとしているため、まだ ID を入力しません。これは更新の際に行います。

## POST コマンドを使用したドキュメントの更新
<a name="quick-start-update"></a>

ドキュメントを更新するには、ID 番号を持つ HTTP `POST` コマンドを使用します。

最初に、ID が `42` のドキュメントを作成します。

```
POST fruits/_doc/42
{
  "name":"banana",
  "color":"yellow"
}
```

その後、その ID を使用してドキュメントを更新します。

```
POST fruits/_doc/42
{
  "name":"banana",
  "color":"yellow",
  "classification":"berries"
}
```

このコマンドは、ドキュメントを新しいフィールド `classification` で更新します。次のレスポンスが生成されます。

```
{
  "_index" : "fruits",
  "_type" : "_doc",
  "_id" : "42",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "failed" : 0
  },
  "_seq_no" : 1,
  "_primary_term" : 1
}
```

**注記**  
存在しないドキュメントを更新しようとすると、OpenSearch Service はドキュメントを作成します。

## 一括アクションの実行
<a name="quick-start-bulk"></a>

`POST _bulk` API オペレーションを使用して、1 回のリクエストで 1 つ以上のインデックスに対して複数のアクションを実行できます。一括アクションコマンドは、次の形式になります。

```
POST /_bulk
<action_meta>\n
<action_data>\n
<action_meta>\n
<action_data>\n
```

各アクションには 2 行の JSON が必要です。まず、アクションの説明またはメタデータを入力します。次の行で、データを入力します。各パートは改行 (\$1n) で区切られます。挿入のアクションの説明は次のようになります。

```
{ "create" : { "_index" : "veggies", "_type" : "_doc", "_id" : "7" } }
```

また、データを含む次の行は次のようになります。

```
{ "name":"kale", "color":"green", "classification":"leafy-green" }
```

メタデータとデータをまとめると、一括オペレーションでの 1 つのアクションが表されます。次のように、1 つのリクエストで多くのオペレーションを実行できます。

```
POST /_bulk
{ "create" : { "_index" : "veggies", "_id" : "35" } }
{ "name":"kale", "color":"green", "classification":"leafy-green" }
{ "create" : { "_index" : "veggies", "_id" : "36" } }
{ "name":"spinach", "color":"green", "classification":"leafy-green" }
{ "create" : { "_index" : "veggies", "_id" : "37" } }
{ "name":"arugula", "color":"green", "classification":"leafy-green" }
{ "create" : { "_index" : "veggies", "_id" : "38" } }
{ "name":"endive", "color":"green", "classification":"leafy-green" }
{ "create" : { "_index" : "veggies", "_id" : "39" } }
{ "name":"lettuce", "color":"green", "classification":"leafy-green" }
{ "delete" : { "_index" : "vegetables", "_id" : "1" } }
```

最後のアクションが `delete` であることに注意してください。`delete` アクションに続くデータはありません。

## ドキュメントの検索
<a name="quick-start-search"></a>

これでクラスターにデータが存在するようになったので、そのデータを検索できます。例えば、すべての根菜類を検索したり、すべての葉菜類の数を取得したり、1 時間あたりにログ記録されたエラーの数を調べたりすることができます。

**基本的な検索**

基本的な検索は次のようになります。

```
GET veggies/_search?q=name:l*
```

リクエストにより、レタスドキュメントを含む JSON レスポンスが生成されます。

**高度な検索**

リクエスト本文でクエリオプションを JSON として指定すると、より高度な検索を実行できます。

```
GET veggies/_search
{
  "query": {
    "term": {
      "name": "lettuce"
    }
  }
}
```

この例では、レタスドキュメントを含む JSON レスポンスも生成します。

**ソート**

ソートを使用すると、このタイプのクエリをさらに多く実行できます。まず、インデックスを再作成する必要があります。これは、自動フィールドマッピングが、デフォルトではソートできないタイプを選択するためです。次のリクエストを送信して、インデックスを削除して再作成します。

```
DELETE /veggies

PUT /veggies
{
   "mappings":{
      "properties":{
         "name":{
            "type":"keyword"
         },
         "color":{
            "type":"keyword"
         },
         "classification":{
            "type":"keyword"
         }
      }
   }
}
```

その後、インデックスにデータを再入力します。

```
POST /_bulk
{ "create" : { "_index" : "veggies", "_id" : "7"  } }
{ "name":"kale", "color":"green", "classification":"leafy-green" }
{ "create" : { "_index" : "veggies", "_id" : "8" } }
{ "name":"spinach", "color":"green", "classification":"leafy-green" }
{ "create" : { "_index" : "veggies", "_id" : "9" } }
{ "name":"arugula", "color":"green", "classification":"leafy-green" }
{ "create" : { "_index" : "veggies", "_id" : "10" } }
{ "name":"endive", "color":"green", "classification":"leafy-green" }
{ "create" : { "_index" : "veggies", "_id" : "11" } }
{ "name":"lettuce", "color":"green", "classification":"leafy-green" }
```

これで、ソートを使用して検索できるようになりました。このリクエストでは、分類による昇順のソートが追加されます。

```
GET veggies/_search
{
  "query" : {
    "term": { "color": "green" }
  },
  "sort" : [
      "classification"
  ]
}
```

## 関連リソース
<a name="quick-start-resources"></a>

詳細については、以下のリソースを参照してください。
+ [Amazon OpenSearch Service の開始方法](gsg.md)
+ [Amazon OpenSearch Service でのデータのインデックス作成](indexing.md)
+ [Amazon OpenSearch Serviceでのデータの検索](searching.md)

# チュートリアル: Amazon OpenSearch Service への移行
<a name="migration"></a>

インデックススナップショットは、セルフマネージド OpenSearch または従来の Elasticsearch クラスターから Amazon OpenSearch Service に移行する一般的な方法です。そのプロセスは、大きく分けて以下のステップで構成されています。

1. 既存のクラスターのスナップショットを作成し、そのスナップショットを Amazon S3 バケットにアップロードする。

1. OpenSearch Service ドメインを作成する。

1. バケットにアクセスするための許可を OpenSearch Service に付与し、スナップショットを使用するための許可があることを確認する。

1. OpenSearch Service ドメインでスナップショットを復元する。

このチュートリアルでは、より詳細な手順と代替のオプション (ある場合) について説明します。

## スナップショットの作成とアップロード
<a name="migration-take-snapshot"></a>

[repository-s3](https://docs.opensearch.org/latest/opensearch/snapshot-restore/#amazon-s3) プラグインを使用して S3 に直接スナップショットを取得できますが、プラグインをすべてのノードにインストールし、調整 `opensearch.yml` (または Elasticsearch クラスター`elasticsearch.yml`を使用している場合）、各ノードを再起動し、 AWS 認証情報を追加して、最後にスナップショットを作成する必要があります。このプラグインは、継続使用や大規模なクラスターの移行の場合に役立ちます。

小規模なクラスターの場合、1 回限りのアプローチとして、[共有ファイルシステムのスナップショット](https://docs.opensearch.org/latest/opensearch/snapshot-restore/#shared-file-system)を作成し、 を使用して S3 AWS CLI にアップロードします。すでにスナップショットを作成している場合は、手順 4 に進んでください。

****スナップショットを取り、Amazon S3 にアップロードするには****

1. すべてのノードで `opensearch.yml` (または `Elasticsearch.yml`) に `path.repo` 設定を追加して、各ノードを再起動します。

   ```
   path.repo: ["/my/shared/directory/snapshots"]
   ```

1. スナップショットを作成する前に必要な [スナップショットリポジトリ](https://opensearch.org/docs/latest/opensearch/snapshot-restore/#register-repository) を登録します。リポジトリは単なる保存場所です。共有ファイルシステム、Amazon S3、File system distribuito Hadoop (HDFS) などです。この場合、共有ファイルシステム (「fs」) を使用します。

   ```
   PUT _snapshot/my-snapshot-repo-name
   {
     "type": "fs",
     "settings": {
       "location": "/my/shared/directory/snapshots"
     }
   }
   ```

1. スナップショットを作成します。

   ```
   PUT _snapshot/my-snapshot-repo-name/my-snapshot-name
   {
     "indices": "migration-index1,migration-index2,other-indices-*",
     "include_global_state": false
   }
   ```

1. [AWS CLI](https://aws.amazon.com/cli/) をインストールし、`aws configure` を実行して認証情報を追加します。

1. スナップショットのディレクトリに移動します。次のコマンドを実行して新しい S3 バケットを作成し、スナップショットのディレクトリの中身をそのバケットにアップロードします。

   ```
   aws s3 mb s3://amzn-s3-demo-bucket --region us-west-2
   aws s3 sync . s3://amzn-s3-demo-bucket --sse AES256
   ```

   スナップショットのサイズとインターネット接続の速度によっては、この操作に時間がかかる場合があります。

## ドメインの作成
<a name="migration-create-domain"></a>

コンソールはドメインを作成する最も簡単な方法ですが、この場合、ターミナルはすでに開いていて、 AWS CLI がインストールされています。次のコマンドを変更して、ニーズに合わせてドメインを作成してください。

```
aws opensearch create-domain \
  --domain-name migration-domain \
  --engine-version OpenSearch_1.0 \
  --cluster-config InstanceType=c5.large.search,InstanceCount=2 \
  --ebs-options EBSEnabled=true,VolumeType=gp2,VolumeSize=100 \
  --node-to-node-encryption-options Enabled=true \
  --encryption-at-rest-options Enabled=true \
  --domain-endpoint-options EnforceHTTPS=true,TLSSecurityPolicy=Policy-Min-TLS-1-2-2019-07 \
  --advanced-security-options Enabled=true,InternalUserDatabaseEnabled=true,MasterUserOptions='{MasterUserName=master-user,MasterUserPassword=master-user-password}' \
  --access-policies '{"Version": "2012-10-17",		 	 	 "Statement":[{"Effect":"Allow","Principal": {"AWS": "arn:aws:iam::aws-region:user/UserName"},"Action":["es:ESHttp*"],"Resource":"arn:aws:es:aws-region:111122223333:domain/migration-domain/*"}]}' \
  --region aws-region
```

このコマンドでは、それぞれ 100 GiB のストレージを持つ 2 つのデータノードがあるインターネットにアクセス可能なドメインが作成されます。また、HTTP Basic 認証とすべての暗号化の設定により、[きめ細かなアクセスコントロール](fgac.md)が可能になります。VPC などのアドバンストセキュリティ設定が必要な場合は、OpenSearch Service コンソールを使用してください。

このコマンドを発行する前に、ドメイン名、マスターユーザーの認証情報、アカウント番号を変更します。S3 バケット AWS リージョン に使用したものと同じ と、スナップショットと互換性のある OpenSearch/Elasticsearch バージョンを指定します。

**重要**  
スナップショットには上位互換性のみがあり、その対象は 1 つのメジャーバージョンのみです。例えば、Elasticsearch 7.*x* クラスター上の OpenSearch 1 *x* クラスターからスナップショットを復元することはできず、OpenSearch 1.*x* または 2.*x* クラスターのみです。また、マイナーバージョンも同様です。セルフマネージド 5.3.3 クラスターのスナップショットを 5.3.2 の OpenSearch Service ドメインに復元することはできません。OpenSearch または Elasticsearch は、スナップショットがサポートしている最新バージョンを選択することをお勧めします。互換性のあるバージョンのテーブルについては、「[スナップショットを使用してデータを移行する](snapshot-based-migration.md)」を参照してください。

## S3 バケットへの許可を提供します。
<a name="migration-permissions"></a>

 AWS Identity and Access Management (IAM) コンソールで、[次のアクセス許可と信頼関係を持つロールを作成します](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create.html)。 [https://docs.aws.amazon.com/IAM/latest/UserGuide/roles-managingrole-editing-console.html#roles-managingrole_edit-trust-policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/roles-managingrole-editing-console.html#roles-managingrole_edit-trust-policy)ロールの作成時に、**AWS サービス**として **S3** を選択します。このロールには、分かりやすいように `OpenSearchSnapshotRole` と名前を付けます。

**アクセス許可**

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [{
      "Action": [
        "s3:ListBucket"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::amzn-s3-demo-bucket"
      ]
    },
    {
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Effect": "Allow",
      "Resource": [
        "arn:aws:s3:::amzn-s3-demo-bucket/*"
      ]
    }
  ]
}
```

------

**信頼関係**

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [{
      "Effect": "Allow",
      "Principal": {
        "Service": "es.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

------

次に、個人的な IAM ロールに、`OpenSearchSnapshotRole` を引き受ける許可を付与します。以下のポリシーを作成して、アイデンティティに[アタッチ](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html)します。

**アクセス許可**

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [{
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": "arn:aws:iam::123456789012:role/OpenSearchSnapshotRole"
    }
  ]
}
```

------

### OpenSearch Dashboards にスナップショットロールをマッピングします (きめ細かなアクセスコントロールを使用している場合)
<a name="migration-snapshot-role"></a>

[きめ細かなアクセスコントロール](fgac.md#fgac-mapping)を有効にした場合は、HTTP 基本認証をその他すべての目的で使用する場合でも、`manage_snapshots` ロールを IAM ロールにマップして、スナップショットを使用できるようにする必要があります。

**スナップショットを使用するためのアイデンティティの許可を提供するには**

1. OpenSearch Service ドメインの作成時に指定したマスターユーザーの認証情報を使用して Dashboards にログインします。Dashboards URL は、OpenSearch Service コンソールに表示されます。`https://domain-endpoint/_dashboards/` の形式です。

1. メインメニューから [**セキュリティ**]、[**ロール**] を選択し、[**manage\$1snapshots**] ロールを選択します。

1. **[マッピングされたユーザー]**、**[マッピングの管理]** を選択します。

1. 適切なフィールドに、個人的な IAM ロールのドメイン ARN を追加します。ARN は次のいずれかの形式となります。

   ```
   arn:aws:iam::123456789123:user/user-name
   ```

   ```
   arn:aws:iam::123456789123:role/role-name
   ```

1. **マップ**を選択し、ロールが**マッピングされたユーザー**に表示されていることを確認します。

## スナップショットを復元する
<a name="migration-restore"></a>

この時点で、OpenSearch Service ドメインにアクセスするには、マスターユーザー認証情報を使用した HTTP 基本認証または IAM 認証情報を使用した AWS 認証の 2 つの方法があります。スナップショットはマスターユーザーの概念がない Amazon S3 を使用するため、IAM 認証情報を使用してスナップショットのリポジトリを OpenSearch Service ドメインに登録する必要があります。

ほとんどのプログラミング言語にはリクエストの署名に役立つライブラリがありますが、[Postman](https://www.postman.com/downloads/) などのツールを使用して IAM 認証情報を **[認可]** セクションに入力するのが簡単な方法です。

![\[Postman interface showing Authorization settings for AWS API request with Signature type.\]](http://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/images/migration2.png)


**スナップショットを復元するには**

1. リクエストにどのような方法で署名するかにかかわらず、まずリポジトリを登録します。

   ```
   PUT _snapshot/my-snapshot-repo-name
   {
     "type": "s3",
     "settings": {
       "bucket": "amzn-s3-demo-bucket",
       "region": "us-west-2",
       "role_arn": "arn:aws:iam::123456789012:role/OpenSearchSnapshotRole"
     }
   }
   ```

1. 次に、リポジトリ内のスナップショットを一覧表示し、復元するスナップショットを見つけます。この時点で、Postman を続けて使用するか、[curl](https://curl.haxx.se/) などのツールに切り替えることができます。

   **短縮構文**

   ```
   GET _snapshot/my-snapshot-repo-name/_all
   ```

   **curl**

   ```
   curl -XGET -u 'master-user:master-user-password' https://domain-endpoint/_snapshot/my-snapshot-repo-name/_all
   ```

1. スナップショットを復元します。

   **短縮構文**

   ```
   POST _snapshot/my-snapshot-repo-name/my-snapshot-name/_restore
   {
     "indices": "migration-index1,migration-index2,other-indices-*",
     "include_global_state": false
   }
   ```

   **curl**

   ```
   curl -XPOST -u 'master-user:master-user-password' https://domain-endpoint/_snapshot/my-snapshot-repo-name/my-snapshot-name/_restore \
     -H 'Content-Type: application/json' \
     -d '{"indices":"migration-index1,migration-index2,other-indices-*","include_global_state":false}'
   ```

1. 最後に、インデックスが正常に復元されていることを検証します。

   **短縮構文**

   ```
   GET _cat/indices?v
   ```

   **curl**

   ```
   curl -XGET -u 'master-user:master-user-password' https://domain-endpoint/_cat/indices?v
   ```

これで、移行は完了です。続いて、新しい OpenSearch Service エンドポイントを使用するようにクライアントを設定したり、ワークロードに合わせて[ドメインのサイズを変更](sizing-domains.md)したり、インデックスのシャード数を確認したり、[IAM マスターユーザー](fgac.md#fgac-concepts)に切り替えたり、OpenSearch Dashboards での可視化の構築を開始したりすることができます。

# チュートリアル: Amazon OpenSearch Service を用いて検索アプリケーションを作成する
<a name="search-example"></a>

Amazon OpenSearch Service を用いて検索アプリケーションを作成する一般的な方法は、サーバーへのユーザークエリを送信するウェブフォームを使用することです。次に、OpenSearch API を直接呼び出すようサーバーを承認し、サーバーが OpenSearch Service にリクエストを送信するようにします。ただし、サーバーに依存しないクライアント側のコードを記述する場合は、セキュリティとパフォーマンスのリスクを補正する必要があります。OpenSearch API への、署名されていないパブリックアクセスを許可することはお勧めしません。ユーザーは、保護されていないエンドポイントにアクセスしたり、過度に広範なクエリ (または多すぎるクエリ) によりクラスターのパフォーマンスに影響を及ぼす可能性があります。

この章では、Amazon API Gateway を使用して OpenSearch API APIsし、API Gateway から OpenSearch Service へのリクエストに署名 AWS Lambda するソリューションについて説明します。

![\[検索アプリケーションのフロー図。\]](http://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/images/search-application-diagram.png)


**注記**  
スタンダードの API Gateway および Lambda 料金表が適用されますが、このチュートリアル内での使用は限定されているため、費用はごくわずかです。

## 前提条件
<a name="search-example-prereq"></a>

このチュートリアルの前提条件は、OpenSearch Service ドメインです。まだドメインを持っていない場合は、「[OpenSearch Service ドメインを作成する](gsgcreate-domain.md)」のステップに従って、ドメインを作成します。

## ステップ 1: サンプルデータのインデックス作成
<a name="search-example-index"></a>

[sample-movies.zip](samples/sample-movies.zip) をダウンロードして解凍します。その後 [\$1bulk](https://opensearch.org/docs/latest/api-reference/document-apis/bulk/) API オペレーションを使用して、`movies` インデックスに 5,000 個のドキュメントを追加します。

```
POST https://search-my-domain.us-west-1.es.amazonaws.com/_bulk
{ "index": { "_index": "movies", "_id": "tt1979320" } }
{"directors":["Ron Howard"],"release_date":"2013-09-02T00:00:00Z","rating":8.3,"genres":["Action","Biography","Drama","Sport"],"image_url":"http://ia.media-imdb.com/images/M/MV5BMTQyMDE0MTY0OV5BMl5BanBnXkFtZTcwMjI2OTI0OQ@@._V1_SX400_.jpg","plot":"A re-creation of the merciless 1970s rivalry between Formula One rivals James Hunt and Niki Lauda.","title":"Rush","rank":2,"running_time_secs":7380,"actors":["Daniel Brühl","Chris Hemsworth","Olivia Wilde"],"year":2013,"id":"tt1979320","type":"add"}
{ "index": { "_index": "movies", "_id": "tt1951264" } }
{"directors":["Francis Lawrence"],"release_date":"2013-11-11T00:00:00Z","genres":["Action","Adventure","Sci-Fi","Thriller"],"image_url":"http://ia.media-imdb.com/images/M/MV5BMTAyMjQ3OTAxMzNeQTJeQWpwZ15BbWU4MDU0NzA1MzAx._V1_SX400_.jpg","plot":"Katniss Everdeen and Peeta Mellark become targets of the Capitol after their victory in the 74th Hunger Games sparks a rebellion in the Districts of Panem.","title":"The Hunger Games: Catching Fire","rank":4,"running_time_secs":8760,"actors":["Jennifer Lawrence","Josh Hutcherson","Liam Hemsworth"],"year":2013,"id":"tt1951264","type":"add"}
...
```

上記は、利用可能なデータの、ごく一部のコマンド例であることにご注意ください。`_bulk` オペレーションを実行するには、`sample-movies` ファイルのコンテンツ全体をコピーして貼り付ける必要があります。詳細な手順については、「[オプション 2: 複数のドキュメントをアップロードする](gsgupload-data.md#gsgmultiple-document)」を参照してください。

次のように curl コマンドを使用しても同じ結果が得られます。

```
curl -XPOST -u 'master-user:master-user-password' 'domain-endpoint/_bulk' --data-binary @bulk_movies.json -H 'Content-Type: application/json'
```

## ステップ 2: Lambda 関数を作成してデプロイする
<a name="search-example-lambda"></a>

API Gateway で API を作成する前に、リクエストを渡す Lambda 関数を作成します。

### Lambda 関数を作成する
<a name="sample-lamdba-python"></a>

このソリューションでは、API Gateway は Lambda 関数にリクエストを渡します。この関数は OpenSearch Service にクエリを送り、結果を返します。このサンプル関数は外部ライブラリを使用するため、デプロイパッケージを作成して Lambda にアップロードする必要があります。

**デプロイパッケージを作成するには**

1. コマンドプロンプトを開き、`my-opensearch-function` プロジェクトディレクトリを作成します。例えば、macOS では次のようになります。

   ```
   mkdir my-opensearch-function
   ```

1. `my-sourcecode-function` プロジェクトディレクトリに移動します。

   ```
   cd my-opensearch-function
   ```

1. 次のサンプル Python コードの内容をコピーし、`opensearch-lambda.py` という名前の新しいファイルに保存します。リージョンとホストエンドポイントをファイルに追加します。

   ```
   import boto3
   import json
   import requests
   from requests_aws4auth import AWS4Auth
   
   region = '' # For example, us-west-1
   service = 'es'
   credentials = boto3.Session().get_credentials()
   awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token)
   
   host = '' # The OpenSearch domain endpoint with https:// and without a trailing slash
   index = 'movies'
   url = host + '/' + index + '/_search'
   
   # Lambda execution starts here
   def lambda_handler(event, context):
   
       # Put the user query into the query DSL for more accurate search results.
       # Note that certain fields are boosted (^).
       query = {
           "size": 25,
           "query": {
               "multi_match": {
                   "query": event['queryStringParameters']['q'],
                   "fields": ["title^4", "plot^2", "actors", "directors"]
               }
           }
       }
   
       # Elasticsearch 6.x requires an explicit Content-Type header
       headers = { "Content-Type": "application/json" }
   
       # Make the signed HTTP request
       r = requests.get(url, auth=awsauth, headers=headers, data=json.dumps(query))
   
       # Create the response and add some extra content to support CORS
       response = {
           "statusCode": 200,
           "headers": {
               "Access-Control-Allow-Origin": '*'
           },
           "isBase64Encoded": False
       }
   
       # Add the search results to the response
       response['body'] = r.text
       return response
   ```

1. 新しい `package` ディレクトリに外部のライブラリをインストールします。

   ```
   pip3 install --target ./package boto3
   pip3 install --target ./package requests
   pip3 install --target ./package requests_aws4auth
   ```

1. ルートにインストール済みライブラリを含むデプロイパッケージを作成します。次のコマンドを使ってプロジェクトディレクトリに `my-deployment-package.zip` ファイルを生成します。

   ```
   cd package
   zip -r ../my-deployment-package.zip .
   ```

1. zip ファイルのルートに `opensearch-lambda.py` ファイルを追加します。

   ```
   cd ..
   zip my-deployment-package.zip opensearch-lambda.py
   ```

Lambda 関数とデプロイパッケージの作成の詳細については、AWS Lambda デベロッパーガイドの「[.zip ファイルアーカイブで Python Lambda 関数をデプロイする](https://docs.aws.amazon.com/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html)」と本ガイドの「[Lambda デプロイパッケージを作成する](integrations-s3-lambda.md#integrations-s3-lambda-deployment-package)」を参照してください。

Lambda コンソールを使って関数を作成するには

1. Lambda コンソール ([https://console.aws.amazon.com/lambda/home](https://console.aws.amazon.com/lambda/home )) に進みます。ナビゲーションペインで、**[Functions]** (関数) を選択します。

1. **[Create Function]** (関数を作成) を選択します。

1. 以下のフィールドを設定します。
   + 関数名: opensearch-function
   + ランタイム: Python 3.9
   + アーキテクチャ: x86\$164

   他のオプションはすべてデフォルトのままにして、**[Create function]** を選択します。

1. 関数の概要ページの**[Code source]** (コードソース) セクションで、ドロップダウンから **[Upload from]** (アップロード元) を選択し、**[.zip file]** (.zip ファイル) を選択します。`my-deployment-package.zip` 作成したファイルを見つけて、**[Save]** (保存) を選択します。

1. *ハンドラー*とは、イベントを処理する関数コード内のメソッドです。**[Runtime settings]** (ランタイム設定) の下で **[Edit]** (編集) を選択し、Lambda 関数が配置されているデプロイパッケージ内の、ファイルの名前に従ってハンドラー名を変更します。例えば、ファイルの名前が `opensearch-lambda.py` の場合、ハンドラー名を `opensearch-lambda.lambda_handler` に変更します。詳細については、「[Python の Lambda 関数ハンドラー](https://docs.aws.amazon.com/lambda/latest/dg/python-handler.html)」を参照してください。

## ステップ 3: API Gateway で API を作成する
<a name="search-example-api"></a>

API Gateway を使用してさらに制限された API を作成することで、OpenSearch `_search` API とのやり取りのプロセスを簡素化することができます。API Gateway により、Amazon Cognito 認証やリクエストスロットリングなどのセキュリティ機能を有効にすることもできます。API を作成してデプロイするには、以下のステップを実施します。

### API の作成と設定
<a name="create-api"></a>

API Gateway コンソールを使用して API を作成するには

1. API Gateway コンソール ([https://console.aws.amazon.com/apigateway/home](https://console.aws.amazon.com/apigateway/home )) に移動します。ナビゲーションペインで、**[API]** を選択します。

1. [**REST API**] (プライベートではない) を見つけ、[**構築**] を選択します。

1. 次のページの **[Create new API]** (新しい API を作成) セクションで、**[New API]** (新規 API) が選択されていることを確認します。

1. 以下のフィールドを設定します。
   + API 名: **opensearch-api**
   + 説明: **Amazon OpenSearch Service ドメイン検索用のパブリック API**
   + エンドポイントタイプ: **リージョン別**

1. **[API の作成]** を選択します。

1. [**アクション**] および [**メソッドの作成**] を選択します。

1. ドロップダウンで [**GET**] を選択し、チェックマークをクリックして確定します。

1. 以下の設定を行い、[**保存**] を選択します。


| 設定 | 値 | 
| --- | --- | 
| 統合タイプ | Lambda function | 
| Lambda プロキシ統合の使用 | はい | 
| Lambda のリージョン | us-west-1 | 
| Lambda function | opensearch-lambda | 
| デフォルトタイムアウトの使用 | はい | 

### メソッドリクエストの設定
<a name="method-request"></a>

[**メソッドリクエスト**] を選択して、以下の設定を行います。


| 設定 | 値 | 
| --- | --- | 
| Authorization | なし | 
| リクエストの検証 |  クエリ文字列パラメータ、およびヘッダーの検証   | 
| API キーが必要です | false | 

**[URL Query String Parameters]** (URL クエリ文字列パラメータ) の下で **[Add query string]** (クエリ文字列を追加) を選択し、次のパラメータを設定します。


| 設定 | 値 | 
| --- | --- | 
| 名前 | q | 
| 必須 |  はい  | 

### API のデプロイとステージの設定
<a name="deploy-api"></a>

 API Gateway コンソールでは、デプロイを作成して新規または既存のステージに関連付けることで API をデプロイできます。

1. [**アクション**] および [**API のデプロイ**] を選択します。

1. [**デプロイステージ**] では、[**新しいステージ**] を選択し、ステージ `opensearch-api-test` に名前を付けます。

1. **[デプロイ]** をクリックします。

1. ステージエディタで以下の設定を行い、[**変更の保存**] を選択します。


| 設定 | 値 | 
| --- | --- | 
| スロットリングの有効化 | はい | 
| Rate |  1,000  | 
| バースト | 500 | 

これらの設定は、エンドポイントのルート (`https://some-id.execute-api.us-west-1.amazonaws.com/search-es-api-test`) への ​`GET` リクエストという 1 つのメソッドのみを持つ API を設定します。リクエストに必要なのは、検索するクエリ文字列という 1 つのパラメータ (`q`) です。呼び出されると、メソッドは `opensearch-lambda` 関数を実行する Lambda にリクエストを渡します。詳細については、「[Amazon API Gateway での API の作成](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-create-api.html)」および「[Amazon API Gateway での REST API のデプロイ](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-deploy-api.html)」を参照してください。

## ステップ 4 (オプション): ドメインアクセスポリシーを変更する
<a name="search-example-perms"></a>

OpenSearch Service ドメインで、Lambda 関数が `movies` インデックスへの `GET` リクエストを行うことを許可する必要があります。きめ細かなアクセスコントロールが有効になっているドメインで未処理のアクセスポリシーがある場合は、そのまま使用できます。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:us-west-1:123456789012:domain/domain-name/*"
    }
  ]
}
```

------

または、所持しているドメインアクセスポリシーをよりきめ細かにすることもできます。例えば、次の最小限のポリシーは、`movies` インデックスへの `opensearch-lambda-role` (Lambda を通じて作成された) 読み取りアクセスを提供します。Lambda が自動的に作成するロールの正確な名前を取得するには、 AWS Identity and Access Management (IAM) コンソールに移動し、**ロールを選択し、**「lambda」を検索します。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/service-role/opensearch-lambda-role-1abcdefg"
      },
      "Action": "es:ESHttpGet",
      "Resource": "arn:aws:es:us-west-1:123456789012:domain/domain-name/movies/_search"
    }
  ]
}
```

------

**重要**  
きめ細かなアクセスコントロールがドメインに対して有効になっている場合は、OpenSearch Dashboards で[ロールをユーザーにマッピングする](fgac.md#fgac-mapping)必要もあります。マッピングを行わないと、アクセス許可エラーが表示されます。

### Lambda 実行ロールのアクセス許可の設定
<a name="search-example-lambda-iam"></a>

ドメインアクセスポリシーの設定に加えて、Lambda 実行ロールに OpenSearch Service ドメインにアクセスするために必要な IAM アクセス許可があることを確認する必要があります。Lambda 関数には、マネージドドメインと OpenSearch Service Serverless コレクションのどちらを使用しているかに応じて、特定のアクセス許可が必要です。

**マネージド OpenSearch Service ドメインの場合:**

以下の IAM ポリシーを Lambda 実行ロールにアタッチして、OpenSearch Service ドメインへのリクエストを許可します。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "es:ESHttpGet",
        "es:ESHttpPost"
      ],
      "Resource": "arn:aws:es:us-west-1:123456789012:domain/domain-name/*"
    }
  ]
}
```

------

**OpenSearch Service Serverless コレクションの場合:**

OpenSearch Service Serverless を使用している場合は、以下の IAM ポリシーを Lambda 実行ロールにアタッチします。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "aoss:*",
      "Resource": "arn:aws:aoss:us-west-1:123456789012:collection/collection-id"
    }
  ]
}
```

------

Lambda 実行ロールにこれらのポリシーをアタッチするには:

1. IAM コンソール ([https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)) に移動します。

1. **[ロール]** を選択し、Lambda 実行ロールを検索します (通常は `opensearch-lambda-role-xxxxxxxx` という名前です)。

1. **[アクセス許可の追加]** を選択し、次いで **[インラインポリシーを作成]** を選択します。

1. **[JSON]** タブを選択し、上記から適切なポリシーを貼り付けて、プレースホルダー値を実際のリソース ARN に置き換えます。

1. **[ポリシーの確認]** を選択し、`OpenSearchAccess` のような名前を入力して、**[ポリシーの作成]** を選択します。

**注記**  
上記の IAM アクセス許可がない場合、ドメインアクセスポリシーでリクエストが許可されている場合でも、Lambda 関数が OpenSearch Service ドメインにクエリしようとすると「アクセスが拒否されました」のエラーが発生します。

アクセスポリシーの詳細については、「[アクセスポリシーの設定](createupdatedomains.md#createdomain-configure-access-policies)」を参照してください。

## Lambda ロールをマッピングする (きめ細かなアクセスコントロールを使用している場合)
<a name="search-example-perms-fgac"></a>

きめ細かなアクセスコントロールでは、アプリケーションをテストする前に追加のステップが導入されます。HTTP 基本認証を他のすべての目的で使用する場合でも、ユーザーに Lambda ロールをマッピングする必要があります。マッピングを行わないと、アクセス許可エラーが表示されます。

1. ドメインの OpenSearch Dashboards URL に移動します。

1. メインメニューから **[Security]** (セキュリティ)、**[Roles]** (ロール) の順に選択し、Lambda ロールをマッピングするロールである `all_access` へのリンクを選択します。

1. **[マッピングされたユーザー]**、**[マッピングの管理]** を選択します。

1. **[Backend roles]** (バックエンドロール) で、Lambda ロールの Amazon リソースネーム (ARN) を追加します。ARN は `arn:aws:iam::123456789123:role/service-role/opensearch-lambda-role-1abcdefg` の形式にします。

1. **[マップ]** を選択し、ユーザーまたはロールが **[マッピングされたユーザー]** の下に表示されていることを確認します。

## ステップ 5: ウェブアプリケーションをテストする
<a name="search-example-webpage"></a>

**ウェブアプリケーションをテストするには**

1. [sample-site.zip](samples/sample-site.zip) をダウンロードして解凍し、お気に入りのテキストエディタで `scripts/search.js` を開きます。

1. API Gateway エンドポイントを指すように `apigatewayendpoint` 変数を更新し、所定のパスの最後にバックスラッシュを追加します。**[Stages]** (ステージ) と API の名前を選択することで、API ゲートウェイでエンドポイントをすばやく見つけることができます。`apigatewayendpoint` 変数は `https://some-id.execute-api.us-west-1.amazonaws.com/opensearch-api-test`/ の形式にします。

1. `index.html` を開き、*thor*、*house*、および他のいくつかの用語の検索を実行してみてください。  
![\[thor の検索例。\]](http://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/images/search-ui.png)

### CORS エラーのトラブルシューティング
<a name="search-example-cors"></a>

Lambda 関数で CORS をサポートするための応答にコンテンツが含まれていても、次のエラーが表示される場合があります。

```
Access to XMLHttpRequest at '<api-gateway-endpoint>' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present in the requested resource.
```

このような場合は、以下のことを試してみます。

1. GET リソースで [CORS を有効化](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors-console.html)します。**[Advanced] ** (アドバンスト) の下で、**[Access-Control-Allow-Credentials]** を `'true'` にセットします。

1. API ゲートウェイ (**[Actions]** (アクション)、**[Deploy API]** (API のデプロイ)) で API を再デプロイします。

1. Lambda 関数トリガーを削除して再追加します。[re-add] (再追加) を追加し、**[Add trigger]** (トリガーを追加) を選択して、関数を呼び出す HTTP エンドポイントを作成します。トリガーには、次の設定がある必要があります。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/search-example.html)

## 次の手順
<a name="search-example-next"></a>

この章は、概念を示すための出発点にすぎません。例えば、次のような変更が考えられます。
+ OpenSearch Service ドメインに独自のデータを追加します。
+ API にメソッドを追加します。
+ Lambda 関数では、検索クエリを変更するか、異なるフィールドを追加します。
+ 結果のスタイルを変更するか、`search.js` を変更してユーザーに異なるフィールドを表示します。

# チュートリアル: OpenSearch Service と OpenSearch Dashboards によるカスタマーサポートへの問い合わせを可視化する
<a name="walkthrough"></a>

この章は、次のような状況の完全なチュートリアルです。ビジネスである程度の数のカスタマーサポートコールを受けており、それらを分析したいと考えています。各問い合わせの件名は何でしょうか? 肯定的なやり取りの数はいくつでしょうか? 否定的なやり取りの数はいくつでしょうか? マネージャーはこれらの問い合わせのトランスクリプトをどのように検索または確認することができますか?

手動ワークフローでは、従業員が通話記録を聴き、各問い合わせの件名をメモし、顧客とのやり取りが肯定的であったかどうかを判断することが考えられます。

このようなプロセスには非常に大きな労力がかかります。1 回の問い合わせの平均時間が 10 分とすると、各従業員が 1 日あたり聴くことができる問い合わせの数は 48 件にすぎません。人間の先入観や偏見を除外することで、生成されるデータは非常に正確なものとなる一方で、データの*量*は最小限になります。つまり、問い合わせの件名と、顧客が満足したかどうかのブール値のみとなります。完全なトランスクリプトなど、それ以上の内容を伴う場合、非常に長い時間がかかる可能性があります。

[Amazon S3](https://aws.amazon.com/s3/)、[Amazon Transcribe](https://aws.amazon.com/transcribe/)、[Amazon Comprehend](https://aws.amazon.com/comprehend/)、および Amazon OpenSearch Service を使用することで、ごくわずかなコードで同様のプロセスを自動化し、はるかに多くのデータを得ることができます。例えば、問い合わせの完全なトランスクリプト、トランスクリプトからのキーワード、および問い合わせの全体的な「センチメント」(肯定的、否定的、中立、混在) を取得できます。次に、OpenSearch と OpenSearch Dashboards を使用して、データを検索して可視化できます。

このチュートリアルはそのとおりに使用できますが、その意図は、OpenSearch Service でインデックス化する前に、JSON ドキュメントを強化する方法に関するアイデアを生み出すことです。

**推定コスト**

一般的に、このチュートリアルのステップを実行するコストは 2 USD 未満です。このチュートリアルでは、以下のリソースを使用します。
+ 転送および保存されるデータが 100 MB 未満である S3 バケット

  詳細については、「[Amazon S3 料金表](https://aws.amazon.com/s3/pricing/)」を参照してください。
+ 1 つの `t2.medium` インスタンスを持つ OpenSearch Service ドメインと、数時間に対応する 10 GiB の EBS ストレージ

  詳細については、「[Amazon OpenSearch Service 料金表](https://aws.amazon.com/elasticsearch-service/pricing/)」を参照してください。
+ Amazon Transcribe への数回の呼び出し

  詳細については、「[Amazon Transcribe 料金表](https://aws.amazon.com/transcribe/pricing/)」を参照してください。
+ Amazon Comprehend への数回の自然言語処理の呼び出し

  詳細については、「[Amazon Comprehend 料金表](https://aws.amazon.com/comprehend/pricing/)」を参照してください。

**Topics**
+ [ステップ 1: 前提条件を設定する](#walkthrough-prereq)
+ [ステップ 2: サンプルコードをコピーする](#walkthrough-script)
+ [(オプション) ステップ 3: サンプルデータのインデックスを作成する](#walkthrough-sample-data)
+ [ステップ 4: データを分析し、可視化する](#walkthrough-analysis)
+ [ステップ 5: リソースのクリーンアップと次のステップ](#walkthrough-next-steps)

## ステップ 1: 前提条件を設定する
<a name="walkthrough-prereq"></a>

続行する前に、以下のリソースが必要です。


****  

| 前提条件 | 説明 | 
| --- | --- | 
| Amazon S3 バケット | 詳細については、Amazon Simple Storage Service コンソールユーザーガイドの[「バケットの作成」](https://docs.aws.amazon.com/AmazonS3/latest/userguide/CreatingABucket.html)を参照してください。 | 
| OpenSearch Service ドメイン | データのコピー先。詳細については、「[OpenSearch Service ドメインの作成](createupdatedomains.md#createdomains)」を参照してください。 | 

これらのリソースがない場合は、次の AWS CLI コマンドを使用して作成できます。

```
aws s3 mb s3://my-transcribe-test --region us-west-2
```

```
aws opensearch create-domain --domain-name my-transcribe-test --engine-version OpenSearch_1.0 --cluster-config  InstanceType=t2.medium.search,InstanceCount=1 --ebs-options EBSEnabled=true,VolumeType=standard,VolumeSize=10 --access-policies '{"Version": "2012-10-17",		 	 	 "Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"es:*","Resource":"arn:aws:es:us-west-2:123456789012:domain/my-transcribe-test/*"}]}' --region us-west-2
```

**注記**  
これらのコマンドでは `us-west-2` リージョンを使用しますが、Amazon Comprehend がサポートしている任意のリージョンを使用することもできます。詳細については、[AWS 全般のリファレンス](https://docs.aws.amazon.com/general/latest/gr/rande.html#comprehend_region) を参照してください。

## ステップ 2: サンプルコードをコピーする
<a name="walkthrough-script"></a>

1. 次の Python 3 サンプルコードをコピーし、`call-center.py` という新しいファイルに貼り付けます。

   ```
   import boto3
   import datetime
   import json
   import requests
   from requests_aws4auth import AWS4Auth
   import time
   import urllib.request
   
   # Variables to update
   audio_file_name = '' # For example, 000001.mp3
   bucket_name = '' # For example, my-transcribe-test
   domain = '' # For example, https://search-my-transcribe-test-12345.us-west-2.es.amazonaws.com
   index = 'support-calls'
   type = '_doc'
   region = 'us-west-2'
   
   # Upload audio file to S3.
   s3_client = boto3.client('s3')
   
   audio_file = open(audio_file_name, 'rb')
   
   print('Uploading ' + audio_file_name + '...')
   response = s3_client.put_object(
       Body=audio_file,
       Bucket=bucket_name,
       Key=audio_file_name
   )
   
   # # Build the URL to the audio file on S3.
   # # Only for the us-east-1 region.
   # mp3_uri = 'https://' + bucket_name + '.s3.amazonaws.com/' + audio_file_name
   
   # Get the necessary details and build the URL to the audio file on S3.
   # For all other regions.
   response = s3_client.get_bucket_location(
       Bucket=bucket_name
   )
   bucket_region = response['LocationConstraint']
   mp3_uri = 'https://' + bucket_name + '.s3-' + bucket_region + '.amazonaws.com/' + audio_file_name
   
   # Start transcription job.
   transcribe_client = boto3.client('transcribe')
   
   print('Starting transcription job...')
   response = transcribe_client.start_transcription_job(
       TranscriptionJobName=audio_file_name,
       LanguageCode='en-US',
       MediaFormat='mp3',
       Media={
           'MediaFileUri': mp3_uri
       },
       Settings={
           'ShowSpeakerLabels': True,
           'MaxSpeakerLabels': 2 # assumes two people on a phone call
       }
   )
   
   # Wait for the transcription job to finish.
   print('Waiting for job to complete...')
   while True:
       response = transcribe_client.get_transcription_job(TranscriptionJobName=audio_file_name)
       if response['TranscriptionJob']['TranscriptionJobStatus'] in ['COMPLETED', 'FAILED']:
           break
       else:
           print('Still waiting...')
       time.sleep(10)
   
   transcript_uri = response['TranscriptionJob']['Transcript']['TranscriptFileUri']
   
   # Open the JSON file, read it, and get the transcript.
   response = urllib.request.urlopen(transcript_uri)
   raw_json = response.read()
   loaded_json = json.loads(raw_json)
   transcript = loaded_json['results']['transcripts'][0]['transcript']
   
   # Send transcript to Comprehend for key phrases and sentiment.
   comprehend_client = boto3.client('comprehend')
   
   # If necessary, trim the transcript.
   # If the transcript is more than 5 KB, the Comprehend calls fail.
   if len(transcript) > 5000:
       trimmed_transcript = transcript[:5000]
   else:
       trimmed_transcript = transcript
   
   print('Detecting key phrases...')
   response = comprehend_client.detect_key_phrases(
       Text=trimmed_transcript,
       LanguageCode='en'
   )
   
   keywords = []
   for keyword in response['KeyPhrases']:
       keywords.append(keyword['Text'])
   
   print('Detecting sentiment...')
   response = comprehend_client.detect_sentiment(
       Text=trimmed_transcript,
       LanguageCode='en'
   )
   
   sentiment = response['Sentiment']
   
   # Build the Amazon OpenSearch Service URL.
   id = audio_file_name.strip('.mp3')
   url = domain + '/' + index + '/' + type + '/' + id
   
   # Create the JSON document.
   json_document = {'transcript': transcript, 'keywords': keywords, 'sentiment': sentiment, 'timestamp': datetime.datetime.now().isoformat()}
   
   # Provide all details necessary to sign the indexing request.
   credentials = boto3.Session().get_credentials()
   awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, 'opensearchservice', session_token=credentials.token)
   
   # Index the document.
   print('Indexing document...')
   response = requests.put(url, auth=awsauth, json=json_document, headers=headers)
   
   print(response)
   print(response.json())
   ```

1. 最初の 6 つの変数を更新します。

1. 次のコマンドを使用して必要なパッケージをインストールします。

   ```
   pip install boto3
   pip install requests
   pip install requests_aws4auth
   ```

1. `call-center.py` と同じディレクトリに MP3 を配置し、スクリプトを実行します。サンプル出力を次に示します。

   ```
   $ python call-center.py
   Uploading 000001.mp3...
   Starting transcription job...
   Waiting for job to complete...
   Still waiting...
   Still waiting...
   Still waiting...
   Still waiting...
   Still waiting...
   Still waiting...
   Still waiting...
   Detecting key phrases...
   Detecting sentiment...
   Indexing document...
   <Response [201]>
   {u'_type': u'call', u'_seq_no': 0, u'_shards': {u'successful': 1, u'failed': 0, u'total': 2}, u'_index': u'support-calls4', u'_version': 1, u'_primary_term': 1, u'result': u'created', u'_id': u'000001'}
   ```

`call-center.py` は多数のオペレーションを実行します。

1. このスクリプトは、音声ファイル (この例では MP3 ですが、Amazon Transcribe は複数の形式をサポートします) を S3 バケットにアップロードします。

1. オーディオファイルの URL を Amazon Transcribe に送信し、書き起こしジョブの完了を待機します。

   書き起こしジョブが完了するまでの時間は、オーディオファイルの長さによって異なります。数秒ではなく、数分であると想定してください。
**ヒント**  
書き起こしの品質を向上させるため、Amazon Transcribe 用の[カスタム語彙](https://docs.aws.amazon.com/transcribe/latest/dg/API_CreateVocabulary.html)を設定できます。

1. 書き起こしジョブが完了すると、スクリプトはトランスクリプトを抽出し、それを 5,000 文字に切り捨て、キーワードとセンチメントの分析のため Amazon Comprehend に送信します。

1. 最後に、スクリプトは完全なトランスクリプト、キーワード、センチメント、および現在のタイムスタンプを JSON ドキュメントに追加し、そのインデックスを OpenSearch Service に作成します。

**ヒント**  
[LibriVox](https://librivox.org/) には、テストに使用できるパブリックドメインオーディオブックがあります。

## (オプション) ステップ 3: サンプルデータのインデックスを作成する
<a name="walkthrough-sample-data"></a>

多くの通話記録が手元にない場合 (これは一般的です)、[sample-calls.zip](samples/sample-calls.zip) にサンプルドキュメントの[インデックス](indexing.md)を作成できます。これは `call-center.py` で生成されるものと同等です。

1. `bulk-helper.py` という名前のファイルを作成します：

   ```
   import boto3
   from opensearchpy import OpenSearch, RequestsHttpConnection
   import json
   from requests_aws4auth import AWS4Auth
   
   host = '' # For example, my-test-domain.us-west-2.es.amazonaws.com
   region = '' # For example, us-west-2
   service = 'es'
   
   bulk_file = open('sample-calls.bulk', 'r').read()
   
   credentials = boto3.Session().get_credentials()
   awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token)
   
   search = OpenSearch(
       hosts = [{'host': host, 'port': 443}],
       http_auth = awsauth,
       use_ssl = True,
       verify_certs = True,
       connection_class = RequestsHttpConnection
   )
   
   response = search.bulk(bulk_file)
   print(json.dumps(response, indent=2, sort_keys=True))
   ```

1. `host` および `region` の最初の 2 つの変数を更新します。

1. 次のコマンドを使用して必要なパッケージをインストールします。

   ```
   pip install opensearch-py
   ```

1. [sample-calls.zip](samples/sample-calls.zip) をダウンロードして解凍します。

1. `sample-calls.bulk` と同じディレクトリに `bulk-helper.py` を配置し、ヘルパーを実行します。サンプル出力を次に示します。

   ```
   $ python bulk-helper.py
   {
     "errors": false,
     "items": [
       {
         "index": {
           "_id": "1",
           "_index": "support-calls",
           "_primary_term": 1,
           "_seq_no": 42,
           "_shards": {
             "failed": 0,
             "successful": 1,
             "total": 2
           },
           "_type": "_doc",
           "_version": 9,
           "result": "updated",
           "status": 200
         }
       },
       ...
     ],
     "took": 27
   }
   ```

## ステップ 4: データを分析し、可視化する
<a name="walkthrough-analysis"></a>

OpenSearch Service にデータを配置したので、OpenSearch Dashboards を使用してそのデータを可視化することができます。

1. `https://search-domain.region.es.amazonaws.com/_dashboards` に移動します。

1. OpenSearch Dashboards を使用するには、インデックスパターンが必要です。Dashboards はインデックスパターンを使用して、分析を 1 つまたは複数のインデックスに絞り込みます。`call-center.py` が作成した `support-calls` インデックスと一致させるには、[**スタックの管理**]、[**インデックスパターン**] に移動し、`support*` のインデックスパターンを定義してから、[**次のステップ**] を選択します。

1. [**タイムフィルターフィールド名**] で、[**タイムスタンプ**] を選択します。

1. これで、可視化の作成を開始できます。[**可視化**] を選択し、新しい視覚化を追加します。

1. 円グラフと `support*` インデックスパターンを選択します。

1. デフォルトの可視化は基本的です。そこで、より魅力的な視覚化を作成するため、[**分割スライス**] を選択します。

   [**集約**] で、[**用語**] を選択します。[**フィールド**] で、[**sentiment.keyword**] を選択します。次に、[**変更の適用**] を選択し、[**保存**] を選択します。  
![\[Dashboards 円グラフのサンプル設定。\]](http://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/images/sentiment-pie-chart.png)

1. [**可視化**] ページに戻り、別の可視化を追加します。今回は、水平棒グラフを選択します。

1. [**シリーズの分割**] を選択します。

   [**集約**] で、[**用語**] を選択します。[**フィールド**] で、[**keywords.keyword**] を選択し、[**サイズ**] を 20 に変更します。次に、[**変更の適用**] を選択し、[**保存**] を選択します。  
![\[Dashboards 水平棒グラフのサンプル設定。\]](http://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/images/keyword-bar-chart.png)

1. [**可視化**] ページに戻り、最終的な 1 つの視覚化である垂直棒グラフを追加します。

1. [**シリーズの分割**] を選択します。[**集約**] で、[**日付ヒストグラム**] を選択します。[**フィールド**] の [**タイムスタンプ**] を選択し、[**間隔**] を [**日別**] に設定します。

1. [**メトリクス & 軸**] を選択し、[**モード**] を [**法線**] に変更します。

1. [**変更の適用**] を選択し、[**保存**] を選択します。  
![\[Dashboards 垂直棒グラフのサンプル設定。\]](http://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/images/timestamp-bar-chart-2.png)

1. これで 3 つの可視化を作成したので、Dashboards ダッシュボードに追加することができます。[**ダッシュボード**] を選択し、ダッシュボードを作成して、可視化を追加します。  
![\[ダッシュボードの可視化の例。\]](http://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/images/dashboard-2.png)

## ステップ 5: リソースのクリーンアップと次のステップ
<a name="walkthrough-next-steps"></a>

不要な料金が発生しないようにするため、S3 バケットおよび OpenSearch Service ドメインを削除します。詳細については、*Amazon Simple Storage Service ユーザーガイド*の「[バケットの削除](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-or-empty-bucket.html#delete-bucket)」およびこのガイドの「[OpenSearch Service ドメインを削除する](gsgdeleting.md)」を参照してください。

トランスクリプトは、MP3 ファイルよりもはるかに少ないディスク容量で済みます。MP3 の保持期間を短くする (例えば、通話記録の保持期間を 3 か月から 1 か月にする) ことも、数年間のトランスクリプトを保持することもでき、いずれの場合もストレージコストを低減できます。

また、 AWS Step Functions と Lambda を使用して文字起こしプロセスを自動化したり、インデックス作成前にメタデータを追加したり、正確なユースケースに合わせてより複雑な視覚化を作成したりできます。