教程:Amazon OpenSearch Service 解析器 - Amazon AppSync
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

教程:Amazon OpenSearch Service 解析器

注意

我们现在主要支持 APPSYNC_JS 运行时环境及其文档。请考虑使用 APPSYNC_JS 运行时环境和此处的指南。

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

有关更多信息,请参阅适用于 OpenSearch 的解析器映射模板参考

一键设置

要在配置了 Amazon OpenSearch Service 的 Amazon AppSync 中自动设置 GraphQL 终端节点,您可以使用以下 Amazon CloudFormation 模板:

Amazon CloudFormation 部署完成后,可以直接跳到运行 GraphQL 查询和变更

创建新的 OpenSearch Service 域

要开始学习本教程,您需要具有一个现有的 OpenSearch Service 域。如果您没有域,可以使用以下示例。请注意,创建 OpenSearch Service 域最多可能需要 15 分钟,然后您才能继续将其与 Amazon 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

可以在您的 Amazon 账户的 US West 2(俄勒冈州)区域中启动以下 Amazon CloudFormation 堆栈:

为 OpenSearch Service 配置数据源

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

{ "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1234234", "Effect": "Allow", "Action": [ "es:ESHttpDelete", "es:ESHttpHead", "es:ESHttpGet", "es:ESHttpPost", "es:ESHttpPut" ], "Resource": [ "arn:aws:es:REGION:ACCOUNTNUMBER:domain/democluster/*" ] } ] }

您还需要为该角色建立与 Amazon AppSync 的信任关系:

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

