使用 Amazon OpenSearch Service 创建搜索应用程序 - Amazon Opensearch Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

使用 Amazon OpenSearch Service 创建搜索应用程序

使用 Amazon OpenSearch Service 创建搜索应用程序的一个常用方法是使用 Web 表单将用户查询发送到服务器。然后,您可以授权服务器直接调用 OpenSearch API 并让服务器向 OpenSearch Service 发送请求。

但是,如果您想编写不依赖服务器的客户端代码,则应针对安全和性能风险作出补偿。不建议允许对 OpenSearch API 的未签名公有访问权限。用户可能会访问不安全的终端节点,或者通过过于广泛的查询(或过多的查询)影响集群性能。

本章为您提供了一个解决方案:使用 Amazon API Gateway 将用户限制到一部分 OpenSearch API 和 Amazon Lambda,并从 API Gateway 到 OpenSearch Service 签署请求。

注意

标准 API Gateway 和 Lambda 定价适用,但不能超出本教程的限制使用量,成本应忽略不计。

先决条件

此教程的一个先决条件是 OpenSearch Service 域。如果您还没有域,请按照创建 OpenSearch Service 域中的步骤创建一个域。

步骤 1:为示例数据建立索引

下载 sample-movies.zip,解压它,然后使用 _bulk API 将 5,000 个文档添加到 movies 索引:

POST https://search-my-domain.us-west-1.es.amazonaws.com/_bulk { "index": { "_index": "movies", "_type": "movie", "_id": "tt1979320" } } {"directors":["Ron Howard"],"release_date":"2013-09-02T00:00:00Z","rating":8.3,"genres":["Action","Biography","Drama","Sport"],"image_url":"http://ia.media-imdb.com/images/M/MV5BMTQyMDE0MTY0OV5BMl5BanBnXkFtZTcwMjI2OTI0OQ@@._V1_SX400_.jpg","plot":"A re-creation of the merciless 1970s rivalry between Formula One rivals James Hunt and Niki Lauda.","title":"Rush","rank":2,"running_time_secs":7380,"actors":["Daniel Brühl","Chris Hemsworth","Olivia Wilde"],"year":2013,"id":"tt1979320","type":"add"} { "index": { "_index": "movies", "_type": "movie", "_id": "tt1951264" } } {"directors":["Francis Lawrence"],"release_date":"2013-11-11T00:00:00Z","genres":["Action","Adventure","Sci-Fi","Thriller"],"image_url":"http://ia.media-imdb.com/images/M/MV5BMTAyMjQ3OTAxMzNeQTJeQWpwZ15BbWU4MDU0NzA1MzAx._V1_SX400_.jpg","plot":"Katniss Everdeen and Peeta Mellark become targets of the Capitol after their victory in the 74th Hunger Games sparks a rebellion in the Districts of Panem.","title":"The Hunger Games: Catching Fire","rank":4,"running_time_secs":8760,"actors":["Jennifer Lawrence","Josh Hutcherson","Liam Hemsworth"],"year":2013,"id":"tt1951264","type":"add"} ...

有关说明,请参阅选项 2:上传多个文档

步骤 2:在 API Gateway 中创建 API

使用 API Gateway 创建更加受限的 API 简化了与OpenSearch _search API 交互的过程。API Gateway 还可让您启用安全功能,如 Amazon Cognito 身份验证和请求限制。执行以下步骤来创建和部署 API:

创建和配置 API

使用 API Gateway 控制台创建 API

  1. 在 API Gateway 中,选择创建 API

  2. 定位REST API(非私有),然后选择构建

  3. 配置以下字段:

    • API 名称:opensearch-api

    • 描述:用于搜索 Amazon OpenSearch Service 域的公共 API

    • 端点类型:区域

  4. 选择 Create API (创建 API)

  5. 选择操作创建方法

  6. 在下拉菜单中选择GET,然后单击复选标记进行确认。

  7. 配置以下设置,然后选择保存

设置
集成类型 Lambda 函数
使用 Lambda 代理集成
Lambda 区域 us-west-1
Lambda 函数 opensearch-lambda(稍后您将在 Lambda 中配置它)
使用原定设置超时
注意

如果按顺序执行这些步骤,则会看到一条错误:“未找到函数:arn:aws:lambda:us-west-1:123456789012:function:opensearch-lambda”。可以忽略此错误,因为将在步骤 3 中配置 Lambda 函数。

配置该方法请求

选择方法请求并配置以下设置:

设置
授权 NONE
请求验证器

验证查询字符串参数和标头

必需的 API 密钥 false

URL 查询字符串参数

设置
名称 q
必填

部署 API 并配置阶段

借助 API Gateway 控制台,您可以创建部署并将其与新的或现有阶段相关联,从而部署 API。

  1. 选择操作部署 API

  2. 对于部署阶段选择新阶段并将阶段命名为 opensearch-api-test

  3. 选择 Deploy(部署)。

  4. 在阶段编辑器中配置以下设置,然后选择保存更改

设置
启用限制
Rate

1000

突增 500

