

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 亚马逊 OpenSearch 服务教程
<a name="tutorials"></a>

本章包括几个使用 Amazon S OpenSearch ervice 的 start-to-finish教程，包括如何迁移到该服务、构建简单的搜索应用程序以及在 OpenSearch 控制面板中创建可视化。

**Topics**
+ [教程：在 Amazon OpenSearch 服务中创建和搜索文档](quick-start.md)
+ [教程：迁移到亚马逊 OpenSearch 服务](migration.md)
+ [教程：使用亚马逊 OpenSearch 服务创建搜索应用程序](search-example.md)
+ [教程：使用 OpenSearch 服务和仪表板可视化客户支持电话 OpenSearch](walkthrough.md)

# 教程：在 Amazon OpenSearch 服务中创建和搜索文档
<a name="quick-start"></a>

在本教程中，您将学习如何在亚马逊 OpenSearch 服务中创建和搜索文档。您可以以 JSON 文档的形式向索引添加数据。 OpenSearch 服务会围绕您添加的第一个文档创建索引。

本教程介绍如何发出 HTTP 请求以创建文档、自动生成文档 ID 以及如何对文档执行基本搜索和高级搜索。

**注意**  
本教程使用具有开放访问权限的域。为了获得最高级别的安全性，我们建议您将域置于虚拟私有云（VPC）内。

## 先决条件
<a name="quick-start-prereqs"></a>

本教程包含以下先决条件：
+ 你必须有一个 AWS 账户.
+ 您必须有一个有效的 OpenSearch 服务域。

## 将文档添加到索引
<a name="quick-start-create"></a>

要将文档添加到索引，您可以使用任何 HTTP 工具，例如 P [ostman](https://www.getpostman.com/)、curl 或 OpenSearch 仪表板控制台。这些示例假设您在 OpenSearch 仪表板中使用开发者控制台。如果您使用其他工具，请提供完整的 URL 和凭证（如有必要）进行相应调整。

**将文档添加到索引**

1. 导航到您的域名的 OpenSearch 控制面板网址。您可以在 OpenSearch 服务控制台的域名控制面板上找到该网址。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
   }
   ```

## 创建自动生成 IDs
<a name="quick-start-id"></a>

OpenSearch 服务可以自动为您的文件生成 ID。要生成的命令 IDs 使用 POST 请求而不是 PUT 请求，并且不需要文档 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 服务会创建该文档。

## 执行批量操作
<a name="quick-start-bulk"></a>

您可以在一个请求中使用 `POST _bulk` API 操作对一个或多个索引执行多个操作。批量操作命令采用以下形式：

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

每个操作都需要两行 JSON。首先，您需要提供操作描述或元数据。在下一行中，您需要提供数据。每个部分使用换行符（\$1n）分隔。插入的操作描述可能如下所示：

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

包含数据的下一行可能如下所示：

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

总的来说，元数据和数据表示批量操作中的单个操作。您可以在一个请求中执行许多操作，如下所示：

```
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>

现在，您的集群中已存在数据，您可以搜索这些数据。例如，您可能想要搜索所有根茎类蔬菜，或获取所有绿叶蔬菜的数量，亦或是查找每小时记录的错误数量。

**基本搜索**

基本搜索如下所示：

