Amazon Aurora PostgreSQLAmazon 定 Location Service 的使用者定義函數 - Amazon Location Service

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

Amazon Aurora PostgreSQLAmazon 定 Location Service 的使用者定義函數

您可以使用 Amazon 定 Location Service 來處理儲存在資料庫表格中的座標和地址,以清理和豐富您的地理空間資料。

例如:

  • 您可以使用地理編碼將位址轉換為座標,以標準化和填補儲存在資料庫表格中位址的資料間隙。

  • 您可以對位址進行地理編碼以取得其位置,並將座標與資料庫空間函數搭配使用,例如顯示指定區域中資料列的函數。

  • 您可以使用豐富的資料來產生自動報告,例如產生說明特定區域中所有裝置的自動報告,或是機器學習的自動報告,以說明傳送位置更新時失敗率較高的區域。

本教學說明如何使用 Amazon 定 Location Service 來格式化和豐富Amazon Aurora PostgreSQL資料庫表格中存放的地址。

  • Amazon Aurora PostgreSQL— 完全受控的關聯式資料庫引擎,與 MySQL 和 PostgreSQL 相容,可輸出高達 MySQL 輸送量的五倍,輸出高達 PostgreSQL 輸送量的三倍,而無需變更大部分現有應用程式。如需詳細資訊,請參閱什麼是 Amazon Aurora?Amazon Aurora 用戶指南

重要

本教學課程中產生的應用程式會使用儲存地理編碼結果的 place 索引。如需儲存地理編碼結果適用費用的詳細資訊,請參閱 Amazon 定 Location Service 定價

範例程式碼可在上的 Amazon 定 Location Service 範例儲存庫中取得 GitHub,其中包含AWS CloudFormation範本。

概要

該架構涉及以下集成:

  • 此解決方案使用 Amazon 位置索引資源來支援使用該操作SearchPlaceIndexForText的地理編碼查詢。

  • AWS Lambda使用 Python Lambda,當 IAM 政策授予允許AWS Lambda呼叫 Amazon 位置地理編碼操作的權限時,對地址進行地理編碼。SearchPlaceIndexForText

  • 授與使用 SQL 使Amazon Aurora PostgreSQL用者定義函數叫用地理編碼 Lambda 函數的權限。

必要條件

開始之前,您需要下列先決條件:

  • Amazon Aurora PostgreSQL叢集。如需有關建立 Amazon Aurora 資料庫叢集的詳細資訊,請參閱 Amazon Aurora 使用者指南

    注意

    如果您的 Amazon Aurora 叢集無法公開使用,您還必須將 Amazon Aurora 設定為AWS Lambda在AWS帳戶中的虛擬私有雲端 (VPC) 中連線到。如需詳細資訊,請參閱 授予Amazon Aurora PostgreSQL存取權 AWS Lambda

  • 用於連接到Amazon Aurora PostgreSQL叢集的 SQL 開發人員工具。

快速入門

除了執行本教學中的步驟之外,您還可以啟動快速堆疊以部署支援 Amazon Location 操作的AWS Lambda函數SearchPlaceIndexForText。這會自動設定您的AWS帳戶以允許 Amazon Aurora 撥打電話。AWS Lambda

設定AWS帳戶後,您將需要:

建立位置索引資源

首先創建地點索引資源以支持地理編碼查詢。

  1. https://console.aws.amazon.com/location/ 打開 Amazon 定 Location Service 控制台。

  2. 在左側導覽窗格中,選擇 [置入索引]。

  3. 填寫下列方塊:

    • 名稱 — 輸入位置索引資源的名稱。例如,AuroraPlaceIndex. 最多可輸入 100 個字元 有效的項目包括英數字元、連字號、句號和底線。

    • 說明 — 輸入選擇性說明。例如,Amazon Aurora 的地方索引

  4. 在「資料提供者」下,選擇可用的資料提供者,以與您的 place 索引資源搭配使用。如果您沒有偏好,我們建議您從 Esri 開始。

  5. 資料儲存選項下,指定是,將儲存結果。這表示您要將地理編碼結果儲存在資料庫中。

  6. (選用) 在 Tags (標籤) 底下,輸入標籤 Key (金鑰)Value (值)。這將添加一個標籤您的新位置索引資源。如需詳細資訊,請參閱標記您的資源

  7. 選擇 [建立地點索引]。

建立用於地理AWS Lambda編碼的函數

若要建立Amazon Aurora PostgreSQL和 Amazon Location Service 之間的連線,您需要一個AWS Lambda函數來處理來自資料庫引擎的請求。此函數會轉譯 Lambda 使用者定義函數事件,並呼叫 Amazon 位置作業SearchPlaceIndexForText

