注意
消歧
本页讨论按需物化视图。有关标准视图的讨论,请参阅视图。
To understand the differences between the view types, see Comparison with Standard Views.
按需物化视图是预先计算的聚合管道结果,存储在磁盘上并从磁盘读取。按需物化视图通常是 $merge 或 $out 阶段的结果。
与标准视图的对比
MongoDB 提供两种不同的视图类型:标准视图和按需物化视图。这两种视图类型都可以返回聚合管道的结果。
标准视图在您读取视图时计算得出,并且不会在磁盘中存储。
索引
标准视图使用底层集合的索引。因此,您无法直接在标准视图上创建、删除或重新构建索引,也无法获取视图上的索引列表。
您可以直接在按需物化视图上创建索引,因为它们存储在磁盘中。
性能
按需物化视图的读取性能要优于标准视图,因为前者是从磁盘中读取,而不是作为查询的一部分通过计算得出。聚合管道越复杂,要聚合的数据量越大,这种性能优势就越明显。
On MongoDB Atlas, Atlas Stream Processing can also maintain a streaming materialized view that updates continuously as source data changes. To learn more, see Streaming Materialized Views.
在 MongoDB Atlas 用户界面中创建物化视图
The example in this section uses the sample training dataset. To learn how to load the sample dataset into your MongoDB Atlas deployment, see Load Sample Data.
要在 MongoDB Atlas 用户界面中创建物化视图,请执行以下步骤:
在 MongoDB Atlas 用户界面中,转到您项目的 Clusters(集群)页面。
如果尚未显示,请从导航栏上的 Organizations 菜单中选择包含所需项目的组织。
如果尚未显示,请从导航栏的 Projects 菜单中选择您的项目。
在侧边栏中,单击 Database 标题下的 Clusters。
会显示集群页面。
添加$out 阶段
从 Select 下拉菜单中选择
$out阶段。在聚合管道中添加以下事务语法,以将管道结果写入
sample_training数据库中的myView集合:'myView' 单击 Save Documents(连接)。
$out 阶段将 aggregation pipeline 的结果写入指定集合,由该集合创建视图。要了解更多信息,请参阅 $out。
刷新集合列表以查看 myView 集合。
要了解如何在 MongoDB Atlas 用户界面中查询 myView 集合,请参阅 MongoDB Atlas 文档中的查看、过滤和排序文档。
例子
The example uses the movies collection from the sample_mflix dataset. To learn how to load sample data, see Load Sample Data.
1. 定义按需物化视图
以下 updateMovieStats 函数定义了 movieYearStats 物化视图,其中包含按年份分类的电影的计数和平均 IMDb 评级。该函数接受 startYear 参数,用于更新从该年份发布的电影的统计信息。
updateMovieStats = function(startYear) { db.movies.aggregate( [ { $match: { year: { $gte: startYear } } }, { $group: { _id: "$year", movieCount: { $sum: 1 }, avgRating: { $avg: "$imdb.rating" } } }, { $merge: { into: "movieYearStats", whenMatched: "replace" } } ] ); };
2. 执行初始运行
对于初次运行,传入开始年份,以便使 movieYearStats 填充从该年份开始的数据:
updateMovieStats(2015);
初次运行后,db.movieYearStats.find().sort( { _id: 1 } ) 返回如下文档:
{ "_id" : 2015, "movieCount" : <num>, "avgRating" : <num> } { "_id" : 2016, "movieCount" : <num>, "avgRating" : <num> } { "_id" : 2017, "movieCount" : <num>, "avgRating" : <num> }
3. 刷新物化视图
假设向 2016 的 movies 集合添加了一部新电影:
db.movies.insertOne( { title: "Grove Test Movie", year: 2016, imdb: { rating: 7.5, votes: 500 } } )
要刷新 movieYearStats 以及后续的 2016,请以 startYear 为 2016 运行该函数:
updateMovieStats(2016);
更新的 movieYearStats 反映了 movies 集合中的新电影。db.movieYearStats.find().sort( { _id: 1 } ) 返回:
{ "_id" : 2015, "movieCount" : <num>, "avgRating" : <num> } { "_id" : 2016, "movieCount" : <num>, "avgRating" : <num> } { "_id" : 2017, "movieCount" : <num>, "avgRating" : <num> }
更多信息
$merge 阶段:
可以输出到相同或不同数据库中的集合。
如果输出集合不存在,则创建一个新集合。
可将结果(插入新文档、合并文档、替换文档、保留现有文档、操作失败、使用自定义更新管道处理文档)并入现有集合。
可输出到分片集合。输入集合也可以是分片的。
请参阅 $merge 以了解:
有关
$merge和可用选项的更多信息示例:按需物化视图:初始创建
示例:On-Demand Materialized View: Update/Replace Data(按需物化视图:更新/替换数据)
示例:Only Insert New Data(仅插入新数据)