Docs 主页 → 启动和管理 MongoDB → MongoDB Atlas
如何使用物化视图运行 Atlas Search 查询
在此页面上
本教程介绍如何使用以下功能的组合来创建索引并针对样本数据集中的 sample_supplies.sales
集合和新的sample_supplies.purchaseOrders
集合运行查询:
按需物化视图是您使用$merge
聚合管道阶段创建和更新的集合。您可以在物化视图上创建 Atlas Search 索引,然后使用$search
聚合管道阶段在物化视图上运行查询。
本教程将指导您完成以下步骤:
在
sample_supplies
数据库中创建名为purchaseOrders
的集合。在 App Services 用户界面中创建名为
updateMonthlySales
的 App Services 函数,以使用来自 Atlas 集群上示例sample_supplies.sales
集合的数据来初始化monthlyPhoneTransactions
物化视图。在 App Services 用户界面中创建名为
updateMonthlyPurchaseOrders
的 App Services 函数,以使用您在 Atlas 集群上创建的sample_supplies.purchaseOrders
集合中的数据更新monthlyPhoneTransactions
物化视图。使用 App Services 定时触发器安排以下函数以定期更新
monthlyPhoneTransactions
物化视图:updateMonthlySales
updateMonthlyPurchaseOrders
在
monthlyPhoneTransactions
物化视图上创建 Atlas Search 索引。对
monthlyPhoneTransactions
物化视图运行查询。
开始之前,请确保 Atlas 集群满足先决条件中所述的要求。
要创建 Atlas Search 索引,您必须拥有 Project Data Access Admin
或更高的项目访问权限。
要创建 App Services 函数和触发器,您必须对项目具有Project Owner
或更高访问权限。
创建purchaseOrders
集合
连接到sample_supplies
数据库。
在终端窗口中打开
mongosh
并连接到集群。有关连接的详细说明,请参阅通过mongosh
连接。使用
sample_supplies
数据库:use sample_supplies
添加新集合。
添加purchaseOrders
集合,其中包含2018 1 月以来的新手机采购订单数据。运行以下命令:
db.purchaseOrders.insertMany( [ { saleDate: ISODate("2018-01-23T21:06:49.506Z"), items: [ { name: 'printer paper', tags: [ 'office', 'stationary' ], price: Decimal128("40.01"), quantity: 2 }, { name: 'notepad', tags: [ 'office', 'writing', 'school' ], price: Decimal128("35.29"), quantity: 2 }, { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ], price: Decimal128("56.12"), quantity: 5 }, { name: 'backpack', tags: [ 'school', 'travel', 'kids' ], price: Decimal128("77.71"), quantity: 2 }, { name: 'notepad', tags: [ 'office', 'writing', 'school' ], price: Decimal128("18.47"), quantity: 2 }, { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ], price: Decimal128("19.95"), quantity: 8 }, { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ], price: Decimal128("8.08"), quantity: 3 }, { name: 'binder', tags: [ 'school', 'general', 'organization' ], price: Decimal128("14.16"), quantity: 3 } ], storeLocation: 'Denver', customer: { gender: 'M', age: 42, email: 'cauho@witwuta.sv', satisfaction: 4 }, couponUsed: true, purchaseMethod: 'Phone' } ])
db.purchaseOrders.insertMany( [ { saleDate: ISODate("2018-01-25T10:01:02.918Z"), items: [ { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ], price: Decimal128("8.05"), quantity: 10 }, { name: 'binder', tags: [ 'school', 'general', 'organization' ], price: Decimal128("28.31"), quantity: 9 }, { name: 'notepad', tags: [ 'office', 'writing', 'school' ], price: Decimal128("20.95"), quantity: 3 }, { name: 'laptop', tags: [ 'electronics', 'school', 'office' ], price: Decimal128("866.5"), quantity: 4 }, { name: 'notepad', tags: [ 'office', 'writing', 'school' ], price: Decimal128("33.09"), quantity: 4 }, { name: 'printer paper', tags: [ 'office', 'stationary' ], price: Decimal128("37.55"), quantity: 1 }, { name: 'backpack', tags: [ 'school', 'travel', 'kids' ], price: Decimal128("83.28"), quantity: 2 }, { name: 'pens', tags: [ 'writing', 'office', 'school', 'stationary' ], price: Decimal128("42.9"), quantity: 4 }, { name: 'envelopes', tags: [ 'stationary', 'office', 'general' ], price: Decimal128("16.68"), quantity: 2 } ], storeLocation: 'Seattle', customer: { gender: 'M', age: 50, email: 'keecade@hem.uy', satisfaction: 5 }, couponUsed: false, purchaseMethod: 'Phone' } ])
创建updateMonthlySales
函数
在 App Services 用户界面中创建updateMonthlySales函数。
updateMonthlySales
函数的工作原理
updateMonthlySales
函数定义一个monthlyPhoneTransactions
物化视图,其中包含每月累计销售信息。该函数更新通过电话进行的销售的每月销售信息。
以下示例定义了该函数:
exports = function(){ var pipeline = [ { $match: {purchaseMethod: "Phone"} }, { $unwind: {path: "$items"}}, { $group: { _id: { $dateToString: { format: "%Y-%m", date: "$saleDate" } }, sales_quantity: { $sum: "$items.quantity"}, sales_price: { $sum: "$items.price"} }}, { $set: { sales_price: { $toDouble: "$sales_price"}}}, { $merge: { into: "monthlyPhoneTransactions", whenMatched: "replace" } } ] var monthlyPhoneTransactions = context.services.get("mongodb-atlas").db("sample_supplies").collection("sales"); return monthlyPhoneTransactions.aggregate(pipeline); };
该函数使用以下聚合管道阶段来更新monthlyPhoneTransactions
:
$match
阶段会对数据进行筛选,以仅处理在Phone
内完成的销售。$group
阶段按年月对销售信息进行分组。此阶段输出具有以下形式的文档:{ "_id" : "<YYYY-mm>", "sales_quantity" : <num>, "sales_amount" : <NumberDecimal> } $set
阶段将sales_price
字段的数据类型更改为double
。 Atlas Search$search
操作符不支持Decimal128
数据类型。更改sales_price
字段的数据类型后,您可以使用 Atlas Search 索引查询该字段。$merge
阶段将输出写入monthlyPhoneTransactions
集合。
步骤
创建一个新应用。
要从用户界面定义新的服务器端函数,必须首先创建一个 App Services App:
如果尚未执行此操作,请单击 App Services标签页。
创建应用程序:
如果您在项目中创建第一个 App Services App,则系统会显示一个不使用模板启动的选项 ( Build your own App )。选择Build your own App选项。
如果您已在项目中创建至少一个 App Services App,请单击Create a New App 。
在Name字段中,输入
Sales-App
作为函数名称。在Link your Database字段下,选择Use an existing MongoDB Atlas Data Source选项。
从下拉列表中,选择您在先决条件中创建的 Atlas 集群。
单击 Create App Service(连接)。
输入updateMonthlySales
功能代码。
单击 Function Editor 标签页。
将 JavaScript 代码添加到
exports
函数中。至少,代码必须将一个函数分配给全局变量exports
:exports = function(){ var pipeline = [ { $match: {purchaseMethod: "Phone"} }, { $unwind: {path: "$items"}}, { $group: { _id: { $dateToString:{ format: "%Y-%m", date: "$saleDate" } }, sales_quantity: { $sum: "$items.quantity"}, sales_price: { $sum: "$items.price"} } }, { $set: { sales_price: { $toDouble: "$sales_price"}}}, { $merge: { into: "monthlyPhoneTransactions", whenMatched: "replace" } } ] var monthlyPhoneTransactions = context.services.get("mongodb-atlas").db("sample_supplies").collection("sales"); return monthlyPhoneTransactions.aggregate(pipeline); }; 单击Function Editor右下角的Run按钮,创建
monthlyPhoneTransactions
物化视图。Function Editor底部的Result标签页应指示成功,没有任何错误。
单击 Save Draft(连接)。
测试函数。
在终端窗口中打开
mongosh
并连接到集群。有关连接的详细说明,请参阅通过mongosh
连接。使用
sample_supplies
数据库:use sample_supplies 查询
sales
集合。请注意,sales
中的最后一次销售发生在2017的 12 月:db.sales.find().sort( {saleDate: -1} ) 确认已在
sample_supplies
数据库中创建物化视图:show collections 该命令会列出您的集合,包括新创建的
monthlyPhoneTransactions
物化视图。查询
monthlyPhoneTransactions
物化视图:db.monthlyPhoneTransactions.find().sort( { _id: -1} ) monthlyPhoneTransactions
物化视图会显示新添加的数据。顶部结果反映了最近的事务发生在 12 月2017 。
创建updateMonthlyPurchaseOrders
函数
在 App Services 用户界面中创建updateMonthlyPurchaseOrders函数。
updateMonthlyPurchaseOrders
函数的工作原理
updateMonthlyPurchaseOrders
函数将每月累积采购订单信息添加到monthlyPhoneTransactions
物化视图。该函数更新通过电话执行的采购订单的每月采购订单信息。
以下示例定义了该函数:
exports = function(){ var pipeline = [ { $match: {purchaseMethod: "Phone"} }, { $unwind: {path: "$items"}}, { $group: { _id: { $dateToString: { format: "%Y-%m", date: "$saleDate" } }, sales_quantity: { $sum: "$items.quantity"}, sales_price: { $sum: "$items.price"} }}, { $set: { sales_price: { $toDouble: "$sales_price"}}}, { $merge: { into: "monthlyPhoneTransactions", whenMatched: "replace" } } ] var monthlyPhoneTransactions = context.services.get("mongodb-atlas").db("sample_supplies").collection("purchaseOrders"); return monthlyPhoneTransactions.aggregate(pipeline); };
updateMonthlyPurchaseOrders
函数使用与updateMonthlySales函数相同的聚合管道阶段来更新monthlyPhoneTransactions
。
步骤
输入updateMonthlyPurchaseOrders
功能代码
单击 Function Editor 标签页。
将 JavaScript 代码添加到
exports
函数中。至少,代码必须将一个函数分配给全局变量exports
:exports = function(){ var pipeline = [ { $match: {purchaseMethod: "Phone"} }, { $unwind: {path: "$items"}}, { $group: { _id: { $dateToString:{ format: "%Y-%m", date: "$saleDate" } }, sales_quantity: { $sum: "$items.quantity"}, sales_price: { $sum: "$items.price"} } }, { $set: { sales_price: { $toDouble: "$sales_price"}}}, { $merge: { into: "monthlyPhoneTransactions", whenMatched: "replace" } } ] var monthlyPhoneTransactions = context.services.get("mongodb-atlas").db("sample_supplies").collection("purchaseOrders"); return monthlyPhoneTransactions.aggregate(pipeline); }; 单击Function Editor右下角的Run按钮,更新
monthlyPhoneTransactions
物化视图。Function Editor底部的Result标签页应指示成功,没有任何错误。
updateMonthlyPurchaseOrders
函数使用2018 1 月采购订单数据刷新monthlyPhoneTransactions
物化视图。单击 Save Draft(连接)。
确认更新。
返回
mongosh
并查询monthlyPhoneTransactions
集合以确认更新:db.monthlyPhoneTransactions.find().sort( { _id: -1} ) monthlyPhoneTransactions
物化视图会显示新添加的数据。顶部结果反映了最近的事务发生在2018 1 月。
创建定时触发器
将上一步中创建的 App Services 函数安排为每天运行一次,以使物化视图保持最新状态。
在物化视图上创建 Atlas Search 索引
在 monthlyPhoneTransactions
集合上创建 Atlas Search 索引。
在物化视图上运行查询
针对新近更新和编制索引的monthlyPhoneTransactions
集合运行查询。
连接到mongosh
中的集群。
在终端窗口中打开mongosh
并连接到集群。有关连接的详细说明,请参阅通过mongosh
连接。
使用sample_supplies
数据库。
在mongosh
提示符下运行以下命令:
use sample_supplies
对sample_supplies.monthlyPhoneTransactions
集合运行简单的 Atlas Search 查询。
以下查询计算 MonthlyPhoneTransactions 中总销售额大于或等于10000
美元的月数:
db.monthlyPhoneTransactions.aggregate([ { $search: { "index": "monthlySalesIndex", "range": { "gt": 10000, "path": ["sales_price"] } } }, { $count: 'months_w_over_10000' }, ])
上述查询返回4
,表示monthlyPhoneTransactions
物化视图的所有月份中只有4个月的总销售额大于或等于10000美元。此结果反映了来自sample_supplies.sales
和sample_supplies.purchaseOrders
集合的数据。
有关完整的聚合管道文档,请参阅《 MongoDB Server 手册》。