

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

# 在 Amazon OpenSearch 服务中导入和管理包裹
<a name="custom-packages"></a>

Amazon Ser OpenSearch vice 允许您上传自定义词典文件，例如停用词和同义词，并将插件与您的域名相关联。这些插件可为预打包、自定义或第三方插件，使您能够灵活扩展域的功能。所有这些类型文件的通用术语是*程序包*。
+ **字典文件**指示忽略常见的高频单词或 OpenSearch 将类似的术语（例如 “冷冻蛋奶冻”、“冰淇淋” 和 “冰淇淋”）视为等效词，从而帮助优化搜索结果。字典文件也可以改进[词干提取](https://en.wikipedia.org/wiki/Stemming)，如日语（kuromoji）分析插件所示。
+ **预打包插件**提供内置功能，例如用于个性化搜索结果的 Amazon Personalize 插件。这些插件使用 `ZIP-PLUGIN` 程序包类型。有关更多信息，请参阅 [Amazon OpenSearch 服务中按引擎版本划分的插件](supported-plugins.md)。
+ **自定义插件和第三方插件**允许您添加定制功能或与外部系统集成，从而为域提供更大的灵活性。与预打包插件类似，您可以将自定义插件作为 `ZIP-PLUGIN` 程序包上传。对于第三方插件，您还必须将插件许可证和配置文件作为单独的软件包导入，然后将其全部与域关联。

  有关更多信息，请参阅以下主题：
  + [在 Amazon OpenSearch 服务中管理自定义插件](custom-plugins.md)
  + [在 Amazon OpenSearch 服务中安装第三方插件](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 服务中管理自定义插件](custom-plugins.md)
+ [在 Amazon OpenSearch 服务中安装第三方插件](plugins-third-party.md)

## 所需的权限
<a name="custom-packages-iam"></a>

没有管理员访问权限的用户需要执行某些 Amazon Identity and Access Management (IAM) 操作才能管理软件包：
+ `es:CreatePackage`：创建程序包
+ `es:DeletePackage`：删除程序包
+ `es:AssociatePackage`：将程序包与域关联
+ `es:DissociatePackage`：将程序包与域取消关联

您还需要对自定义程序包所在的 Amazon S3 存储桶路径或对象的权限。

授予 IAM 中的所有权限，而不是域访问策略中的权限。有关更多信息，请参阅 [亚马逊 OpenSearch 服务中的身份和访问管理](ac.md)。

## 将程序包上传到 Amazon S3
<a name="custom-packages-gs"></a>

本节介绍如何上传自定义词典程序包，因为预打包的插件程序包已安装完毕。在您将自定义字典与域关联之前，您必须将其上传到 Amazon S3 存储桶。有关说明，请参阅 *Amazon Simple Storage Service 用户指南*中的[上传对象](https://docs.amazonaws.cn/AmazonS3/latest/userguide/upload-objects.html)。受支持的插件无需上传。

如果您的字典包含敏感信息，请在上传时[使用 S3 托管密钥指定服务器端加密](https://docs.amazonaws.cn/AmazonS3/latest/userguide/UsingServerSideEncryption.html)。 OpenSearch 服务无法访问您使用 Amazon 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 字典）使用多个文件，并且在文件系统上需要自己的目录。目前，S OpenSearch ervice 仅支持单文件字典。

## 导入和关联程序包
<a name="custom-packages-assoc"></a>

控制台是将自定义词典导入 S OpenSearch ervice 的最简单方法。当您从 Amazon S3 导入字典时， OpenSearch 服务会存储自己的包副本，并使用 OpenSearch 服务托管密钥使用 AES-256 自动加密该副本。

可选插件已预先安装在 S OpenSearch ervice 中，因此您无需自己上传它们，但需要将插件与域关联起来。控制台中的**程序包**屏幕上列出了可用的插件。

### 导入程序包并将其与域关联（控制台）
<a name="associate-console"></a>

1. 在亚马逊 OpenSearch 服务控制台中，选择**套餐**。

1. 选择 **Import package（导入软件包）**。

1. 为程序包提供描述性名称。

1. 提供文件的 S3 路径，然后选择**导入**。

1. 返回到 **Packages (程序包)** 屏幕。

1. 当程序包状态为**可用**时，请选择。

1. 选择**关联到域**。

1. 选择一个域，然后选择**下一步**。查看程序包，并选择**关联**。

1. 在导航窗格中，选择您的域，然后选择**程序包**选项卡。

1. 如果程序包是自定义字典，当程序包**可用**时记下 ID。在对的[请求中`analyzers/id`用作文件路径 OpenSearch](#custom-packages-using)。

## 将包与一起使用 OpenSearch
<a name="custom-packages-using"></a>

本节介绍如何使用这两种类型的程序包：自定义字典和预打包插件。

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

将文件与域关联后，您可以在创建标记器和标记筛选条件时，在 `synonyms_path`、`stopwords_path` 和 `user_dictionary` 等参数中使用该文件。确切的参数因对象而异。多个对象支持 `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 服务允许您将预安装的可选 OpenSearch 插件关联到您的域中。预先打包的插件包与特定 OpenSearch 版本兼容，并且只能与具有该版本的域名相关联。适用于您域的可用程序包列表包括与您的域版本兼容的所有受支持插件。将插件与域关联后，该域上的安装流程就开始了。然后，当你向 S OpenSearch ervice 发出请求时，你可以引用和使用该插件。

关联和解除关联插件需要部署。 blue/green 有关更多信息，请参阅 [通常会导致 blue/green 部署的更改](managedomains-configuration-changes.md#bg)。

可选插件包括语言分析器和自定义搜索结果。例如，Amazon Personalize 搜索排名插件使用机器学习，为您的客户进行搜索结果的个性化设置。有关此插件的更多信息，请参阅对[搜索结果进行个性化设置](https://docs.amazonaws.cn/personalize/latest/dg/personalize-opensearch.html)。 OpenSearch有关受支持插件的完整列表，请参阅 [Amazon OpenSearch 服务中按引擎版本划分的插件](supported-plugins.md)。

#### Sudachi 插件
<a name="sudachi"></a>

对于 [Sudachi 插件](https://github.com/WorksApplications/elasticsearch-sudachi)，当您重新关联字典文件时，它不会立即反映在域上。当下一次 blue/green 部署作为配置更改或其他更新的一部分在域上运行时，字典会刷新。您也可以使用更新后的数据创建新的程序包，使用此新程序包创建新索引，利用现有索引重新创建新索引，然后删除旧索引。如果您更喜欢使用重新编制索引的方法，请使用索引别名，这样您的流量就不会受到干扰。

此外，Sudachi 插件仅支持二进制 Sudachi 字典，您可以通过 API 操作上传这些字典。[CreatePackage](https://docs.amazonaws.cn/opensearch-service/latest/APIReference/API_CreatePackage.html)有关预先构建的系统字典和编译用户字典流程的信息，请参阅 [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 *不会*自动更新亚马逊 OpenSearch 服务上的压缩包。 OpenSearch 服务会存储自己的文件副本，因此，如果您将新版本上传到 S3，则必须手动对其进行更新。

您的每个关联域也存储*其*自己的文件副本。为了保持搜索行为的可预测性，域将继续使用其当前的软件包版本，直到您明确更新它们。要更新自定义软件包，请在中修改文件 Amazon S3 Control，在 S OpenSearch ervice 中更新软件包，然后应用更新。

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

1. 在 OpenSearch 服务控制台中，选择**软件包**。

1. 选择一个软件包，然后选择**更新**。

1. 提供文件的新 S3 路径，然后选择**更新程序包**。

1. 返回到 **Packages (程序包)** 屏幕。

1. 当程序包状态为**可用**时，将其选中。然后选择一个或多个关联域，**应用更新**，并确认。等待关联状态更改为**处于活动状态**。

1. 以下步骤因您配置索引的方式而异：
   + 如果您的域名正在运行 OpenSearch 或 Elasticsearch 7.8 或更高版本，并且仅使用[可更新](#custom-packages-using)字段设置为 true 的搜索分析器，则无需采取任何进一步的操作。 OpenSearch 服务使用 [\$1plugins/\$1refresh\$1search\$1](https://docs.opensearch.org/latest/im-plugin/refresh-analyzer/index/) analyzers API 自动更新您的索引。
   + 如果域运行的是 Elasticsearch 7.7 或更低版本，使用索引分析器，或者不使用 `updateable` 字段，请参阅[使用新词典手动更新索引](#custom-packages-updating-index-analyzers)。

尽管控制台是最简单的方法，但您也可以使用 Amazon CLI SDKs、或配置 API 来更新 OpenSearch 服务包。有关更多信息，请参阅[Amazon CLI 命令参考](https://docs.amazonaws.cn/cli/latest/reference/)和[亚马逊 OpenSearch 服务 API 参考](https://docs.amazonaws.cn/opensearch-service/latest/APIReference/Welcome.html)。

### Amazon SDK
<a name="update-sdk"></a>

无需在控制台中手动更新软件包，而是可以使用自动更新过程。 SDKs 以下示例 Python 脚本将新的包文件上传到 Amazon S3，更新 OpenSearch 服务中的软件包，并将新包应用于指定的域。确认更新成功后，它会进行示例调用，以 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)
```

**注意**  
如果您在使用运行脚本时收到 “找不到软件包” 错误 Amazon CLI，则可能意味着 Boto3 正在使用 \$1/.aws/config 中指定的任何区域，这不是您的 S3 存储桶所在的区域。或者运行 `aws configure` 并指定正确的区域，或者将区域显式添加到客户端：  

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

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

手动索引更新仅适用于自定义词典，不适用于预打包插件。要使用更新的字典，如果满足以下任何条件，则必须手动更新索引：
+ 您的域名运行弹性搜索 7.7 或更早版本。
+ 您可以使用自定义软件包作为索引分析器。
+ 您可以使用自定义软件包作为搜索分析器，但不包括[可更新](#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 服务中移除包裹并*不会*将其从 Amazon S3 上的原始位置移除。

### 将程序包与域取消关联
<a name="dissociate-console"></a>

1. 在[https://console.aws.amazon.com/aos/家](https://console.amazonaws.cn/aos/home)中登录亚马逊 OpenSearch 服务控制台。

1. 在导航窗格中，选择**域**。

1. 选择域，然后导航至**程序包**选项卡。

1. 选择程序包、**操作**，然后选择 **取消关联**。确认您的选择。

1. 等待程序包从列表中消失。您可能需要刷新浏览器。

1. 如果要将程序包与其他域一起使用，请在此处停止。要继续删除程序包（如果是自定义字典），请在导航窗格中选择**程序包**。

1. 选择程序包，然后选择**删除**。

或者，也可以使用 Amazon CLI SDKs、或配置 API 来解除关联和移除软件包。有关更多信息，请参阅[Amazon CLI 命令参考](https://docs.amazonaws.cn/cli/latest/reference/)和[亚马逊 OpenSearch 服务 API 参考](https://docs.amazonaws.cn/opensearch-service/latest/APIReference/Welcome.html)。