如何使用物化视图运行 Atlas Search 查询
本教程介绍如何创建索引并针对 示例数据集和新 sample_supplies.purchaseOrders
中的 sample_supplies.sales
集合运行查询。
按需具体化视图是使用 $merge
聚合管道阶段创建和更新的集合。您可以在物化视图上创建 Atlas Search 索引,然后使用 $search
聚合管道阶段对物化视图运行查询。
本教程将指导您完成以下步骤:
在
sample_supplies
数据库中创建名为purchaseOrders
的集合。创建两个定时触发器:
updateMonthlySales
,带有一个名为updateMonthlySales
的函数,该函数使用示例sample_supplies.sales
集合中的数据初始化monthlyPhoneTransactions
物化视图。updateMonthlyPurchaseOrders
,其中包含一个名为updateMonthlyPurchaseOrders
的函数,该函数使用sample_supplies.purchaseOrders
集合中的数据来更新monthlyPhoneTransactions
物化视图。
在
monthlyPhoneTransactions
物化视图上创建 Atlas Search 索引。对
monthlyPhoneTransactions
物化视图运行查询。
开始之前,请确保 Atlas 集群满足先决条件中所述的要求。
要创建 Atlas Search 索引,您必须拥有 Project Data Access Admin
或更高的项目访问权限。
要创建触发器,您必须拥有 Project Owner
或更高的项目访问权限。
创建 集合<a class=\" \" href=\" \" title=\" \"><svg xmlns=\" \" width=\" \" height=\" \" fill=\" \" viewbox=\" \" class=\" \"purchaseOrders
role=\" \" aria-label=\" \"><path fill=\" \" d=\" \"> <path fill=\" \" d=\" \">
连接到 数据库。<a class=\" \" href=\" \" title=\" \"><svg xmlns=\" \" width=\" \" height=\" \" fill=\" \" viewbox=\" \" class=\" \" role=\" \" aria-label=\" \"><path fill=\" \" d=\" \"> <path fill=\" \"sample_supplies
d=\" \">
在终端窗口中打开
mongosh
并连接到集群。有关连接的详细说明,请参阅通过mongosh
连接。使用
sample_supplies
数据库:use sample_supplies
添加新集合。
添加purchaseOrders
集合,其中包含自 2018 年一月份起的新手机采购订单数据。运行以下命令:
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' } ])
查询新集合。
查询 purchaseOrders
集合以确认新的采购订单条目。
db.purchaseOrders.find().sort( {saleDate: -1} )
{ _id: ObjectId("62434c07d574cd0ce200ba75"), 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' }, { _id: ObjectId("62434c07d574cd0ce200ba74"), 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' }
这两个查询结果反映采购订单数据在 2018 的 1 月结束。
创建定时触发器
在以下过程中,您将创建触发器以创建物化视图,并安排函数每天更新物化视图。
创建updateMonthlySales
触发器
步骤
AtlasGoTriggers在Atlas中,Go项目的 页面。
如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含项目的组织。
如果尚未显示,请从导航栏的 Projects 菜单中选择您的项目。
在侧边栏中,单击 Services 标题下的 Triggers。
会显示触发器页面。
创建该函数。
此触发器的函数定义了一个 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
集合。
创建updateMonthlyPurchaseOrders
触发器
步骤
AtlasGoTriggers在Atlas中,Go项目的 页面。
如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含项目的组织。
如果尚未显示,请从导航栏的 Projects 菜单中选择您的项目。
在侧边栏中,单击 Services 标题下的 Triggers。
会显示触发器页面。
创建该函数。
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
。
使用 mongosh
查询 monthlyPhoneTransactions
集合以确认更新:
db.monthlyPhoneTransactions.find().sort( { _id: -1} )
{ _id: '2018-01', sales_quantity: 66, sales_price: Decimal128("1407.10") }
monthlyPhoneTransactions
物化视图显示新添加的数据。排在前面的结果显示最近的交易发生在 2018 年 1 月。
在物化视图上创建 Atlas Search 索引
在 monthlyPhoneTransactions
集合上创建 Atlas Search 索引。
AtlasGoClusters在Atlas中,Go项目的 页面。
如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含所需项目的组织。
如果尚未显示,请从导航栏的Projects菜单中选择所需的项目。
如果尚未出现,请单击侧边栏中的 Clusters(部署)。
会显示集群页面。
转到集群的 Atlas Search 页面。
您可以从侧边栏、 Data Explorer 或集群详细信息页面转到 Atlas Search 页面。
在侧边栏中,单击 Services 标题下的 Atlas Search。
从 Select data source 下拉菜单中选择您的集群并单击 Go to Atlas Search。
将显示 Atlas Search 页面。
单击集群的对应 Browse Collections 按钮。
展开数据库并选择集合。
单击该集合的 Search Indexes 标签页。
将显示 Atlas Search 页面。
单击集群的名称。
单击 Atlas Search 标签页。
将显示 Atlas Search 页面。
对物化视图运行查询
针对新更新并编入索引的 monthlyPhoneTransactions
集合运行查询。
通过mongosh
连接到您的集群。
在终端窗口中打开mongosh
并连接到集群。 有关连接的详细说明,请参阅通过mongosh
连接。
使用sample_supplies
数据库。
在 mongosh
提示符下运行以下命令:
use sample_supplies
对 集合运行简单的 Atlas Searchsample_supplies.monthlyPhoneTransactions
查询。
以下查询统计 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 服务器手册。