```
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>

有关更多信息，请参阅以下资源：
+ [亚马逊 OpenSearch 服务入门](gsg.md)
+ [在 Amazon OpenSearch 服务中为数据编制索引](indexing.md)
+ [在亚马逊 OpenSearch 服务中搜索数据](searching.md)

# 教程：迁移到亚马逊 OpenSearch 服务
<a name="migration"></a>

索引快照是从自行管理 OpenSearch 或旧版 Elasticsearch 集群迁移到亚马逊服务的常用方式。 OpenSearch 总体而言，此过程包括以下步骤：

1. 拍摄现有集群的快照，然后将快照上载到 Amazon S3 存储桶。

1. 创建 OpenSearch 服务域。

1. 向 S OpenSearch ervice 授予访问存储桶的权限，并确保您有权使用快照。

1. 在 OpenSearch 服务域上恢复快照。

此演练提供更详细的步骤和替代选项（如果适用）。

## 拍摄并上载快照
<a name="migration-take-snapshot"></a>

尽管您可以使用 rep [ository-s3](https://docs.opensearch.org/latest/opensearch/snapshot-restore/#amazon-s3) 插件将快照直接拍摄到 S3，但您必须在每个节点上安装该插件，进行调整`opensearch.yml`（或者`elasticsearch.yml`如果使用 Elasticsearch 集群），重启每个节点，添加您的 AWS 凭据，最后拍摄快照。此插件是持续使用或迁移大型集群的绝佳选择。

对于较小的集群，一次性方法是拍摄[共享文件系统快照](https://docs.opensearch.org/latest/opensearch/snapshot-restore/#shared-file-system)，然后使用将其上传 AWS CLI 到 S3。如果您已有快照，请跳至步骤 4。

****拍摄快照并将其上载到 Amazon S3****

1. 将 `path.repo` 设置添加到所有节点上的 `opensearch.yml`（或 `Elasticsearch.yml`），然后重新启动每个节点。

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

1. 注册[快照存储库](https://opensearch.org/docs/latest/opensearch/snapshot-restore/#register-repository)，这是您拍摄快照之前所必需的。存储库只是一个存储位置：共享文件系统、Amazon S3、Hadoop Distributed File System (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 的存储。它还可以通过 HTTP 基本身份验证和所有加密设置实现[精细访问控制](fgac.md)。如果您需要更高级的安全配置（例如 VPC），请使用 OpenSearch 服务控制台。

在发布命令之前，请更改域名、主用户凭证和账号。指定与 S3 存储桶相同的 AWS 区域 OpenSearch/Elasticsearch 版本以及与您的快照兼容的版本。

**重要**  
快照只能向前兼容，并且只能与一个主要版本兼容。例如，您无法从 OpenSearch 1 恢复快照。 Elasticsearch 上的 *x* 集群 7. *x 个*集群，只有一个 OpenSearch 1。 *x* 或 2。 *x* 集群。次要版本也很重要。您无法从 5.3.2 OpenSearch 服务域上自行管理的 5.3.3 集群恢复快照。我们建议选择您的快照支持的最新版本 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/roles-managingrole-editing-console.html#roles-managingrole_edit-trust-policy)的角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create.html)。创建角色时，选择 **S3**作为 **AWS 服务**。将该角色命名为 `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 仪表板中映射快照角色（如果使用精细的访问控制）
<a name="migration-snapshot-role"></a>