您可以使用AWS Lambda主控台AWS Command Line Interface、或 AWS Lambda API 建立函數。

若要使用主控台建立 Lambda 使用者定義函數

  1. 前往 https://console.aws.amazon.com/lambda/ 開啟 AWS Lambda 主控台。

  2. 在左側導覽中,選擇 [功能]。

  3. 選擇「建立函數」,並確定已選取「從頭開始作者」。

  4. 填寫下列方塊:

    • 函數名稱 — 輸入函數的唯一名稱。有效的項目包括英數字元、連字號和底線 (不含空格)。例如,AuroraGeocoder.

    • 執行階段 — 選擇 Python 3.8

  5. 選擇 建立函式

  6. 選擇 [程式碼] 索引標籤以開啟編輯器。

  7. 使用下列項目覆寫中lambda_function.py的預留位置程式碼:

    from os import environ import boto3 from botocore.config import Config # load the place index name from the environment, falling back to a default PLACE_INDEX_NAME = environ.get("PLACE_INDEX_NAME", "AuroraPlaceIndex") location = boto3.client("location", config=Config(user_agent="Amazon Aurora PostgreSQL")) """ This Lambda function receives a payload from Amazon Aurora and translates it to an Amazon Location `SearchPlaceIndex` call and returns the results as-is, to be post-processed by a PL/pgSQL function. """ def lambda_handler(event, context): kwargs = {} if event.get("biasPosition") is not None: kwargs["BiasPosition"] = event["biasPosition"] if event.get("filterBBox") is not None: kwargs["FilterBBox"] = event["filterBBox"] if event.get("filterCountries") is not None: kwargs["FilterCountries"] = event["filterCountries"] if event.get("maxResults") is not None: kwargs["MaxResults"] = event["maxResults"] return location.search_place_index_for_text( IndexName=PLACE_INDEX_NAME, Text=event["text"], **kwargs)["Results"]
  8. 如果您將 place index 命名為其他名稱 AuroraPlaceIndex,請創建一個名為的環境變量,PLACE_INDEX_NAME將資源名稱分配給:

    • 組態索引標籤中,選擇環境變數

    • 選擇編輯,然後選擇新增環境變數

    • 對於:輸入PLACE_INDEX_NAME

    • 對於:輸入位置索引資源的名稱。

  9. 選擇部署以儲存更新的功能。

  10. 從「測試」下拉式功能表中選擇「設定測試事件」。

  11. 選擇 建立新測試事件

  12. 輸入下列測試事件:

    { "text": "Baker Beach", "biasPosition": [-122.483, 37.790], "filterCountries": ["USA"] }
  13. 選擇「測試」以測試 Lambda 函數。

  14. 選擇 Configuration (組態) 索引標籤。

  15. 在 [一般設定] 下:選擇 [權限]

  16. 執行角色下:選擇超連結的角色名稱,以將 Amazon Location Service 許可授與您的 Lambda 函數。

  17. 在「權限」標籤下:選取「新增權限」下拉式清單,然後選擇「建立內嵌原則」。

  18. 選擇 JSON 標籤。

  19. 新增下列 IAM 政策:

    • 下列原則授予傳送SearchPlaceIndexForText至 place 索引資源的權限AuroraPlaceIndex

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "geo:SearchPlaceIndexForText", "Resource": "arn:aws:geo:<Region>:<AccountId>:place-index/AuroraPlaceIndex" } ] }
  20. 選擇檢閱政策

  21. 輸入政策名稱。例如,AuroraPlaceIndexReadOnly.

  22. 選擇建立政策

授予Amazon Aurora PostgreSQL存取權 AWS Lambda

在Amazon Aurora PostgreSQL可以調用AWS Lambda函數之前,您必須授予訪問權限。

如果您的Amazon Aurora PostgreSQL叢集無法公開存取,您必須先建立 VPC 端點,以便 AWS Lambda Amazon Aurora 呼叫您的 Lambda 函數。

為以下項目建立 VPC 端點 AWS Lambda

注意

只有當您的Amazon Aurora PostgreSQL叢集無法公開存取時,才需要執行此步驟。

  1. 開啟 Amazon Virtual Private Cloud Console

  2. 在左側導覽中,選擇「端點」。

  3. 選擇 建立端點

  4. 在「服務名稱」篩選器中,輸入「lambda」,然後選擇com.amazonaws.<region>.lambda

  5. 選擇包含您的 Aurora 叢集的 VPC。

  6. 為每個可用區域選擇一個子網路。

  7. 安全群組篩選器中,輸入「default」或 Aurora 叢集所屬安全群組的名稱,然後選擇安全性群組。

  8. 選擇 建立端點

