按需物化视图
注意
本页的内容讨论了按需物化视图。有关视图的讨论,请参阅视图。
从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") },
] );1.定义按需物化视图
下面的updateMonthlySales函数定义了一个monthlybakesales物化视图,其中包含累积的每月销售信息。在示例中,该函数采用了一个日期参数来更新从特定日期开始的每月销售信息。
$match阶段过滤数据以仅处理那些销售额大于或等于startDate阶段按年-月对销售信息进行分组。此阶段输出的文档具有以下形式:
2. 执行初始运行
对于初始运行,你可以传入一个日期new ISODate("1970-01-01"):
初始运行后,monthlybakesales包含以下文档;即db.monthlybakesales.find().sort( { _id: 1 } )返回以下内容:
3. 刷新物化视图
假设到了2019年2月的第一周,bakesales集合更新了新的销售信息;具体来说就是一月和二月新增的销售。
为了刷新1月和2月的monthlybakesales数据,需要再次运行该函数以重新运行聚合管道,日期参数值从new ISODate("2019-01-01")开始。
monthlybakesales的内容已更新,并能反映出bakesales集合中的最新数据;即db.monthlybakesales.find().sort( { _id: 1 } )返回以下内容:
附加信息
$merge阶段:
可以输出到相同或不同数据库中的集合。
如果输出集合不存在,则会创建一个新集合。
可以将结果(插入新文档、合并文档、替换文档、保留现有文档、操作失败、使用自定义更新管道处理文档)合并到现有集合中。
可以输出到分片的集合中。输入集合也可以是分片集合。
参考$merge:
有关
$merge和可用选项的更多信息示例:按需物化视图:初始创建
示例:仅插入新数据
原文链接:https://docs.mongodb.com/manual/core/materialized-views/
译者:李正洋
最后更新于