亚马逊AWS官方博客

使用Amazon Elasticsearch Service在Amazon DocumentDB (兼容MongoDB)的数据上运行全文搜索查询

原文链接:

https://amazonaws-china.com/cn/blogs/database/run-full-text-search-queries-on-amazon-documentdb-data-with-amazon-elasticsearch-service/

 

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函数。

下图所示,为这套解决方案的最终架构。

 

演练概述

本文具体涵盖以下任务:

  1. 部署一套AWS CloudFormation模板以启动以下组件:
    1. Amazon DocumentDB集群
    2. Amazon ES域
    3. AWS Cloud9环境
    4. AWS Secrets Manager secret
    5. Amazon SNS触发器
    6. EventBridge规则
  2. 设置一套AWS Cloud9环境。
  3. 在Amazon DocumentDB上启用变更流。
  4. 设置并部署Lambda流函数,该函数将变更事件从Amazon DocumentDB集群复制到Amazon ES域。
  5. 运行全文搜索查询。

 

部署一套CloudFormation模板

AWS CloudFormation提供一种通用语言,供您在云环境中对AWS资源进行建模及配置。在本演练中,您将部署一套CloudFormation模板,用于创建以下内容:

  1. Amazon DocumentDB集群 – 运营性质的JSON数据存储方案
  2. Amazon ES域 – 运行全文搜索查询
  3. AWS Cloud9环境 – 一套集成开发环境 (IDE)
  4. Secrets Manager secret – 管理Amazon DocumentDB凭证
  5. 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栈名称相匹配

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 StreamsAmazon Simple Queue Service (Amazon SQS)以及Amazon S3。

如果您对本文还有任何疑问或建议,请在评论中与我们分享。如果您希望查看Lambda函数源代码,或希望指出错误,请访问我们的Amazon DocumentDB 示例GitHub repo。如果您对Amazon DocumentDB还有任何功能需求,请通过documentdb-feature-request@amazon.com邮件地址与我们联系。

 

本篇作者

Herbert Gomez

Amazon Web Services公司解决方案架构师。他与AWS客户合作,帮助他们在云端构建安全、有弹性、可扩展的高性能应用程序。

Vijay Injam

Amazon Web Services公司高级NoSQL数据架构师。他对AWS抱有极高热忱,乐于帮助客户使用AWS NoSQL数据库进行创新。

Meet Bhagdev

Amazon Web Services公司高级产品经理。Meet对一切数据充满热情,并投入大量时间与客户交流,根据他们的要求建立起愉悦的体验。在加入AWS之前,Meet曾在微软负责Azure数据库项目。