这些设置将配置一个 API,该 API 只有一个方法:一个针对终端节点根的 GET 请求 (https://some-id.execute-api.us-west-1.amazonaws.com/search-es-api-test)。该请求需要单个参数 (q) - 查询字符串要搜索的。调用后,该方法会将请求传递到将运行 opensearch-lambda 函数的 Lambda。有关更多信息,请参阅在 Amazon API Gateway 中创建 API在 Amazon API Gateway 中部署 REST API

步骤 3:创建并部署 Lambda 函数

在 API Gateway 中创建 API 后,创建将请求传递到的 Lambda 函数。

创建 Lambda 函数

在此解决方案中,API Gateway 会将请求传递到以下 Python 3.8 Lambda 函数,该函数将查询 OpenSearch Service 并返回结果:将该函数命名为 opensearch-lambda

由于此示例函数使用的是外部库,您需要创建一个部署程序包并将其上传到 Lambda,才能使代码正常运行。有关创建 Lambda 函数和部署程序包的更多信息,请参阅Amazon Lambda开发人员指南中的使用 .zip 文件归档部署 Python Lambda 函数和本指南中的 创建 Lambda 部署程序包

import boto3 import json import requests from requests_aws4auth import AWS4Auth region = '' # For example, us-west-1 service = 'es' credentials = boto3.Session().get_credentials() awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token) host = '' # The OpenSearch domain endpoint with https:// index = 'movies' url = host + '/' + index + '/_search' # Lambda execution starts here def lambda_handler(event, context): # Put the user query into the query DSL for more accurate search results. # Note that certain fields are boosted (^). query = { "size": 25, "query": { "multi_match": { "query": event['queryStringParameters']['q'], "fields": ["title^4", "plot^2", "actors", "directors"] } } } # Elasticsearch 6.x requires an explicit Content-Type header headers = { "Content-Type": "application/json" } # Make the signed HTTP request r = requests.get(url, auth=awsauth, headers=headers, data=json.dumps(query)) # Create the response and add some extra content to support CORS response = { "statusCode": 200, "headers": { "Access-Control-Allow-Origin": '*' }, "isBase64Encoded": False } # Add the search results to the response response['body'] = r.text return response

修改处理程序

处理程序是函数代码中处理事件的方法。您需要根据 Lambda 函数所在的部署包中的文件名更改处理程序名称。例如,如果您的文件名为 function.py,请将处理程序重命名为 function.lambda_handler。有关更多信息,请参阅 Python 中的 Lambda 函数处理程序中的

配置触发器

选择添加触发器并创建调用函数的 HTTP 端点。该触发器必须具有以下配置:

触发器 API 部署阶段 安全性
API Gateway opensearch-api opensearch-api-test Open(打开)

步骤 4:(可选)修改域访问策略

OpenSearch Service 域必须允许 Lambda 函数向 movies 索引发出 GET 请求。如果您的域具有已启用精细访问控制的开放访问策略,则可以将其保持原样:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "es:*", "Resource": "arn:aws:es:us-west-1:123456789012:domain/domain-name/*" } ] }

您也可以选择建立更加精细的域访问策略。例如,以下最低策略提供了对整个 movies 索引的 opensearch-lambda-role(通过 Lambda 创建)访问:要获取 Lambda 自动创建的角色的确切名称,请转到 Amazon Identity and Access Management(IAM) 控制台,请选择角色,并搜索 “lambda”。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789012:role/service-role/opensearch-lambda-role-1abcdefg" }, "Action": "es:ESHttpGet", "Resource": "arn:aws:es:us-west-1:123456789012:domain/domain-name/movies/_search" } ] }
注意

如果您为域启用了精细的访问控制,则可能还需要在 OpenSearch 控制面板中将角色映射到用户,否则就会看到权限错误。

有关访问策略的更多信息,请参阅 配置访问策略

步骤 5:测试 Web 应用程序

测试 Web 应用程序

  1. 下载 sample-site.zip,解压后在常用文本编辑器中打开 scripts/search.js

  2. 更新 apigatewayendpoint 变量以指向您的 API Gateway 端点。终端节点采用 https://some-id.execute-api.us-west-1.amazonaws.com/opensearch-api-test 的形式。您可以选择阶段,然后选择 API 的名称,即可在 API Gateway 中快速找到端点。

  3. 打开 index.html 并尝试运行对 thorhouse 和其他几个术语的搜索。

    
                        一个对 thor 的示例搜索。

排除 CORS 错误

尽管 Lambda 函数在响应中包含支持 CORS 的内容,但您仍可能会看到以下错误:

Access to XMLHttpRequest at '<api-gateway-endpoint>' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present in the requested resource.

如果,请尝试以下操作:

  1. 在 GET 资源上启用 CORS。在 Advanced (高级) 西方,设置 Access-Control-Allow-Credentials'true'

  2. 在 API Gateway 中重新部署 API (Action (操作)Deploy API (部署 API))。

  3. 删除并重新添加 Lambda 函数触发器。

后续步骤

本章只是一个展示概念的起始点。您可以考虑以下修改:

  • 将您自己的数据添加到 OpenSearch Service 域。

  • 将方法添加到您的 API。

  • 在 Lambda 函数中,修改搜索查询或提高不同的字段。

  • 以不同的方式呈现结果或修改 search.js 以向用户显示不同的字段。