

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

# 在中使用亚马逊 OpenSearch 服务解析器 AWS AppSync
<a name="tutorial-elasticsearch-resolvers-js"></a>

AWS AppSync 支持从您在自己的 AWS 账户中配置的域中使用 Amazon OpenSearch 服务，前提是这些域不存在于 VPC 中。预置域后，您可以使用数据来源连接这些域，此时，您可以在架构中配置一个解析器以执行 GraphQL 操作（如查询、变更和订阅）。本教程将引导您了解一些常见示例。

如需了解更多信息，请参阅我们的[JavaScript 解析器函数参考。 OpenSearch](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-elasticsearch-js.html)

## 创建新的 OpenSearch 服务域
<a name="create-a-new-es-domain-js"></a>

要开始使用本教程，您需要一个现有的 OpenSearch 服务域。如果您没有域，可以使用以下示例。请注意，创建 OpenSearch 服务域最多可能需要 15 分钟，然后才能继续将其与 AWS AppSync数据源集成。

```
aws cloudformation create-stack --stack-name AppSyncOpenSearch \
--template-url https://s3.us-west-2.amazonaws.com/awsappsync/resources/elasticsearch/ESResolverCFTemplate.yaml \
--parameters ParameterKey=OSDomainName,ParameterValue=ddtestdomain ParameterKey=Tier,ParameterValue=development \
--capabilities CAPABILITY_NAMED_IAM
```

您可以在自己的账户中在美国西部 2（俄勒冈）地区启动以下 AWS CloudFormation 堆栈： AWS 

 [https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/elasticsearch/ESResolverCFTemplate.yaml](https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/elasticsearch/ESResolverCFTemplate.yaml)

## 为 OpenSearch 服务配置数据源
<a name="configure-data-source-for-es-js"></a>

创建 OpenSearch 服务域后，导航到您的 AWS AppSync GraphQL API，然后选择 “**数据源**” 选项卡。选择 “**创建数据源**”，然后输入数据源的友好名称，例如 “*oss*”。然后，为**数据源类型**选择 **Amazon OpenSearch 域名**，选择相应的区域，您应该会看到您的 OpenSearch 服务域已列出。选择后，您可以创建一个新角色并 AWS AppSync 分配适合角色的权限，也可以选择具有以下内联策略的现有角色：

您还需要 AWS AppSync 为该角色与建立信任关系：

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

****  

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

------

此外， OpenSearch 服务域有自己的**访问策略**，您可以通过 Amazon S OpenSearch ervice 控制台对其进行修改。您必须添加与以下策略类似的策略，其中包含适用于 OpenSearch 服务域的相应操作和资源。请注意，**委托**人将是 AWS AppSync 数据源角色，如果您让上述控制台创建该角色，则可以在 IAM 控制台中找到该角色。

## 连接解析器
<a name="connecting-a-resolver-js"></a>

现在，数据源已连接到您的 OpenSearch 服务域，您可以使用解析器将其连接到您的 GraphQL 架构，如以下示例所示：

```
 type Query {
   getPost(id: ID!): Post
   allPosts: [Post]
 }

 type Mutation {
   addPost(id: ID!, author: String, title: String, url: String, ups: Int, downs: Int, content: String): AWSJSON
 }

type Post {
  id: ID!
  author: String
  title: String
  url: String
  ups: Int
  downs: Int
  content: String
}
```

请注意，有一个用户定义的 `Post` 类型（具有一个 `id` 字段）。在以下示例中，我们假设有一个过程（可以自动化）将此类型放入您的 OpenSearch 服务域，该过程将映射到索引`/post/_doc``post`所在位置的路径根。从该根路径中，您可以执行单独文档搜索、使用 `/id/post*` 的通配符搜索或使用 `/post/_search` 路径的多文档搜索。例如，如果您具有另一个名为 `User` 的类型，您可以使用名为 `user` 的新索引对文档编制索引，然后使用 `/user/_search` **路径**执行搜索。

在 AWS AppSync 控制台的**架构**编辑器中，修改前面的`Posts`架构以包含`searchPosts`查询：

```
type Query {
  getPost(id: ID!): Post
  allPosts: [Post]
  searchPosts: [Post]
}
```

保存架构。在**解析器**窗格中，找到 `searchPosts` 并选择**附加**。选择您的 OpenSearch 服务数据源并保存解析器。使用下面的代码片段更新解析器的代码：

```
import { util } from '@aws-appsync/utils'

/**
 * Searches for documents by using an input term
 * @param {import('@aws-appsync/utils').Context} ctx the context
 * @returns {*} the request
 */
export function request(ctx) {
	return {
		operation: 'GET',
		path: `/post/_search`,
		params: { body: { from: 0, size: 50 } },
	}
}

/**
 * Returns the fetched items
 * @param {import('@aws-appsync/utils').Context} ctx the context
 * @returns {*} the result
 */
export function response(ctx) {
	if (ctx.error) {
		util.error(ctx.error.message, ctx.error.type)
	}
	return ctx.result.hits.hits.map((hit) => hit._source)
}
```

这假设前面的架构中包含已在 S OpenSearch ervice 中为该`post`字段编制索引的文档。如果您以不同方式设置数据结构，则需要相应地进行更新。

## 修改您的搜索
<a name="modifying-your-searches-js"></a>

