

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

# 在 Amazon OpenSearch Service 中匯入和管理套件
<a name="custom-packages"></a>

Amazon OpenSearch Service 可讓您上傳自訂字典檔案，例如停止單字和同義詞，並將外掛程式與您的網域建立關聯。這些外掛程式可以是預先封裝、自訂或第三方，可讓您彈性擴展網域的功能。所有這些類型檔案的一般術語都是*套件*。
+ **字典檔案**會指示 OpenSearch 忽略常見的高頻率單字，或將類似字詞視為同等字詞，例如「凍結卡士達」、「Gelato」和「冰淇淋」，以協助精簡搜尋結果。它們也可以改善[幹線](https://en.wikipedia.org/wiki/Stemming)，如日文 (kuromoji) 分析外掛程式所示。
+ **預先封裝的外掛程式**提供內建功能，例如用於個人化搜尋結果的 Amazon Personalize 外掛程式。這些外掛程式使用 `ZIP-PLUGIN`套件類型。如需詳細資訊，請參閱[依 Amazon OpenSearch Service 中引擎版本區分的外掛程式](supported-plugins.md)。
+ **自訂和第三方外掛程式**可讓您新增量身打造的功能，或與外部系統整合，為您的網域提供更多彈性。如同預先封裝的外掛程式，您可以將自訂外掛程式上傳為`ZIP-PLUGIN`套件。對於第三方外掛程式，您還必須將外掛程式授權和組態檔案匯入為單獨的套件，然後將它們全部與網域建立關聯。

  如需詳細資訊，請參閱下列主題：
  + [在 Amazon OpenSearch Service 中管理自訂外掛程式](custom-plugins.md)
  + [在 Amazon OpenSearch Service 中安裝第三方外掛程式](plugins-third-party.md)

**注意**  
您最多可以將 20 個外掛程式與單一網域建立關聯。此限制包含所有外掛程式類型 - 選用、第三方和自訂外掛程式。

**Topics**
+ [所需的許可](#custom-packages-iam)
+ [將套件上傳至 Amazon S3](#custom-packages-gs)
+ [匯入和關聯套件](#custom-packages-assoc)
+ [搭配 OpenSearch 使用套件](#custom-packages-using)
+ [更新套件](#custom-packages-updating)
+ [使用新的字典手動更新索引](#custom-packages-updating-index-analyzers)
+ [解除關聯並移除套件](#custom-packages-dissoc)
+ [在 Amazon OpenSearch Service 中管理自訂外掛程式](custom-plugins.md)
+ [在 Amazon OpenSearch Service 中安裝第三方外掛程式](plugins-third-party.md)

## 所需的許可
<a name="custom-packages-iam"></a>

沒有管理員存取權的使用者需要特定 AWS Identity and Access Management (IAM) 動作，才能管理套件：
+ `es:CreatePackage` – 建立套件
+ `es:DeletePackage` – 刪除套件
+ `es:AssociatePackage` – 將套件與網域建立關聯
+ `es:DissociatePackage` – 取消套件與網域的關聯

您也需要自訂套件所在的 Amazon S3 儲存貯體路徑或物件的許可。

授予 IAM 內的所有許可，而不是在網域存取政策中。如需詳細資訊，請參閱[Amazon OpenSearch Service 中的 Identity and Access Management](ac.md)。

## 將套件上傳至 Amazon S3
<a name="custom-packages-gs"></a>

本節說明如何上傳自訂字典套件，因為已安裝預先封裝的外掛程式套件。您必須先將其上傳至 Amazon S3 儲存貯體，才能將自訂字典與您的網域建立關聯。如需指示說明，請參閱 *Amazon Simple Storage Service 使用者指南*中的[上傳物件](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html)。不需要上傳支援的外掛程式。

如果您的字典包含敏感資訊，請在上傳時[以 S3-managed金鑰指定伺服器端加密](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingServerSideEncryption.html)。OpenSearch Service 無法存取您使用 AWS KMS 金鑰保護的 S3 中的檔案。

上傳檔案後，請記下其 S3 路徑。路徑格式為 `s3://{{amzn-s3-demo-bucket}}/{{file-path}}/{{file-name}}`。

您可以使用下列同義字檔案進行測試。另存為 `synonyms.txt`。

```
danish, croissant, pastry
ice cream, gelato, frozen custard
sneaker, tennis shoe, running shoe
basketball shoe, hightop
```

某些字典 (例如 Hunspell 字典) 會使用多個檔案並要求在檔案系統上使用自己的字典。目前，OpenSearch Service 僅支援單一檔案字典。

## 匯入和關聯套件
<a name="custom-packages-assoc"></a>

主控台是將自訂字典匯入 OpenSearch Service 的最簡單方法。當您從 Amazon S3 匯入字典時，OpenSearch Service 會儲存自己的套件複本，並使用 AES-256 搭配 OpenSearch Service 受管金鑰自動加密該複本。

選用外掛程式已預先安裝在 OpenSearch Service 中，因此您不需要自行上傳，但您需要將外掛程式與網域建立關聯。可用的外掛程式會列在 主控台的**套件**畫面上。

### 匯入套件並將其關聯至網域
<a name="associate-console"></a>

1. 在 Amazon OpenSearch Service 主控台中，選擇 **Packages** (套件)。

1. 選擇 **Import package** (匯入套件)。

1. 為套件提供描述性名稱。

1. 提供檔案的 S3 路徑，然後選擇 **Import (匯入)**。

1. 返回 **Packages (套件)** 畫面。

1. 當封裝狀態為 **Available (可用)** 時，請加以選取。

1. 選擇**與網域建立關聯**。

1. 選取網域，然後選擇**下一步**。檢閱套件，然後選擇**關聯**。

1. 在導覽窗格中，選擇您的網域，然後移至 **Packages** (套件) 索引標籤。

1. 如果套件是自訂字典，請在套件變成**可用**時記下 ID。使用 `analyzers/{{id}}` 作為[對 OpenSearch 的請求](#custom-packages-using)中的檔案路徑。

## 搭配 OpenSearch 使用套件
<a name="custom-packages-using"></a>

本節說明如何使用兩種類型的套件：自訂字典和預先封裝的外掛程式。

### 使用自訂字典
<a name="custom-dictionaries-using"></a>

將檔案與網域建立關聯後，您可以在建立權杖化程式和權杖篩選條件`user_dictionary`時`synonyms_path`，將其用於參數，例如 `stopwords_path`、 和 。確切的參數因物件而異。多個物件可支援 `synonyms_path` 和 `stopwords_path`，但 `user_dictionary` 專屬於 kuromoji 外掛程式。

對於 IK (中文) 分析外掛程式，您可以將自訂字典檔案做為自定套件上傳，並將其與一個網域相關聯，且外掛程式會自動將其掛載，不需要 `user_dictionary` 參數。如果您的檔案是同義詞檔案，請使用 `synonyms_path` 參數。

以下範例會將同義字檔案新增至新索引：

```
PUT {{my-index}}
{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "{{my_analyzer}}": {
            "type": "custom",
            "tokenizer": "standard",
            "filter": ["{{my_filter}}"]
          }
        },
        "filter": {
          "{{my_filter}}": {
            "type": "synonym",
            "synonyms_path": "analyzers/{{F111111111}}",
            "updateable": true
          }
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "{{description}}": {
        "type": "text",
        "analyzer": "standard",
        "search_analyzer": "{{my_analyzer}}"
      }
    }
  }
}
```

此請求建立使用標準分詞器和同義詞字符篩選條件索引的自訂分析器。
+ 分詞器會根據一組規則將字符分解為*字符* (通常是字詞)。最簡單的例子是空格分詞器，每次遇到一個空白字符時，便會將前面的字元分解為字符。一個更複雜的例子是標準分詞器，它會使用一組基於語法的規則跨多種語言作業。
+ 字符篩選條件會新增、修改或刪除字符。例如，同義字字符篩選條件會在同義字清單中找到單字時加入字符。停止字符篩選條件會在停止字詞清單中找到字詞時移除標記。

此請求還會將一個文字欄位 (`description`) 新增至映射，並讓 OpenSearch 使用新分析器作為其搜尋分析器。您可以看到它仍然使用標準分析器作為其索引分析器。

最後，請注意字符篩選器中的 `"updateable": true` 行。此欄位僅適用於搜尋分析器，不適用於索引分析器，如果您稍後想要自動[更新搜尋分析器](#custom-packages-updating)，此欄位就非常重要。

為了測試，我們加入了一些文件索引：

```
POST _bulk
{ "index": { "_index": "my-index", "_id": "1" } }
{ "description": "ice cream" }
{ "index": { "_index": "my-index", "_id": "2" } }
{ "description": "croissant" }
{ "index": { "_index": "my-index", "_id": "3" } }
{ "description": "tennis shoe" }
{ "index": { "_index": "my-index", "_id": "4" } }
{ "description": "hightop" }
```

然後使用同義詞來搜尋它們：

```
GET my-index/_search
{
  "query": {
    "match": {
      "description": "gelato"
    }
  }
}
```

在這種情況下，OpenSearch 會傳回以下回應：

```
{
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 0.99463606,
    "hits": [{
      "_index": "my-index",
      "_type": "_doc",
      "_id": "1",
      "_score": 0.99463606,
      "_source": {
        "description": "ice cream"
      }
    }]
  }
}
```

**提示**  
字典檔案使用與其大小呈正比的 Java 堆積空間。例如，2 GiB 的字典檔案可能會在節點上使用 2 GiB 的堆積空間。如果您使用大型檔案，請確保節點有足夠的堆積空間可容納這些檔案。[監控](managedomains-cloudwatchmetrics.md#managedomains-cloudwatchmetrics-cluster-metrics) `JVMMemoryPressure` 指標，並視需要擴展您的叢集。

### 使用預先封裝的外掛程式
<a name="optional-plugins"></a>

OpenSearch Service 可讓您將預先安裝的選用 OpenSearch 外掛程式與網域建立關聯。預先封裝的外掛程式套件與特定 OpenSearch 版本相容，而且只能與該版本的網域建立關聯。您網域的可用套件清單包含與您的網域版本相容的所有支援外掛程式。將外掛程式與網域建立關聯後，網域上的安裝程序就會開始。然後，您可以在向 OpenSearch Service 提出請求時參考和使用外掛程式。

關聯和取消關聯外掛程式需要藍/綠部署。如需詳細資訊，請參閱[通常會導致藍/綠部署的變更](managedomains-configuration-changes.md#bg)。

選用的外掛程式包括語言分析器和自訂的搜尋結果。例如，Amazon Personalize Search Ranking 外掛程式使用機器學習來為您的客戶個人化搜尋結果。如需此外掛程式的詳細資訊，請參閱[從 OpenSearch 個人化搜尋結果](https://docs.aws.amazon.com/personalize/latest/dg/personalize-opensearch.html)。如需所有支援的外掛程式清單，請參閱 [依 Amazon OpenSearch Service 中引擎版本區分的外掛程式](supported-plugins.md)。

#### Sudachi 外掛程式
<a name="sudachi"></a>

對於 [Sudachi 外掛程式](https://github.com/WorksApplications/elasticsearch-sudachi)，當您重新關聯字典檔案時，它不會立即反映在網域上。當下一個藍/綠部署在網域上執行時，字典會重新整理，作為組態變更或其他更新的一部分。或者，您可以使用更新的資料建立新的套件、使用此新套件建立新的索引、將現有索引重新索引為新索引，然後刪除舊索引。如果您偏好使用重新索引方法，請使用索引別名，以免流量中斷。

此外，Sudachi 外掛程式僅支援二進位 Sudachi 字典，您可以使用 [CreatePackage](https://docs.aws.amazon.com/opensearch-service/latest/APIReference/API_CreatePackage.html) API 操作上傳。如需有關預先建置的系統字典和編譯使用者字典程序的資訊，請參閱 [Sudachi 文件](https://github.com/WorksApplications/elasticsearch-sudachi)。

**注意**  
將二進位字典檔案上傳至 Amazon S3 時，您必須將 S3 物件的內容類型設定為 `binary/octet-stream`。使用 `application/octet-stream` 會導致套件匯入失敗。

下列範例示範如何使用系統和使用者字典搭配 Sudachi 權杖化工具。您必須將這些字典上傳為具有 類型的自訂套件，`TXT-DICTIONARY`並在其他設定中提供其套件 IDs。

```
PUT sudachi_sample
{
  "settings": {
    "index": {
      "analysis": {
        "tokenizer": {
          "sudachi_tokenizer": {
            "type": "sudachi_tokenizer",
            "additional_settings": "{\"systemDict\": \"{{<system-dictionary-package-id>}}\",\"userDict\": [\"{{<user-dictionary-package-id>}}\"]}"
        }
        },
        "analyzer": {
          "sudachi_analyzer": {
            "filter": ["my_searchfilter"],
            "tokenizer": "sudachi_tokenizer",
            "type": "custom"
          }
        },
        "filter":{
          "my_searchfilter": {
            "type": "sudachi_split",
            "mode": "search"
          }
        }
      }
    }
  }
}
```

## 更新套件
<a name="custom-packages-updating"></a>

本節僅涵蓋如何更新自訂字典套件，因為預先封裝的外掛程式套件已為您更新。將新版本的字典上傳至 Amazon S3 *並不會*自動更新 Amazon OpenSearch Service 上的套件。OpenSearch Service 會儲存自己的檔案副本，因此如果您將新版本上傳到 S3，則必須手動更新。

每個關聯網域也都會儲存*其*自己的檔案副本。為了保持搜尋行為可預測，網域會繼續使用其目前的套件版本，直到您明確更新它們為止。若要更新自訂套件，請在 中修改 檔案 Amazon S3 Control、在 OpenSearch Service 中更新套件，然後套用更新。

### 主控台
<a name="update-console"></a>

1. 在 OpenSearch Service 主控台中，選擇 **Packages** (套件)。

1. 選擇套件和 **Update** (更新)。

1. 提供檔案的新 S3 路徑，然後選擇**更新套件**。

1. 返回 **Packages (套件)** 畫面。

1. 當套件狀態變為 **Available** (可用) 時，請加以選取。然後選擇一個或多個關聯網域，選擇 **Apply update** (套用更新) 並確認。等待關聯狀態變為 **Active** (作用中)。

1. 後續步驟取決於您設定索引的方式：
   + 如果您的網域執行的是 OpenSearch 或 Elasticsearch 7.8 或更新版本，且僅使用[可更新](#custom-packages-using)欄位設定為 true 的搜尋分析器，則您不需要採取任何進一步動作。OpenSearch Service 會使用 [\_plugins/\_refresh\_search\_analyzers API](https://docs.opensearch.org/latest/im-plugin/refresh-analyzer/index/) 自動更新您的索引。
   + 如果您的網域正在執行 Elasticsearch 7.7 或更早版本、使用索引分析器，或不使用 `updateable` 欄位，請參閱 [使用新的字典手動更新索引](#custom-packages-updating-index-analyzers)。

雖然主控台是最簡單的方法，但您也可以使用 、 AWS CLI開發套件或組態 API 來更新 OpenSearch Service 套件。 SDKs 如需詳細資訊，請參閱 [AWS CLI 命令參考](https://docs.aws.amazon.com/cli/latest/reference/)和 [Amazon OpenSearch Service API 參考](https://docs.aws.amazon.com/opensearch-service/latest/APIReference/Welcome.html)。

### AWS 開發套件
<a name="update-sdk"></a>

您可以使用開發套件來自動化更新程序，而不是在主控台中手動更新套件。以下範例 Python 指令碼會將新的套件檔案上傳到 Amazon S3，在 OpenSearch Service 中更新套件，並將新套件套用到指定網域。確認更新成功後，它會對 OpenSearch 進行範例呼叫，以證明已套用新的同義詞。

您必須提供 `host`、`region`、`file_name`、`bucket_name`、`s3_key`、`package_id`、`domain_name` 和 `query` 的值。

```
from requests_aws4auth import AWS4Auth
import boto3
import requests
import time
import json
import sys

host = ''  # The OpenSearch domain endpoint with https:// and a trailing slash. For example, https://my-test-domain.us-east-1.es.amazonaws.com/
region = ''  # For example, us-east-1
file_name = ''  # The path to the file to upload
bucket_name = ''  # The name of the S3 bucket to upload to
s3_key = ''  # The name of the S3 key (file name) to upload to
package_id = ''  # The unique identifier of the OpenSearch package to update
domain_name = ''  # The domain to associate the package with
query = ''  # A test query to confirm the package has been successfully updated

service = 'es'
credentials = boto3.Session().get_credentials()
client = boto3.client('opensearch')
awsauth = AWS4Auth(credentials.access_key, credentials.secret_key,
                   region, service, session_token=credentials.token)


def upload_to_s3(file_name, bucket_name, s3_key):
    """Uploads file to S3"""
    s3 = boto3.client('s3')
    try:
        s3.upload_file(file_name, bucket_name, s3_key)
        print('Upload successful')
        return True
    except FileNotFoundError:
        sys.exit('File not found. Make sure you specified the correct file path.')


def update_package(package_id, bucket_name, s3_key):
    """Updates the package in OpenSearch Service"""
    print(package_id, bucket_name, s3_key)
    response = client.update_package(
        PackageID=package_id,
        PackageSource={
            'S3BucketName': bucket_name,
            'S3Key': s3_key
        }
    )
    print(response)


def associate_package(package_id, domain_name):
    """Associates the package to the domain"""
    response = client.associate_package(
        PackageID=package_id, DomainName=domain_name)
    print(response)
    print('Associating...')


def wait_for_update(domain_name, package_id):
    """Waits for the package to be updated"""
    response = client.list_packages_for_domain(DomainName=domain_name)
    package_details = response['DomainPackageDetailsList']
    for package in package_details:
        if package['PackageID'] == package_id:
            status = package['DomainPackageStatus']
            if status == 'ACTIVE':
                print('Association successful.')
                return
            elif status == 'ASSOCIATION_FAILED':
                sys.exit('Association failed. Please try again.')
            else:
                time.sleep(10)  # Wait 10 seconds before rechecking the status
                wait_for_update(domain_name, package_id)


def sample_search(query):
    """Makes a sample search call to OpenSearch"""
    path = '_search'
    params = {'q': query}
    url = host + path
    response = requests.get(url, params=params, auth=awsauth)
    print('Searching for ' + '"' + query + '"')
    print(response.text)
```

**注意**  
如果您在使用 執行指令碼時收到「找不到套件」錯誤 AWS CLI，可能表示 Boto3 正在使用 \~/.aws/config 中指定的區域，這不是 S3 儲存貯體所在的區域。執行 `aws configure` 並指定正確的區域，或者明確地將區域新增至用戶端：  

```
client = boto3.client('opensearch', region_name='us-east-1')
```

## 使用新的字典手動更新索引
<a name="custom-packages-updating-index-analyzers"></a>

手動索引更新僅適用於自訂字典，不適用於預先封裝的外掛程式。若要使用更新的字典，如果您符合下列任何條件，則必須手動更新索引：
+ 您的網域執行 Elasticsearch 7.7 或更早版本。
+ 您使用自訂套件作為索引分析器。
+ 您使用自訂套件作為搜索分析器，但不包含 [updateable](#custom-packages-using) (可更新) 欄位。

若要使用新套件檔案更新分析器，您有兩個選項：
+ 關閉並開啟您要更新的任何索引：

  ```
  POST {{my-index}}/_close
  POST {{my-index}}/_open
  ```
+ 對索引進行重新索引。首先，建立使用更新同義詞檔案 （或全新的檔案） 的索引。請注意，僅支援 UTF-8。

  ```
  PUT {{my-new-index}}
  {
    "settings": {
      "index": {
        "analysis": {
          "analyzer": {
            "synonym_analyzer": {
              "type": "custom",
              "tokenizer": "standard",
              "filter": ["synonym_filter"]
            }
          },
          "filter": {
            "synonym_filter": {
              "type": "synonym",
              "synonyms_path": "analyzers/{{F222222222}}"
            }
          }
        }
      }
    },
    "mappings": {
      "properties": {
        "{{description}}": {
          "type": "text",
          "analyzer": "synonym_analyzer"
        }
      }
    }
  }
  ```

  然後將舊索引[重新索引](https://docs.opensearch.org/latest/opensearch/reindex-data/)到該新索引：

  ```
  POST _reindex
  {
    "source": {
      "index": "{{my-index}}"
    },
    "dest": {
      "index": "{{my-new-index}}"
    }
  }
  ```

  如果您經常更新索引分析器，請使用[索引別名](https://docs.opensearch.org/latest/opensearch/index-alias/)來維持最新索引的一致路徑：

  ```
  POST _aliases
  {
    "actions": [
      {
        "remove": {
          "index": "{{my-index}}",
          "alias": "{{latest-index}}"
        }
      },
      {
        "add": {
          "index": "{{my-new-index}}",
          "alias": "{{latest-index}}"
        }
      }
    ]
  }
  ```

  如果您不需要舊索引，請將其刪除：

  ```
  DELETE {{my-index}}
  ```

## 解除關聯並移除套件
<a name="custom-packages-dissoc"></a>

從網域取消套件的關聯，無論是自訂字典或預先封裝的外掛程式，都表示您在建立新索引時無法再使用該套件。取消套件的關聯後，使用套件的現有索引就無法再使用它。您必須從任何索引移除套件，才能將其取消關聯，否則取消關聯會失敗。

主控台是將套件與網域解除關聯並將其從 OpenSearch Service 中移除的最簡單方法。從 OpenSearch Service 中移除套件*並不會*將其從 Amazon S3 上的原始位置中移除。

### 取消套件與網域的關聯
<a name="dissociate-console"></a>

1. 登入 Amazon OpenSearch Service 主控台，網址為 https：//[https://console.aws.amazon.com/aos/home](https://console.aws.amazon.com/aos/home)。

1. 在導覽窗格中，選擇**網域**。

1. 選擇網域，然後導覽至**套件**索引標籤。

1. 選擇套件，**Actions** (動作)，然後選擇 **Dissociate** (解除關聯)。確認您的選擇。

1. 等待套件從清單中消失。您可能需要重新整理瀏覽器。

1. 如果您想要將套件與其他網域搭配使用，請在這裡停止。若要繼續移除套件 （如果它是自訂字典），請在導覽窗格中選擇**套件**。

1. 選取套件並選擇 **Delete (刪除)**。

或者，使用 、 AWS CLI SDKs或組態 API 來取消關聯和移除套件。如需詳細資訊，請參閱 [AWS CLI 命令參考](https://docs.aws.amazon.com/cli/latest/reference/)和 [Amazon OpenSearch Service API 參考](https://docs.aws.amazon.com/opensearch-service/latest/APIReference/Welcome.html)。