如果启用了[细粒度访问权限](fgac.md#fgac-mapping)，即使您将 HTTP 基本身份验证用于所有其他目的，也需要将 `manage_snapshots` 角色映射到您的 IAM 角色，以便使用快照。

**授予您的身份使用快照的权限**

1. 使用您在创建 OpenSearch 服务域时指定的主用户凭据登录控制面板。您可以在 OpenSearch 服务控制台中找到控制面板 URL。其格式为 `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. 选择 **Map**（映射）并确认在 **Mapped users**（映射的用户）下显示的角色。

## 还原快照。
<a name="migration-restore"></a>

此时，您可以通过两种方式访问您的 OpenSearch 服务域：使用主用户证书进行 HTTP 基本身份验证或使用 IAM 凭证进行 AWS 身份验证。由于快照使用没有主用户概念的 Amazon S3，因此您必须使用您的 IAM 证书在 OpenSearch 服务域中注册快照存储库。

大多数编程语言都有库来协助对请求进行签名，但更简单的方法是使用像 [Postman](https://www.postman.com/downloads/) 这样的工具，并将您的 IAM 凭证放入**授权**部分中。

![\[Postman interface showing Authorization settings for AWS API request with Signature type.\]](http://docs.aws.amazon.com/zh_cn/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 服务终端节点，[调整域](sizing-domains.md)大小以适应您的工作负载，检查索引的分片数，切换到 [IAM 主用户](fgac.md#fgac-concepts)，或者开始在控制面板中 OpenSearch 构建可视化效果。

# 教程：使用亚马逊 OpenSearch 服务创建搜索应用程序
<a name="search-example"></a>

使用 Amazon Serv OpenSearch ice 创建搜索应用程序的常用方法是使用网络表单向服务器发送用户查询。然后，您可以授权服务器 OpenSearch APIs 直接调用，并让服务器向 Serv OpenSearch ice 发送请求。但是，如果您想编写不依赖服务器的客户端代码，则应针对安全和性能风险作出补偿。不建议允许未签名的公开访问权限。 OpenSearch APIs 用户可能会访问不安全的终端节点，或者通过过于广泛的查询（或过多的查询）影响集群性能。

本章介绍一个解决方案：使用 Amazon API Gateway 将用户限制为其中的一个子集， OpenSearch APIs 并 AWS Lambda 对从 API Gateway 到 OpenSearch 服务的请求进行签名。

![\[搜索应用程序流程图。\]](http://docs.aws.amazon.com/zh_cn/opensearch-service/latest/developerguide/images/search-application-diagram.png)


**注意**  
标准 API Gateway 和 Lambda 定价适用，但不能超出本教程的限制使用量，成本应忽略不计。

## 先决条件
<a name="search-example-prereq"></a>

本教程的先决条件是 OpenSearch 服务域。如果您还没有，请按照[创建 OpenSearch 服务域](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 操作将 5000 个文档添加到 `movies` 索引：

```
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 服务并返回结果。由于此示例函数使用的是外部库，您需要创建一个部署程序包并将其上传到 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. 将 `opensearch-lambda.py` 文件添加到 zip 文件的根目录。

   ```
   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/](https://console.aws.amazon.com/lambda/home )在左侧导航窗格中，选择**函数**。

1. 选择**创建函数**。

1. 配置以下字段：
   + 函数名称：opensearch-function
   + 运行时：Python 3.9
   + 架构：x86\$164

   保留所有其他默认选项，然后选择**创建函数**。

1. 在函数摘要页面的**代码源**部分，选择从下拉列表中**上传**，然后选择 **.zip 文件**。找到您创建的 `my-deployment-package.zip` 文件，然后选择**保存**。

1. *处理程序*是函数代码中处理事件的方法。在**运行时设置**下，选择**编辑**，根据 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. 在[https://console.aws.amazon.com/apigateway/家](https://console.aws.amazon.com/apigateway/home )中导航到 API Gateway 控制台。在左侧导航窗格中，选择**APIs**。

1. 定位**REST API**（非私有），然后选择**构建**。

1. 在下一页中，找到**新建 API** 部分，确保选中**新建 API**。

1. 配置以下字段：
   + API 名称：**opensearch-api**
   + 描述：**用于搜索亚马逊 OpenSearch 服务域名的公共 API**
   + 端点类型：**区域**

1. 选择**创建 API**。

1. 选择**操作**和**创建方法**。

1. 在下拉菜单中选择**GET**，然后单击复选标记进行确认。

1. 配置以下设置，然后选择**保存**：


| 设置 | 值 | 
| --- | --- | 
| 集成类型 | Lambda 函数 | 
| 使用 Lambda 代理集成 | 是 | 
| Lambda 区域 | us-west-1 | 
| Lambda 函数 | opensearch-lambda | 
| 使用原定设置超时 | 是 | 

### 配置该方法请求
<a name="method-request"></a>

选择**方法请求**并配置以下设置：


| 设置 | 值 | 
| --- | --- | 
| Authorization | NONE | 
| 请求验证器 |  验证查询字符串参数和标头   | 
| 必需的 API 密钥 | false | 

在 **URL 查询字符串参数**下，选择**添加查询字符串**并配置以下参数：


| 设置 | 值 | 
| --- | --- | 
| Name | q | 
| 必需 |  是  | 

### 部署 API 并配置阶段
<a name="deploy-api"></a>

 借助 API Gateway 控制台，您可以创建部署并将其与新的或现有阶段相关联，从而部署 API。

1. 选择**操作**和**部署 API**。

1. 对于**部署阶段**选择**新阶段**并将阶段命名为 `opensearch-api-test`。

1. 选择**部署**。

1. 在阶段编辑器中配置以下设置，然后选择**保存更改**：


| 设置 | 值 | 
| --- | --- | 
| 启用限制 | 是 | 
| 费率 |  1000  | 
| 突增 | 500 | 

这些设置将配置一个 API，该 API 只有一个方法：一个针对终端节点根的 `GET` 请求 (`https://some-id.execute-api.us-west-1.amazonaws.com/search-es-api-test`)。该请求需要单个参数 (`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 服务域必须允许 Lambda 函数向`GET`索引发出请求。`movies`如果您的域具有已启用精细访问控制的开放访问策略，则可以将其保持原样：

------
#### [ 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 仪表板中[将角色映射到用户](fgac.md#fgac-mapping)，否则您将看到权限错误。

### 配置 Lambda 执行角色权限
<a name="search-example-lambda-iam"></a>

除了配置域访问策略外，您还必须确保 Lambda 执行角色具有访问您的 OpenSearch 服务域所必需的 IAM 权限。Lambda 函数需要特定的权限，具体取决于您使用的是托管域还是无 OpenSearch 服务集合。

**对于托管 OpenSearch 服务域：**

将以下 IAM 策略附加到您的 Lambda 执行角色以允许其向您的 OpenSearch 服务域发出请求：

------
#### [ 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 服务集合：**

如果您使用的是无服务器 OpenSearch 服务，请将以下 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. 导航到 [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/) 的 IAM 控制台。

1. 选择**角色**，并搜索 Lambda 执行角色（通常命名为 `opensearch-lambda-role-xxxxxxxx`）。

1. 选择**添加权限**，然后选择**创建内联策略**。

1. 选择 **JSON** 选项卡并粘贴上面的相应策略，将占位符值替换为实际资源 ARNs。

1. 选择**查看策略**，提供名称（例如 `OpenSearchAccess`），然后选择**创建策略**。

**注意**  
如果没有这些 IAM 权限，即使域访问策略允许请求，您的 Lambda 函数在尝试查询您的 OpenSearch 服务域时也会收到 “访问被拒绝” 错误。

有关访问策略的更多信息，请参阅 [配置访问策略](createupdatedomains.md#createdomain-configure-access-policies)。

## 映射 Lambda 角色（如果使用精细访问控制）
<a name="search-example-perms-fgac"></a>

精细访问控制将在您能测试应用程序之前引入一个额外步骤。即使您将 HTTP 基本身份验证用于所有其他目的，也需要将 Lambda 角色映射到用户，否则您将看到权限错误。

1. 导航到该域的 OpenSearch 控制面板 URL。

1. 从主菜单中，选择**安全**、**角色**，然后选择 `all_access` 链接和需要将 Lambda 角色映射到的角色。

1. 选择**映射的用户**、**管理映射**。

1. 在 **Backend roles**（后端角色）下，添加 Lambda 角色的 Amazon 资源名称（ARN）。ARN 应采用 `arn:aws:iam::123456789123:role/service-role/opensearch-lambda-role-1abcdefg` 形式。

1. 选择**映射**并确认在**映射的用户**下显示的用户或角色。

## 步骤 5：测试 Web 应用程序
<a name="search-example-webpage"></a>

**测试 Web 应用程序**

1. 下载 [sample-site.zip](samples/sample-site.zip)，解压后在常用文本编辑器中打开 `scripts/search.js`。

1. 更新 `apigatewayendpoint` 变量以指向您的 API Gateway 端点，并在给定路径末尾添加反斜线。您可以选择**阶段**，然后选择 API 的名称，即可在 API Gateway 中快速找到端点。`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/zh_cn/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 Gateway 中重新部署 API (**Action (操作)**、**Deploy API (部署 API)**)。

1. 删除并重新添加 Lambda 函数触发器。重新添加，选择**添加触发器**并创建调用函数的 HTTP 端点。该触发器必须具有以下配置：    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/opensearch-service/latest/developerguide/search-example.html)

## 后续步骤
<a name="search-example-next"></a>

本章只是一个展示概念的起始点。您可以考虑以下修改：
+ 将您自己的数据添加到 OpenSearch 服务域。
+ 将方法添加到您的 API。
+ 在 Lambda 函数中，修改搜索查询或提高不同的字段。
+ 以不同的方式呈现结果或修改 `search.js` 以向用户显示不同的字段。

# 教程：使用 OpenSearch 服务和仪表板可视化客户支持电话 OpenSearch
<a name="walkthrough"></a>

本章是对以下情况的完整演练：企业收到一些客户支持呼叫，想要对其进行分析。每个呼叫的主题是什么？ 多少是正面的？ 多少是负面的？ 经理如何搜索或查看这些呼叫的脚本？

手动工作流可能包括：员工倾听录音、记录每个呼叫的主题并确定每个客户的互动是否积极。

此类流程需要大量人力。假设每次呼叫的平均时间为 10 分钟，则每位员工每天只能接听 48 次呼叫。排除人为偏见，他们生成的数据将高度准确，但数据*量* 将达到最少：只有调用的主题和一个表示客户是否满意的布尔值。涉及任何内容 (如完整脚本) 都会占用大量时间。

使用 [Amazon S3](https://aws.amazon.com/s3/)、[Amazon T [ranscribe、Amazon Comprehend 和 A OpenSearch mazon Service，你可以用很少的代码自动执行类似的流程，最终](https://aws.amazon.com/comprehend/)获得](https://aws.amazon.com/transcribe/)更多的数据。例如，您可以获取呼叫的完整脚本、该脚本中的关键字以及呼叫的总体“情绪”(正面、负面、中性或混合)。然后，您可以使用 OpenSearch 和 OpenSearch 仪表板来搜索和可视化数据。

虽然您可以按原样使用此演练，但其目的是在将它们编入服务中的 OpenSearch 索引之前，激发有关如何丰富您的 JSON 文档的想法。

**估计成本**

通常，执行本演练中步骤的成本低于 2 美元。本演练使用以下资源：
+ 传输和存储数据少于 100 MB 的 S3 存储桶

  要了解更多信息，请参阅 [Amazon S3 定价](https://aws.amazon.com/s3/pricing/)。
+ OpenSearch 具有一个`t2.medium`实例和 10 GiB EBS 存储空间的服务域，可存放数小时

  要了解更多信息，请参阅 [Amazon OpenSearch 服务定价](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>

继续操作之前，必须具有以下资源。


****  

| 先决条件 | 说明 | 
| --- | --- | 
| 亚马逊 S3 存储桶 | 有关更多信息，请参阅 Amazon Simple Storage Service 用户指南中的[创建存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/CreatingABucket.html)。 | 
| OpenSearch 服务域 | 数据的目的地。有关更多信息，请参阅[创建 OpenSearch 服务域](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. 更新最初的六个变量。

1. 使用以下命令安装所需的程序包：

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

1. 将您的 MP3 放在与相同的目录中`call-center.py`并运行脚本。示例输出如下：

   ```
   $ 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. 该脚本会将音频文件（在本例中为，但是 Amazon Tr MP3 anscribe 支持多种格式）上传到您的 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 文档中，并在 S OpenSearch ervice 中对其进行索引。

**提示**  
[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` 更新最初的两个变量。

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>

现在，您已在 S OpenSearch ervice 中拥有一些数据，您可以使用 OpenSearch 仪表板将其可视化。

1. 导航到 `https://search-domain.region.es.amazonaws.com/_dashboards`。

1. 在使用 OpenSearch 仪表板之前，您需要一个索引模式。控制面板使用索引模式来将分析范围缩小到一个或多个索引。要匹配 `call-center.py` 创建的 `support-calls` 索引，转到**堆栈管理**、**索引模式**，并定义索引模式`support*`，然后选择**下一步**。

1. 对于 **Time Filter field name (时间筛选字段名称)**，选择 **timestamp (时间戳)**。

1. 现在，您可以开始创建可视化了。选择 **Visualize (可视化)**，然后添加新的可视化。

1. 选择饼图和 `support*` 索引模式。

1. 默认可视化是基本的，因此请选择 **Split Slices (拆分切片)** 来创建更有趣的可视化。

   对于 **Aggregation**，选择 **Terms**。对于 **Field (字段)**，请选择 **sentiment.keyword**。然后选择 **Apply changes (应用更改)** 和 **Save (保存)**。  
![\[控制面板饼图的示例配置。\]](http://docs.aws.amazon.com/zh_cn/opensearch-service/latest/developerguide/images/sentiment-pie-chart.png)

1. 返回到 **Visualize (可视化)** 页面，然后添加其他可视化。这次请选择水平条形图。

1. 选择 **Split Series (拆分序列)**。

   对于 **Aggregation**，选择 **Terms**。对于 **Field (字段)**，请选择 **keywords.keyword**，并将 **Size (大小)** 更改为 20。然后选择 **Apply Changes (应用更改)** 和 **Save (保存)**。  
![\[控制面板水平饼图的示例配置。\]](http://docs.aws.amazon.com/zh_cn/opensearch-service/latest/developerguide/images/keyword-bar-chart.png)

1. 返回到 **Visualize (可视化)** 页面并添加一个最终的可视化、一个垂直条形图。

1. 选择 **Split Series (拆分序列)**。对于 **Aggregation (聚合)**，请选择 **Date Histogram (日期直方图)**。对于 **Field (字段)**，请选择 **timestamp (时间戳)** 并将 **Interval (间隔)** 更改为 **Daily (每日)**。

1. 选择 **Metrics & Axes (指标和轴)**，并将 **Mode (模式)** 更改为 **normal (正常)**。

1. 选择 **Apply Changes (应用更改)** 和 **Save (保存)**。  
![\[控制面板垂直条形图的示例配置。\]](http://docs.aws.amazon.com/zh_cn/opensearch-service/latest/developerguide/images/timestamp-bar-chart-2.png)

1. 现在，您有三个可视化内容，可以将它们添加到控制面板。选择 **Dashboard (控制面板)**，创建一个控制面板，并添加您的可视化内容。  
![\[示例控制面板可视化。\]](http://docs.aws.amazon.com/zh_cn/opensearch-service/latest/developerguide/images/dashboard-2.png)

## 步骤 5：清除资源和后续步骤
<a name="walkthrough-next-steps"></a>

为避免不必要的费用，请删除 S3 存储桶和 OpenSearch 服务域。要了解更多信息，请参阅*亚马逊简单存储服务用户指南中的[删除存储桶](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-or-empty-bucket.html#delete-bucket)和本指南*中的[删除 OpenSearch 服务域](gsgdeleting.md)。

与 MP3 文件相比，转录需要的磁盘空间要少得多。您可以缩短 MP3 保留期限（例如，从三个月的通话录音缩短到一个月），保留多年的笔录，同时还能节省存储成本。

您还可以使用 AWS Step Functions 和 Lambda 自动执行转录过程，在索引之前添加其他元数据，或者制作更复杂的可视化效果以适合您的确切用例。