使用 Amazon OpenSearch Service 建立一個搜尋應用程式 - Amazon OpenSearch Service

使用 Amazon OpenSearch Service 建立一個搜尋應用程式

使用 ​Amazon OpenSearch Service 建立搜尋應用程式的常見方法是使用 web 表單將使用者查詢傳送到伺服器。接著,您可以授權伺服器直接呼叫 ​OpenSearch API 並讓伺服器將請求傳送至 OpenSearch Service。

如果您想要寫入不依賴伺服器的用戶端程式碼,您應彌補安全性和效能風險。允許對 ​OpenSearch API 的未簽署、公開存取是不明智的做法。使用者可能會透過過於廣泛的查詢 (或太多查詢) 存取不安全的端點或影響叢集效能。

本章提出一種解決方案:使用 Amazon API Gateway​ 將使用者限制到 OpenSearch​ API 和 ​AWS Lambda 的子集,以便簽署從 ​API Gateway 到 OpenSearch Service 的請求。

注意

標準 API Gateway​ 和 ​Lambda 定價適用,但在此教學課程的限制使用量之內,成本應微乎其微。

先決條件

此教學的先決條件是 OpenSearch Service​ 網域。如果沒有,請遵循建立 OpenSearch Service 網域中的步驟建立一個。

步驟 1:索引範例資料

下載 sample-movies.zip、進行解壓縮,然後使用 _bulk​ API 來將 5000 個文件新增到 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 中,選擇 Create API (建立 API)。

  2. 找到 REST API (非私有) 並選擇 Build (建置)。

  3. 設定下列欄位:

    • API 名稱:opensearch-api

    • 描述:搜尋 Amazon OpenSearch Service 網域的公有 API

    • 端點類型:區域

  4. 選擇 Create API (建立 API)。

  5. 選擇 Actions (動作) 和 Create Method (建立方法)。

  6. 在下拉式選單中選擇 GET,然後按一下核取記號以確認。

  7. 進行下列設定,然後選擇 Save (儲存):

設定 數值
整合類型 Lambda 函數
使用 Lambda 代理整合
Lambda 區域 us-west-1
Lambda 函數 opensearch-lambda (稍後您將在 Lambda 中設定它)
使用預設逾時
注意

如果您按順序執行這些步驟,您會看到一個錯誤:「找不到函數:arn:aws:lambda:us-west-1:123456789012:function:opensearch-lambda」。您可以忽略此錯誤,因為您將在步驟 3 中設定 Lambda 函數。

設定方法請求

選擇 Method Request (方法請求),然後進行下列設定:

設定 數值
Authorization NONE
請求驗證程式

驗證查詢字串參數與標頭

需要 API 金鑰 false

URL 查詢字串參數

設定 數值
名稱 q
必要

部署 API 並設定階段

API Gateway 主控台可讓您透過建立部署並將它與全新或現有階段建立關聯來部署 API。

  1. 選擇 Actions (動作) 和 Deploy API (部署 API)。

  2. 對於 Deployment stage (部署階段),選擇 New Stage (新增階段) 並將階段命名為 opensearch-api-test

  3. 選擇 Deploy (部署)。

  4. 在階段編輯器中進行下列設定,然後選擇 Save Changes (儲存變更):

設定 數值
啟用調節
速率

1000

爆量 500

這些設定會設定僅有一個方法的 API:GET 對端點根進行要求 (https://some-id.execute-api.us-west-1.amazonaws.com/search-es-api-test)。要求需要單一參數 (q),要搜尋的查詢字串。呼叫時,方法會將請求傳遞至 Lambda,它會執行 ​opensearch-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 函數和部署套件的詳細資訊,請參閱 AWS 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 函數處理常式

設定觸發

選擇 Add trigger (新增觸發) 並建立可叫用函數的 HTTP 端點。觸發必須具有以下組態:

觸發條件 API 部署階段 安全性
API Gateway opensearch-api opensearch-api-test 開啟

步驟 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 自動建立之角色的確切名稱,請移至 AWS Identity and Access Management (IAM) 主控台,選擇 Roles (角色),並搜索 "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" } ] }
注意

如果您為網域啟用了精細存取控制,則可能還需要將角色映射至使用者,否則您將看到許可錯誤。

如需存取政策的詳細資訊,請參閱設定存取政策

步驟 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 您可以透過選擇 Stages (階段),然後選取 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 (Actions (動作)、Deploy API (部署 API))。

  3. 刪除並重新新增您的 Lambda 函數觸發程序。

下一步驟

本章只是展縣概念的起點。您可以考慮以下修改:

  • 將自己的資料新增到 OpenSearch Service 網域。

  • 將方法新增至 API

  • 在 Lambda​ 函數中,修改搜尋查詢或提升不同的欄位。

  • 樣式結果不同或修改 search.js​ 來向使用者顯示不同的欄位。