前面的解析器请求处理程序为所有记录执行简单的查询。假设您想要按某个特定作者进行搜索。此外，假设您希望将该作者指定为 GraphQL 查询中定义的参数。在 AWS AppSync 控制台的**架构**编辑器中，添加一个`allPostsByAuthor`查询：

```
type Query {
  getPost(id: ID!): Post
  allPosts: [Post]
  allPostsByAuthor(author: String!): [Post]
  searchPosts: [Post]
}
```

在**解析器**窗格中，找到 `allPostsByAuthor` 并选择**附加**。选择 OpenSearch 服务数据源并使用以下代码：

```
import { util } from '@aws-appsync/utils'

/**
 * Searches for documents by `author`
 * @param {import('@aws-appsync/utils').Context} ctx the context
 * @returns {*} the request
 */
export function request(ctx) {
	return {
		operation: 'GET',
		path: '/post/_search',
		params: {
			body: {
				from: 0,
				size: 50,
				query: { match: { author: ctx.args.author } },
			},
		},
	}
}

/**
 * Returns the fetched items
 * @param {import('@aws-appsync/utils').Context} ctx the context
 * @returns {*} the result
 */
export function response(ctx) {
	if (ctx.error) {
		util.error(ctx.error.message, ctx.error.type)
	}
	return ctx.result.hits.hits.map((hit) => hit._source)
}
```

请注意，`body` 用一个针对 `author` 字段的术语查询填充，它将作为一个参数从客户端进行传递。或者，您可以选择使用预填充的信息，例如标准文本。

## 向 OpenSearch 服务添加数据
<a name="adding-data-to-es-js"></a>

由于 GraphQL 突变，您可能需要向 OpenSearch 服务域中添加数据。这是一个用于搜索和其他用途的强大机制。由于您可以使用 GraphQL 订阅来[实现实时数据](aws-appsync-real-time-data.md)，因此它可以用作通知客户服务域中数据 OpenSearch 更新的机制。

返回 AWS AppSync 控制台中的 “**架构**” 页面，然后为`addPost()`突变选择**附加**。再次选择 OpenSearch 服务数据源并使用以下代码：

```
import { util } from '@aws-appsync/utils'

/**
 * Searches for documents by `author`
 * @param {import('@aws-appsync/utils').Context} ctx the context
 * @returns {*} the request
 */
export function request(ctx) {
	return {
		operation: 'PUT',
		path: `/post/_doc/${ctx.args.id}`,
		params: { body: ctx.args },
	}
}

/**
 * Returns the inserted post
 * @param {import('@aws-appsync/utils').Context} ctx the context
 * @returns {*} the result
 */
export function response(ctx) {
	if (ctx.error) {
		util.error(ctx.error.message, ctx.error.type)
	}
	return ctx.result
}
```

与之前一样，这是一个说明如何设置数据结构的示例。如果您具有不同的字段名称或索引，则需要更新 `path` 和 `body`。该示例还说明了如何在请求处理程序中使用 `context.arguments`（也可以写成 `ctx.args`）。

## 检索单个文档
<a name="retrieving-a-single-document-js"></a>

最后，如果要使用架构中的`getPost(id:ID)`查询来返回单个文档，请在 AWS AppSync 控制台的**架构**编辑器中找到此查询，然后选择 Att **ach**。再次选择 OpenSearch 服务数据源并使用以下代码：

```
import { util } from '@aws-appsync/utils'

/**
 * Searches for documents by `author`
 * @param {import('@aws-appsync/utils').Context} ctx the context
 * @returns {*} the request
 */
export function request(ctx) {
	return {
		operation: 'GET',
		path: `/post/_doc/${ctx.args.id}`,
	}
}

/**
 * Returns the post
 * @param {import('@aws-appsync/utils').Context} ctx the context
 * @returns {*} the result
 */
export function response(ctx) {
	if (ctx.error) {
		util.error(ctx.error.message, ctx.error.type)
	}
	return ctx.result._source
}
```

## 执行查询和变更
<a name="tutorial-elasticsearch-resolvers-perform-queries-mutations-js"></a>

现在，您应该能够对您的 OpenSearch 服务域执行 GraphQL 操作了。导航到 AWS AppSync 控制台的 “**查询**” 选项卡并添加一条新记录：

```
mutation AddPost {
    addPost (
        id:"12345"
        author: "Fred"
        title: "My first book"
        content: "This will be fun to write!"
        url: "publisher website",
        ups: 100,
        downs:20 
       )
}
```

您将会在右侧看到变更结果。同样，您现在可以对您的 OpenSearch 服务域运行`searchPosts`查询：

```
query search {
    searchPosts {
        id
        title
        author
        content
    }
}
```

## 最佳实践
<a name="best-practices-js"></a>
+ OpenSearch 服务应该用于查询数据，而不是作为您的主数据库。如组合 GraphQL 解 OpenSearch 析器中所述，您可能需要将服务与亚马逊 DynamoDB [结合](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-combining-graphql-resolvers-js.html)使用。
+ 仅通过允许 AWS AppSync 服务角色访问集群来授予对域的访问权限。
+ 您可以通过最低成本的集群先开始小规模开发，然后随着您转向生产阶段，而转至具有高可用性 (HA) 的较大集群。