

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

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

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

如需詳細資訊，請參閱 [ OpenSearch 的 JavaScript 解析程式函數參考](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-elasticsearch-js.html)。

## 建立新的 OpenSearch Service 網域
<a name="create-a-new-es-domain-js"></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 的 US-West-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-js"></a>

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

您還需要為該角色設定與 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 網域新增類似下列的政策，以及適當的動作和資源。請注意，**主體**將是 AWS AppSync 資料來源角色，如果您讓該主控台建立，可以在 IAM 主控台中找到該角色。

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

現在資料來源已連線至 OpenSearch Service 網域，您可以使用解析程式將其連線至 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 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`並選擇**連接**。選擇您的 OpenSearch Service 資料來源並儲存解析程式。使用以下程式碼片段更新解析程式的程式碼：

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

這會假設上述結構描述的文件已在 OpenSearch Service 的 `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 Service 資料來源，並使用下列程式碼：

```
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 Service
<a name="adding-data-to-es-js"></a>

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

返回 AWS AppSync 主控台中的**結構描述**頁面，然後選取**附加**以進行`addPost()`變動。再次選取 OpenSearch Service 資料來源，並使用下列程式碼：

```
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`。此範例也說明如何在請求處理常式中使用 `ctx.args`，`context.arguments`也可以寫入為 。

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

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

```
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 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 search {
    searchPosts {
        id
        title
        author
        content
    }
}
```

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