亚马逊AWS官方博客
使用Amazon Elasticsearch Service在Amazon DocumentDB (兼容MongoDB)的数据上运行全文搜索查询
原文链接:
Amazon DocumentDB (兼容MongoDB)是一项快速、可扩展、具备高可用性的全托管文档数据库服务,可支持MongoDB工作负载。您可以使用相同的MongoDB应用程序代码、驱动程序与工具运行、管理并扩展Amazon DocumentDB上的工作负载,且不必分神于底层基础设施管理事务。作为一套文档数据库,Amazon DocumentDB极大简化了对JSON数据的存储、查询与索引流程。
随着用例的发展,您可能希望从数据当中获取更多洞见。例如,如果您运营一套社交媒体平台,则可以使用Amazon DocumentDB以JSON文档的形式存储用户个人资料与用户内容数据模型。随着平台的发展,您还可以搜索用户内容以查找与特定关键词相关的模式。例如,您可能希望确定有哪些用户发布过关于运动的信息,确定哪些用户共享过与小狗相关的内容、或搜索过某些特定标签。您可以对数据运行全文查询并轻松达成这些目标。Amazon Elasticsearch Service (Amazon ES)专门用于为您对数据运行全文搜索查询。
在本文中,我们将向您介绍如何将Amazon DocumentDB与Amazon ES相集成,帮助您对Amazon DocumentDB数据运行全文搜索查询。具体来讲,我们将向您展示如何使用AWS Lambda函数将事件从Amazon DocumentDB集群的变更流传输至Amazon ES域,借此对数据运行全文搜索查询。为了实现解决方案自动化,我们使用Amazon EventBridge每60秒触发一条发往Amazon Simple Notification Service (Amazon SNS)的消息,并由SNS服务按计划调用Lambda函数。
演练概述
本文具体涵盖以下任务:
- 部署一套AWS CloudFormation模板以启动以下组件:
- Amazon DocumentDB集群
- Amazon ES域
- AWS Cloud9环境
- AWS Secrets Manager secret
- Amazon SNS触发器
- EventBridge规则
- 设置一套AWS Cloud9环境。
- 在Amazon DocumentDB上启用变更流。
- 设置并部署Lambda流函数,该函数将变更事件从Amazon DocumentDB集群复制到Amazon ES域。
- 运行全文搜索查询。
部署一套CloudFormation模板
AWS CloudFormation提供一种通用语言,供您在云环境中对AWS资源进行建模及配置。在本演练中,您将部署一套CloudFormation模板,用于创建以下内容:
- Amazon DocumentDB集群 – 运营性质的JSON数据存储方案
- Amazon ES域 – 运行全文搜索查询
- AWS Cloud9环境 – 一套集成开发环境 (IDE)
- Secrets Manager secret – 管理Amazon DocumentDB凭证
- Amazon SNS触发器与EventBridge规则 – 自动执行解决方案,每120秒运行一次Lambda函数
备注:此模板将产生费用。关于模板所部署资源的更多定价信息,请参阅AWS费率说明。
要部署此模板,请完成以下操作步骤:
- 在AWS CloudFormation控制台上, 选择 Create stack。
- 选择 Upload a template file。
- 选择 choose file。
- 上传 docdb_change_streams.yml 文件。
- 选择 Next。
- 为您的Amazon DocumentDB集群输入名称、用户名、密码与标识符。
AWS Cloud9要求使用AWS身份与访问管理(IAM)角色。如果您之前已经在使用AWS Cloud9,则应拥有现成角色。您可以跳转至IAM控制台并搜索AWSCloud9SSMAccessRole角色进行验证。
- 如果您已经拥有角色,请选择 true。如果还没有角色,请选择 false,AWS CloudFormation模板将为您创建新角色。
- 其他部分保留默认设置,之后选择 Next。
- 选中复选框,允许栈为您创建角色。
- 选择 Create stack。
设置一套AWS Cloud9环境
要设置您的云IDE,请完成以下操作步骤:
-
- 在AWS Cloud9控制台上,启动之前由CloudFormation栈创建完成的环境。
- 在您的环境中,启动一个新选项卡打开Preferences标签。
- 在左侧导航栏中选择 AWS SETTINGS。
- 关闭AWS托管临时凭证。这样我们可以在之后的演练步骤中简化开发人员的使用体验。
- 关闭 Preferences 选项卡。
- 通过AWS Cloud9环境的终端,使用以下代码删除一切现有凭证文件:
rm -vf ${HOME}/.aws/credentials
- 为使用以下代码创建的CloudFormation栈名称,设定一项环境变量(我们稍后将使用此环境变量):
export STACK=<Name of your CloudFormation stack>
#这应与您在上一步中指定的AWS CloudFormation栈名称相匹配
- 配置 AWS命令行界面 (AWS CLI)默认使用当前区域:
export AWS_REGION=$(curl -s 169.254.169.254/latest/dynamic/instance-identity/document | grep region | cut -d\" -f4)
- 通过运行以下代码,下载并运行startup.sh文件:
curl -s https://raw.githubusercontent.com/aws-samples/amazon-documentdb-samples/master/samples/change-streams/setup/startup.sh -o startup.shchmod 700 startup.sh
./startup.sh
此启动脚本会更新并安装必要的Python库,打包Lambda函数代码,并将其上传至Amazon Simple Storage Service(Amazon S3)存储桶,而后将CloudFormation栈的输出复制至AWS Cloud9环境。
在Amazon DocumentDB上启用变更流
Amazon DocumentDB变更流提供一条按时间顺序排列的更新事件序列,用以囊括发生在集群内各集合与数据库中的更新事件。您可以轮询单一集合上的变更流,并在发生变更事件(INSERTS, UPDATES以及DELETES)时进行读取。我们使用变量流,将变更事件从您的Amazon DocumentDB集群流式传输至Amazon ES域。要在集群上启用变更流,请输入以下代码(请将相应部分替换为您的集群值)。首先,我们使用mongo shell登录数据库:
export USERNAME=<DocumentDB cluster username>
echo "export USERNAME=${USERNAME}" >> ~/.bash_profile
export PASSWORD=<DocumentDB cluster password>
echo "export PASSWORD=${PASSWORD}" >> ~/.bash_profile
export DOCDB_ENDPOINT=$(jq < cfn-output.json -r '.DocumentDBEndpoint')
echo "export DOCDB_ENDPOINT=${DOCDB_ENDPOINT}" >> ~/.bash_profile
#登录至您的Amazon DocumentDB集群
mongo --ssl --host $DOCDB_ENDPOINT:27017 --sslCAFile rds-combined-ca-bundle.pem --username $USERNAME --password $PASSWORD
接下来,在集群上启用变更流:
db.adminCommand({modifyChangeStreams: 1, database: "", collection: "", enable: true});
您应得到以下响应结果:
{ "ok" : 1 }
设置并部署Lambda函数
Lambda函数从Secrets Manager当中检索Amazon DocumentDB凭证,建立与Amazon DocumentDB集群的连接,从Amazon DocumentDB变更流中读取变更事件,并将其复制到Amazon ES索引。此函数还会在Amazon DocumentDB当中存储一个变更流恢复令牌,确保下次运行时清楚应在哪里恢复。为了实现整套解决方案的自动化,我们每60秒轮询一次变更。这里使用EventBridge触发一条发往Amazon SNS的消息,并由后者据此调用以上提到的函数。
此Lambda函数使用以下三项可调整的变量:
- Timeout – Lambda函数的超时持续时长。默认设置为120秒。
- Documents_per_run – 该变更控制每次运行函数时,从变更流中扫描多少个文档。默认设置为1000个。
- Iterations_per_sync – 此变更确定Lambda函数在同步恢复令牌(恢复令牌以跟踪变更流中处理的事件)之前需要等待多少次迭代。默认设置为15次。
要部署Lambda函数,请在AWS Cloud9环境中开启一个新终端,而后输入以下代码:
curl -s https://raw.githubusercontent.com/aws-samples/amazon-documentdb-samples/master/samples/change-streams/setup/lambda_function_config.sh -o lambda_function_config.sh
chmod 700 lambda_function_config.sh
./lambda_function_config.sh
这将创建并部署新的CloudFormation栈。此栈预置有Lambda函数,此函数将变更事件从您的Amazon DocumentDB集群流式传输到Amazon ES域。栈内填充有以下内容:
- 供Amazon DocumentDB集群使用的环境变量
- Amazon ES域
- 监控的数据库名称(Lambda函数负责监控变更事件的数据库)
- 状态数据库与集合名称(存储最后处理的变更事件的数据库与集合)
- SNS主题ARN
- Lambda角色ARN
- Secrets Manager ARN
运行全文搜索查询
在开始运行全文搜索查询之前,您需要完成以下步骤:
- 在您的AWS Cloud9终端内,输入以下代码将示例代码插入您的Amazon DocumentDB集群。在本演练中,我们插件几条来自2014年元旦前夜的推文:
#执行Python脚本将数据插入至您的Amazon DocumentDB集群
python es-test.py
- 通过从mongo shell验证您的Amazon DocumentDB集群并使用以下代码以验证文档是否成功插入:
mongo --ssl --host $DOCDB_ENDPOINT:27017 --sslCAFile rds-combined-ca-bundle.pem --username $USERNAME --password $PASSWORDuse sampledb
db.tweets.find()
在将数据插入Amazon DocumentDB集群之后,当Lambda函数运行时,数据会自动被复制到您的Amazon ES域。通过EventBridge与Amazon SNS设置,默认触发器每120秒运行一次函数。或者,您也可以通过AWS管理控制台或AWS CLI运行Lambda函数进行一次性测试。
- 在触发Lambda函数之后,通过从AWS Cloud9环境中的终端面向您的Amazon ES域输入以下代码,即可验证数据是否成功复制:
curl https://$(jq < cfn-output.json -r '.ElasticsearchDomainEndpoint')/_cat/indices?v
您应该看到,Amazon DocumentDB集群中的数据已经被填充进一条新的索引(具体参见以下截屏)。
在数据被复制到您的Amazon ES域之后,您可以对域内的JSON数据运行全文搜索查询。例如,您可以运行查询以查找全文中提及“gym”的推文:
curl -X GET "https://$(jq < cfn-output.json -r '.ElasticsearchDomainEndpoint')/sampledb-tweets/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"match" : {
"text": "gym"
}
}
}'
借助Amazon ES,您还可以运行模糊的全文搜索查询。模糊查询返回包含与搜索词相似的文档内容。例如,如果搜索词是“hello”,则匹配结果将包含“help”、“hallo”以及“heloo”等部分。在以下代码中,我们运行查询并查找可与“New”模糊匹配的所有推文:
curl -X GET "https://$(jq < cfn-output.json -r '.ElasticsearchDomainEndpoint')/sampledb-tweets/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"fuzzy": {
"text": {
"value": "New"
}
}
}
}'
关于Amazon ES查询类型的更多信息,请参阅在Amazon Elasticsearch Service中搜索数据。
清理资源
要清理本次演练中创建的资源,请导航至AWS CloudFormation控制台,找到您为本次演练创建的栈,而后一一将其删除。操作之后,即可删除与演练相关的所有资源。
总结
本文向您展示了如何将Amazon ES与Amazon DocumentDB集成起来以对JSON数据执行全文搜索查询。具体来说,我们使用Lambda函数将变更事件从Amazon DocumentDB变更流复制到Amazon ES索引。
您也可以使用变更流将Amazon DocumentDB与其他AWS服务相集成。例如,您可以将变更流事件复制到Amazon Managed Streaming for Apache Kafka(或者任何其他Apache Kafka发行版当中)、Amazon Kinesis Data Streams, Amazon Simple Queue Service (Amazon SQS)以及Amazon S3。
如果您对本文还有任何疑问或建议,请在评论中与我们分享。如果您希望查看Lambda函数源代码,或希望指出错误,请访问我们的Amazon DocumentDB 示例GitHub repo。如果您对Amazon DocumentDB还有任何功能需求,请通过documentdb-feature-request@amazon.com邮件地址与我们联系。
本篇作者