建立 IAM 政策以授予叫用AWS Lambda函數的權限

  1. 開啟 IAM 主控台

  2. 在左側導覽中,展開 [存取管理] 以選擇 [原則]。

  3. 選擇建立政策

  4. JSON 索引標籤上,輸入下列原則:

    • 以下是授與叫用AuroraGeocoderAWS Lambda函數之Amazon Aurora PostgreSQL權限的 IAM 政策範例。

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": [ "arn:aws:lambda:<Region>:<AccountId>:function:AuroraGeocoder" ] } ] }
  5. 選擇下一步:標籤以新增選擇性標籤。

  6. 選擇 下一步:檢閱

  7. 檢閱您的保單,並輸入保單的下列詳細資料:

    • 名稱 — 使用字母數字和 '+=, .@-_' 字元。最多 128 個字元。例如,AuroraGeocoderInvoke.

    • 說明 — 輸入選擇性說明。使用英數字元和 '+=, .@-_' 字元。最多可輸入 1000 個字元

  8. 選擇建立政策。請注意此政策的 ARN,您可以使用該 ARN 將政策附加到 IAM 角色。

建立 IAM 角色以授予權限給 Amazon Relational Database Service 服務 (Amazon RDS)

透過建立 IAM 角色,Amazon Aurora PostgreSQL可以代表您擔任該角色來存取您的 Lambda 函數。如需詳細資訊,請參閱《IAM 使用者指南》中的建立角色以將許可委派給 IAM 使用者

下列範例是建立名為之角色的AWS CLI命令 AuroraGeocoderInvokeRole

aws iam create-role --role-name rds-lambda-role --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "rds.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }'

將您的 IAM 政策附加到 IAM 角色

當您具有 IAM 角色時,請附加您已建立的 IAM 政策。

下列範例是將原則附加AuroraGeocoderInvoke至角色的AWS CLI命令AuroraGeocoderInvokeRole

aws iam attach-role-policy --policy-arn AuroraGeocoderInvoke --role-name AuroraGeocoderInvokeRole

將 IAM 角色新增至 Amazon Aurora 資料庫叢集

下列範例是將 IAM 角色新增至名為的Amazon Aurora PostgreSQL資料庫叢集的AWS CLI命令MyAuroraCluster

aws rds add-role-to-db-cluster \ --db-cluster-identifier MyAuroraCluster \ --feature-name Lambda \ --role-arn AuroraGeocoderInvokeRole \ --region your-region

叫用 AWS Lambda 函數

授與叫用地理編碼 Lambda 函數的權限後,您可以建立使用Amazon Aurora PostgreSQL者定義函數來叫用地理編碼AWS Lambda函數。Amazon Aurora PostgreSQL如需詳細資訊,請參閱 Amazon Aurora 使用者指南中的從資Amazon Aurora PostgreSQL料庫叢集叫用AWS Lambda函數

安裝所需的擴充功能

若要安裝必要的 PostgreSQL 擴充功能aws_lambdaaws _commons擴充功能,請參閱 Amazon Aurora 使用者指南中的使用 Lambda 函數概觀

CREATE EXTENSION IF NOT EXISTS aws_lambda CASCADE;

安裝所需的擴充 PostGIS 能

PostGIS 是 PostgreSQL 的擴充功能,可用於儲存和管理空間資訊。如需詳細資訊,請參Amazon Relational Database Service 使用者指南中的使用 PostGIS 擴充功能。

CREATE EXTENSION IF NOT EXISTS postgis;

建立叫用 Lambda 函數的 SQL 使用者定義函數

在 SQL 編輯器中,建立新的使用者定義函數f_SearchPlaceIndexForText來叫用函數 AuroraGeocoder

CREATE OR REPLACE FUNCTION f_SearchPlaceIndexForText( text text, bias_position geometry(Point, 4326) DEFAULT NULL, filter_bbox box2d DEFAULT NULL, filter_countries text[] DEFAULT NULL, max_results int DEFAULT 1 ) RETURNS TABLE ( label text, address_number text, street text, municipality text, postal_code text, sub_region text, region text, country text, geom geometry(Point, 4326) ) LANGUAGE plpgsql IMMUTABLE AS $function$ begin RETURN QUERY WITH results AS ( SELECT json_array_elements(payload) rsp FROM aws_lambda.invoke( aws_commons.create_lambda_function_arn('AuroraGeocoder'), json_build_object( 'text', text, 'biasPosition', CASE WHEN bias_position IS NOT NULL THEN array_to_json(ARRAY[ST_X(bias_position), ST_Y(bias_position)]) END, 'filterBBox', CASE WHEN filter_bbox IS NOT NULL THEN array_to_json(ARRAY[ST_XMin(filter_bbox), ST_YMin(filter_bbox), ST_XMax(filter_bbox), ST_YMax(filter_bbox)]) END, 'filterCountries', filter_countries, 'maxResults', max_results ) ) ) SELECT rsp->'Place'->>'Label' AS label, rsp->'Place'->>'AddressNumber' AS address_number, rsp->'Place'->>'Street' AS street, rsp->'Place'->>'Municipality' AS municipality, rsp->'Place'->>'PostalCode' AS postal_code, rsp->'Place'->>'SubRegion' AS sub_region, rsp->'Place'->>'Region' AS region, rsp->'Place'->>'Country' AS country, ST_GeomFromGeoJSON( json_build_object( 'type', 'Point', 'coordinates', rsp->'Place'->'Geometry'->'Point' ) ) geom FROM results; end; $function$;