此外,OpenSearch Service 域具有自己的访问策略,您可以通过 Amazon OpenSearch Service 控制台修改该策略。您需要添加一个类似于下面的策略,并具有 OpenSearch Service 域的相应操作和资源。请注意,主体是 AppSync 数据源角色,如果您让控制台创建该角色,则可以在 IAM 控制台中找到该角色。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNTNUMBER:role/service-role/APPSYNC_DATASOURCE_ROLE" }, "Action": [ "es:ESHttpDelete", "es:ESHttpHead", "es:ESHttpGet", "es:ESHttpPost", "es:ESHttpPut" ], "Resource": "arn:aws:es:REGION:ACCOUNTNUMBER:domain/DOMAIN_NAME/*" } ] }

连接解析器

数据源现已连接到您的 OpenSearch Service 域,您可以使用解析器将其连接到您的 GraphQL 架构,如以下示例中所示:

schema { query: Query mutation: Mutation } 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 Service 域中,这会映射到 /post/_doc 的路径根,其中 post 是索引。从该根路径中,您可以执行单独文档搜索、使用 /id/post* 的通配符搜索或使用 /post/_search 路径的多文档搜索。例如,如果您具有另一个名为 User 的类型,您可以使用名为 user 的新索引对文档编制索引,然后使用 /user/_search 路径执行搜索。

从 Amazon AppSync 控制台的架构编辑器中,修改前面的 Posts 架构以包含 searchPosts 查询:

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

保存架构。在右侧,对于 searchPosts,选择 Attach resolver (附加解析器)。在操作菜单中,选择更新运行时,然后选择单位解析器 (仅限 VTL)。然后,选择您的 OpenSearch Service 数据源。在 request mapping template (请求映射模板) 部分下,选择 Query posts (查询文章) 的下拉列表以获取基本模板。将 path 修改为 /post/_search。它应该类似以下内容:

{ "version":"2017-02-28", "operation":"GET", "path":"/post/_search", "params":{ "headers":{}, "queryString":{}, "body":{ "from":0, "size":50 } } }

这假设前面的架构的文档已在 OpenSearch Service 中使用 post 字段编制索引。如果您以不同方式设置数据的结构,将需要相应地进行更新。

响应映射模板部分下面,如果要从 OpenSearch Service 查询中获取数据结果并将其转换为 GraphQL,则需要指定相应的 _source 筛选条件。使用以下模板:

[ #foreach($entry in $context.result.hits.hits) #if( $velocityCount > 1 ) , #end $utils.toJson($entry.get("_source")) #end ]

修改您的搜索

上述的请求映射模板针对所有记录执行一个简单查询。假设您想要按某个特定作者进行搜索。此外,假设您希望该作者是在 GraphQL 查询中定义的一个参数。在 Amazon AppSync 控制台的架构编辑器中,添加一个 allPostsByAuthor 查询:

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

现在选择附加解析器并选择 OpenSearch Service 数据源,但在响应映射模板中使用以下示例:

{ "version":"2017-02-28", "operation":"GET", "path":"/post/_search", "params":{ "headers":{}, "queryString":{}, "body":{ "from":0, "size":50, "query":{ "match" :{ "author": $util.toJson($context.arguments.author) } } } } }

请注意,body 用一个针对 author 字段的术语查询填充,它将作为一个参数从客户端进行传递。您可以选择已预填充信息(如标准文本),甚至使用其他实用程序

如果您使用此解析器,则使用上例所示的相同信息填写响应映射模板

将数据添加到 OpenSearch Service

您可能希望将数据添加到您的 OpenSearch Service 域以作为 GraphQL 变更结果。这是一个用于搜索和其他用途的强大机制。由于您可以使用 GraphQL 订阅实时获取数据,因此,它作为一种机制向客户端通知 OpenSearch Service 域中的数据更新。

返回到 Amazon AppSync 控制台中的架构页面,然后为 addPost() 变更选择附加解析器。再次选择 OpenSearch Service 数据源,并将以下响应映射模板用于 Posts 架构:

{ "version":"2017-02-28", "operation":"PUT", "path": $util.toJson("/post/_doc/$context.arguments.id"), "params":{ "headers":{}, "queryString":{}, "body":{ "id": $util.toJson($context.arguments.id), "author": $util.toJson($context.arguments.author), "ups": $util.toJson($context.arguments.ups), "downs": $util.toJson($context.arguments.downs), "url": $util.toJson($context.arguments.url), "content": $util.toJson($context.arguments.content), "title": $util.toJson($context.arguments.title) } } }

和之前一样,这是一个介绍如何设置数据的结构的示例。如果您有不同的字段名称或索引,则需要相应地更新 pathbody。此示例还显示如何使用 $context.arguments 从您的 GraphQL 变更参数填充模板。

在继续之前,使用以下响应映射模板,这会返回变更操作结果或错误信息以作为输出:

#if($context.error) $util.toJson($ctx.error) #else $util.toJson($context.result) #end

检索单个文档

最后,如果要在架构中使用 getPost(id:ID) 查询以返回单个文档,请在 Amazon AppSync 控制台的架构编辑器中找到该查询,然后选择附加解析器。再次选择 OpenSearch Service 数据源,并使用以下映射模板:

{ "version":"2017-02-28", "operation":"GET", "path": $util.toJson("post/_doc/$context.arguments.id"), "params":{ "headers":{}, "queryString":{}, "body":{} } }

由于上面的 pathid 参数用于空正文,此命令将返回单个文档。但是,您需要使用以下响应映射模板,因为现在您返回的是单个项目而不是列表:

$utils.toJson($context.result.get("_source"))

执行查询和变更

您现在应该能够对 OpenSearch Service 域执行 GraphQL 操作。导航到 Amazon 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 Service 域运行 searchPosts 查询:

query searchPosts { searchPosts { id title author content } }

最佳实操

  • 应将 OpenSearch Service 用于查询数据,而不是作为主数据库。您可能希望将 OpenSearch Service 与 Amazon DynamoDB 一起使用,如组合使用 GraphQL 解析器中所述。

  • 通过允许 Amazon AppSync 服务角色访问集群,仅授予您的域的访问权限。

  • 您可以通过最低成本的集群先开始小规模开发,然后随着您转向生产阶段,而转至具有高可用性 (HA) 的较大集群。