数据库
首页 > 数据库> > MongoDB按需物化视图介绍

MongoDB按需物化视图介绍

作者:互联网

图片

注意

本页的内容讨论了按需物化视图。有关视图的讨论,请参阅视图

从4.2版本开始,MongoDB为aggregation pipeline添加了$merge阶段。此阶段可以将管道结果合并到现有集合中,而不是完全替换现有集合。此功能允许用户创建按需物化视图,每次运行管道时都可以更新输出集合的内容。

示例

假设现在接近2019年1月末,集合bakesales包含按项目分类的销售信息:

db.bakesales.insertMany( [   { date: new ISODate("2018-12-01"), item: "Cake - Chocolate", quantity: 2, amount: new NumberDecimal("60") },   { date: new ISODate("2018-12-02"), item: "Cake - Peanut Butter", quantity: 5, amount: new NumberDecimal("90") },   { date: new ISODate("2018-12-02"), item: "Cake - Red Velvet", quantity: 10, amount: new NumberDecimal("200") },   { date: new ISODate("2018-12-04"), item: "Cookies - Chocolate Chip", quantity: 20, amount: new NumberDecimal("80") },   { date: new ISODate("2018-12-04"), item: "Cake - Peanut Butter", quantity: 1, amount: new NumberDecimal("16") },   { date: new ISODate("2018-12-05"), item: "Pie - Key Lime", quantity: 3, amount: new NumberDecimal("60") },   { date: new ISODate("2019-01-25"), item: "Cake - Chocolate", quantity: 2, amount: new NumberDecimal("60") },   { date: new ISODate("2019-01-25"), item: "Cake - Peanut Butter", quantity: 1, amount: new NumberDecimal("16") },   { date: new ISODate("2019-01-26"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") },   { date: new ISODate("2019-01-26"), item: "Cookies - Chocolate Chip", quantity: 12, amount: new NumberDecimal("48") },   { date: new ISODate("2019-01-26"), item: "Cake - Carrot", quantity: 2, amount: new NumberDecimal("36") },   { date: new ISODate("2019-01-26"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") },   { date: new ISODate("2019-01-27"), item: "Pie - Chocolate Cream", quantity: 1, amount: new NumberDecimal("20") },   { date: new ISODate("2019-01-27"), item: "Cake - Peanut Butter", quantity: 5, amount: new NumberDecimal("80") },   { date: new ISODate("2019-01-27"), item: "Tarts - Apple", quantity: 3, amount: new NumberDecimal("12") },   { date: new ISODate("2019-01-27"), item: "Cookies - Chocolate Chip", quantity: 12, amount: new NumberDecimal("48") },   { date: new ISODate("2019-01-27"), item: "Cake - Carrot", quantity: 5, amount: new NumberDecimal("36") },   { date: new ISODate("2019-01-27"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") },   { date: new ISODate("2019-01-28"), item: "Cookies - Chocolate Chip", quantity: 20, amount: new NumberDecimal("80") },   { date: new ISODate("2019-01-28"), item: "Pie - Key Lime", quantity: 3, amount: new NumberDecimal("60") },   { date: new ISODate("2019-01-28"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") },] );

定义按需物化视图

下面的updateMonthlySales函数定义了一个monthlybakesales物化视图,其中包含累积的每月销售信息。在示例中,该函数采用了一个日期参数来更新从特定日期开始的每月销售信息。

updateMonthlySales = function(startDate) {   db.bakesales.aggregate( [      { $match: { date: { $gte: startDate } } },      { $group: { _id: { $dateToString: { format: "%Y-%m", date: "$date" } }, sales_quantity: { $sum: "$quantity"}, sales_amount: { $sum: "$amount" } } },      { $merge: { into: "monthlybakesales", whenMatched: "replace" } }   ] );};
{ "_id" : "<YYYY-mm>", "sales_quantity" : <num>, "sales_amount" : <NumberDecimal> }

执行初始运行

对于初始运行,你可以传入一个日期new ISODate("1970-01-01")

updateMonthlySales(new ISODate("1970-01-01"));

初始运行后,monthlybakesales包含以下文档;即db.monthlybakesales.find().sort( { _id: 1 } )返回以下内容:​​​​​​​

{ "_id" : "2018-12", "sales_quantity" : 41, "sales_amount" : NumberDecimal("506") }{ "_id" : "2019-01", "sales_quantity" : 86, "sales_amount" : NumberDecimal("896") }

刷新物化视图

假设到了2019年2月的第一周,bakesales集合更新了新的销售信息;具体来说就是一月和二月新增的销售。

db.bakesales.insertMany( [   { date: new ISODate("2019-01-28"), item: "Cake - Chocolate", quantity: 3, amount: new NumberDecimal("90") },   { date: new ISODate("2019-01-28"), item: "Cake - Peanut Butter", quantity: 2, amount: new NumberDecimal("32") },   { date: new ISODate("2019-01-30"), item: "Cake - Red Velvet", quantity: 1, amount: new NumberDecimal("20") },   { date: new ISODate("2019-01-30"), item: "Cookies - Chocolate Chip", quantity: 6, amount: new NumberDecimal("24") },   { date: new ISODate("2019-01-31"), item: "Pie - Key Lime", quantity: 2, amount: new NumberDecimal("40") },   { date: new ISODate("2019-01-31"), item: "Pie - Banana Cream", quantity: 2, amount: new NumberDecimal("40") },   { date: new ISODate("2019-02-01"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") },   { date: new ISODate("2019-02-01"), item: "Tarts - Apple", quantity: 2, amount: new NumberDecimal("8") },   { date: new ISODate("2019-02-02"), item: "Cake - Chocolate", quantity: 2, amount: new NumberDecimal("60") },   { date: new ISODate("2019-02-02"), item: "Cake - Peanut Butter", quantity: 1, amount: new NumberDecimal("16") },   { date: new ISODate("2019-02-03"), item: "Cake - Red Velvet", quantity: 5, amount: new NumberDecimal("100") }] )
为了刷新1月和2月的monthlybakesales数据,需要再次运行该函数以重新运行聚合管道,日期参数值从new ISODate("2019-01-01")开始。
updateMonthlySales(new ISODate("2019-01-01"));
monthlybakesales的内容已更新,并能反映出bakesales集合中的最新数据;即db.monthlybakesales.find().sort( { _id: 1 } )返回以下内容:​​​​​​
{ "_id" : "2018-12", "sales_quantity" : 41, "sales_amount" : NumberDecimal("506") }{ "_id" : "2019-01", "sales_quantity" : 102, "sales_amount" : NumberDecimal("1142") }{ "_id" : "2019-02", "sales_quantity" : 15, "sales_amount" : NumberDecimal("284") }

附加信息

$merge阶段:

参考$merge

原文链接:On-Demand Materialized Views — MongoDB Manual

译者:李正洋

DBA一枚,擅长oracle/mongodb//tidb等多种数据库。

现阶段对开源分布式数据库、云计算等领域有很大兴趣;平时喜欢打羽毛球、看电影等。

 

标签:MongoDB,NumberDecimal,视图,物化,amount,ISODate,date,new,quantity
来源: https://blog.csdn.net/u014361223/article/details/122242957