調用 SQL 函數從 Aurora 進行地理編碼

執行 SQL 陳述式會叫用 Lambda 函數 AuroraGeocoder,該函數會從資料庫中的資料庫表格取得地址記錄,並使用地點索引Amazon Aurora PostgreSQL資源對這些記錄進行地理編碼。

注意

Amazon Aurora PostgreSQL針對 SQL 使用者定義函數的每次呼叫叫用 Lambda 函數。

如果您要對 50 個資料列進行地理編碼,請Amazon Aurora PostgreSQL呼叫 Lambda 函數 50 次。每一列都有一次叫用。

下列 f_SearchPlaceIndexForText SQL 函數透過 AuroraGeocoderLambda 函數向 Amazon 位置的 SearchPlaceIndexForText API 發出請求。該函數返回一個作為 PostGIS 幾何圖形的geom列,該列ST_AsText(geom)轉換為文本。

SELECT *, ST_AsText(geom) FROM f_SearchPlaceIndexForText('Vancouver, BC');

默認情況下,返回將包含一行。若要要求其他資料列,請在加拿大的MaxResults限制範圍內執行下列 SQL 陳述式,同時提供BiasPosition和限制結果。

SELECT * FROM f_SearchPlaceIndexForText('Mount Pleasant', ST_MakePoint(-123.113, 49.260), null, '{"CAN"}', 5);

若要使用邊界方塊篩選結果,請將 a 傳遞Box2Dfilter_bbox

  • FilterBBox— 傳回邊界方框內的位置來篩選結果。這是選擇性的參數。

SELECT * FROM f_SearchPlaceIndexForText('Mount Pleasant', null, 'BOX(-139.06 48.30, -114.03 60.00)'::box2d, '{"CAN"}', 5);

如需有關 PostGIS 類型和函數的詳細資訊,請參閱 PostGIS 參考資料。

豐富包含地址數據的數據庫

您可以建構格式化的地址,並使用 Amazon Location 操作同時標準化和地理編碼SearchPlaceIndexForText給定的資料庫表格,並將下列資料分成以下各欄:

  • id

  • address

  • city

  • state

  • zip

WITH source_data AS ( SELECT id, address || ', ' || city || ', ' || state || ', ' || zip AS formatted_address FROM addresses ), geocoded_data AS ( SELECT *, (f_SearchPlaceIndexForText(formatted_address)).* FROM source_data ) SELECT id, formatted_address, label normalized_address, ST_Y(geom) latitude, ST_X(geom) longitude FROM geocoded_data -- limit the number of rows that will be geocoded; remove this to geocode the entire table LIMIT 1;

下面的例子說明了一個生成的數據表行:

id | formatted_address | normalized_address | latitude | longitude ----+--------------------------------+--------------------------------------------+------------------+------------------- 42 | 123 Anytown Ave N, Seattle, WA | 123 Anytown Ave N, Seattle, WA, 12345, USA | 47.6223000127926 | -122.336745971039 (1 row)

更新資料庫表格並填入欄

下列範例會更新資料表,並將SearchPlaceIndexForText查詢結果填入資料行:

WITH source_data AS ( -- select rows that have not been geocoded and created a formatted address for each SELECT id, address || ', ' || city || ', ' || state || ', ' || zip AS formatted_address FROM addresses WHERE label IS NULL -- limit the number of rows that will be geocoded; remove this to geocode the entire table LIMIT 1 ), geocoded_data AS ( -- geocode each row and keep it linked to the source's ID SELECT id, (f_SearchPlaceIndexForText(formatted_address)).* FROM source_data ) UPDATE addresses -- populate columns SET normalized_address = geocoded_data.label, latitude = ST_Y(geocoded_data.geom), longitude = ST_X(geocoded_data.geom) FROM geocoded_data -- ensure that rows match WHERE addresses.id = geocoded_data.id;

後續步驟

範例程式碼可在上的 Amazon 定 Location Service 範例儲存庫中取得 GitHub,其中包含AWS CloudFormation範本。