

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 Amazon OpenSearch Service 解析程式 in AWS AppSync
<a name="tutorial-elasticsearch-resolvers"></a>

**注意**  
我們現在主要支援 APPSYNC\$1JS 執行期及其文件。請考慮[在此處](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html)使用 APPSYNC\$1JS 執行期及其指南。

AWS AppSync 支援從您在自己的 AWS 帳戶中佈建的網域使用 Amazon OpenSearch Service，前提是這些網域不存在於 VPC 中。在佈建網域之後，您可以使用資料來源來連線到這些網域，此時您可以在結構描述中設定解析程式，來進行 GraphQL 操作，例如查詢、變動和訂閱。本教學課程將會逐步說明一些常見的範例。

如需詳細資訊，請參閱 [ OpenSearch 的解析程式映射範本參考](resolver-mapping-template-reference-elasticsearch.md#aws-appsync-resolver-mapping-template-reference-elasticsearch)。

## 一鍵設定
<a name="one-click-setup"></a>

若要在已設定 Amazon OpenSearch Service 的 AWS AppSync 中自動設定 GraphQL 端點，您可以使用此 AWS CloudFormation 範本：

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

 AWS CloudFormation 部署完成後，您可以直接跳至[執行 GraphQL 查詢和變動](#tutorial-elasticsearch-resolvers-perform-queries-mutations)。

## 建立新的 OpenSearch Service 網域
<a name="create-a-new-es-domain"></a>

若要開始使用本教學課程，您需要現有的 OpenSearch Service 網域。如果尚未擁有，您可以使用下列範例。請注意，建立 OpenSearch Service 網域最多可能需要 15 分鐘，然後才能繼續將其與 an 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
```

您可以在 AWS 帳戶中的美國西部 2 （奧勒岡） 區域啟動下列 AWS CloudFormation 堆疊：

 [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 Service 的資料來源
<a name="configure-data-source-for-es"></a>

建立 OpenSearch Service 網域後，導覽至 your AWS AppSync GraphQL API，然後選擇**資料來源**索引標籤。選擇**新增**，然後輸入資料來源的易記名稱，例如「oss」。然後選擇**資料來源類型的** **Amazon OpenSearch 網域**，選擇適當的區域，您應該會看到列出的 OpenSearch Service 網域。選取後，您可以建立新的角色，而 AWS AppSync 會指派適合角色的許可，也可以選擇具有下列內嵌政策的現有角色：

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

****  

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

------

您還需要為該角色設定與 AWS AppSync 的信任關係：

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

****  

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

------

此外，OpenSearch Service 網域具有自己的**存取政策**，您可以透過 Amazon OpenSearch Service 主控台進行修改。您需要新增類似下列的政策，以及 OpenSearch Service 網域的適當動作和資源。請注意，**主體**將是 AppSync 資料來源角色，如果您讓主控台建立此角色，可以在 IAM 主控台中找到。

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

****  

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

------

## 連結解析程式
<a name="connecting-a-resolver"></a>

現在資料來源已連線至 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`。

從 AWS 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
]
```

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

前述的請求映射範本，會針對所有記錄執行簡單的查詢。假設您想要根據特定的作者來進行搜尋。此外，假設您希望該位作者成為 GraphQL 查詢中所定義的引數。在 AWS 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` 欄位的查詢詞語，此欄位會做為引數，從用戶端直接傳來。您可以選擇性地預先填入資訊 (例如標準的文字內容)，或甚至使用其他[公用程式](resolver-context-reference.md#aws-appsync-resolver-mapping-template-context-reference)。

如果您正在使用此解析程式，請使用與先前範例相同的資訊，來填寫**回應映射範本**。

## 將資料新增至 OpenSearch Service
<a name="adding-data-to-es"></a>

由於 GraphQL 變動，您可能想要將資料新增至 OpenSearch Service 網域。這是一個具有搜尋和其他用途的強大機制。由於您可以使用 GraphQL 訂閱[讓資料即時](aws-appsync-real-time-data.md)，因此它可做為通知用戶端 OpenSearch Service 網域中資料更新的機制。

返回 AWS 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)
        }
    }
}
```

和之前相同，這是如何建構資料結構的一個範例。如果有不同的欄位名稱或索引，您需要適當地更新 `path` 與 `body`。此範例也示範了如何利用 `$context.arguments`，以 GraphQL 變動引數來填寫範本。

在繼續之前，請使用下列回應映射範本，這會傳回變動操作的結果或錯誤資訊做為輸出：

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

## 擷取單一文件
<a name="retrieving-a-single-document"></a>

最後，如果您想要在結構描述中使用`getPost(id:ID)`查詢來傳回個別文件，請在 AWS AppSync 主控台的結構描述編輯器中尋找此查詢，然後選擇**連接解析程式**。再次選取 OpenSearch Service 資料來源，並使用下列映射範本：

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

由於上述的 `path` 使用 `id` 引數與空的內容，因此這會傳回空的單一文件。不過，因為現在傳回的是單一項目而非清單，您需要使用下列回應映射範本：

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

## 執行查詢與變動
<a name="tutorial-elasticsearch-resolvers-perform-queries-mutations"></a>

您現在應該能夠對 OpenSearch Service 網域執行 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 Service 網域執行`searchPosts`查詢：

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

## 最佳實務
<a name="best-practices"></a>
+ OpenSearch Service 應該用於查詢資料，而不是做為您的主要資料庫。您可能想要將 OpenSearch Service 與 Amazon DynamoDB 搭配使用，如[合併 GraphQL 解析程式](tutorial-combining-graphql-resolvers.md#aws-appsync-tutorial-combining-graphql-resolvers)中所述。
+ 只有在允許 AWS AppSync 服務角色存取叢集時，才允許 存取您的網域。
+ 您可以在開發時少量使用最低成本的叢集，然後在進入正式生產時，轉移到具有高可用性 (HA) 的較大型叢集。