如何使用物化视图运行 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
或更高的项目访问权限。
创建 purchaseOrders
集合
连接到 sample_supplies
数据库。
在终端窗口中打开
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(集群)。
会显示集群页面。
开始您的索引配置。
在页面上进行以下选择,然后单击 Next。
Search Type | 选择 Atlas Search 索引类型。 |
Index Name and Data Source | 指定以下信息:
|
Configuration Method | For a guided experience, select Visual Editor. To edit the raw index definition, select JSON Editor. |
对物化视图运行查询
针对新更新并编入索引的 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 服务器手册。