创建和查询视图
在此页面上
要创建视图,请使用以下方法之一:
要在 MongoDB Atlas 用户界面中创建视图,您必须使用物化视图。如需了解详情,请参阅在 MongoDB Atlas 用户界面中创建物化视图。
重要
视图名称包含在集合列表输出中
列出集合的操作,例如 db.getCollectionInfos()
和 db.getCollectionNames()
,在其输出中包含视图。
视图定义是公开的;即视图上的 db.getCollectionInfos()
和 explain
操作将包括定义视图的管道。因此,应避免在视图定义中直接引用敏感字段和值。
db.createCollection()
语法
db.createCollection( "<viewName>", { "viewOn" : "<source>", "pipeline" : [<pipeline>], "collation" : { <collation> } } )
db.createView()
语法
db.createView( "<viewName>", "<source>", [<pipeline>], { "collation" : { <collation> } } )
限制
您必须在与源集合相同的数据库中创建视图。
视图定义
pipeline
不能包含$out
或$merge
阶段。这一限制也适用于嵌入式管道,例如在$lookup
或$facet
阶段中使用的管道。视图一旦创建便无法重命名。
不支持的操作
某些操作不适用于视图:
$text
操作符,因为聚合中的$text
只对第一阶段有效。正在重新命名视图。
有关详细信息,请参阅视图支持的操作。
例子
此示例使用学生数据填充collection,并创建视图来查询数据。
填充集合
创建一个用于此示例的 students
集合:
db.students.insertMany( [ { sID: 22001, name: "Alex", year: 1, score: 4.0 }, { sID: 21001, name: "bernie", year: 2, score: 3.7 }, { sID: 20010, name: "Chris", year: 3, score: 2.5 }, { sID: 22021, name: "Drew", year: 1, score: 3.2 }, { sID: 17301, name: "harley", year: 6, score: 3.1 }, { sID: 21022, name: "Farmer", year: 1, score: 2.2 }, { sID: 20020, name: "george", year: 3, score: 2.8 }, { sID: 18020, name: "Harley", year: 5, score: 2.8 }, ] )
使用 db.createView() 创建视图
使用 db.createView()
创建仅限一年级学生的视图:
db.createView( "firstYears", "students", [ { $match: { year: 1 } } ] )
在示例中:
firstYears
是新视图的名称。students
是视图所依据的集合。$match
是一个聚合表达式,它会与students
集合中的一年级学生进行匹配。
查询视图
此示例查询视图:
db.firstYears.find({}, { _id: 0 } )
以下输出仅包含具有一年级学生数据的文档。{ _id: 0 }
投影会抑制输出中的 _id
字段。
[ { sID: 22001, name: 'Alex', year: 1, score: 4 }, { sID: 22021, name: 'Drew', year: 1, score: 3.2 }, { sID: 21022, name: 'Farmer', year: 1, score: 2.2 } ]
使用 db.createCollection() 创建视图
使用 db.createCollection()
方法可以创建具有特定选项的集合或视图。
以下示例将创建一个 graduateStudents
视图。该视图仅包含由 $match
阶段选择的文档。排序规则设置(可选)决定了排序顺序。
db.createCollection( "graduateStudents", { viewOn: "students", pipeline: [ { $match: { $expr: { $gt: [ "$year", 4 ] } } } ], collation: { locale: "en", caseFirst: "upper" } } )
注意
排序规则行为
您可以在创建视图时为其指定默认排序规则。如果未指定排序规则,则视图的默认排序规则是“简单”二进制比较排序规则。也就是说,视图不会继承集合的默认排序规则。
视图上的字符串比较使用的是视图的默认排序规则。尝试更改或覆盖视图默认排序规则的操作会失败并报错。
如果从另一个视图创建视图,则无法指定与源视图不同的排序规则。
如果执行的聚合涉及多个视图,例如使用
$lookup
或$graphLookup
,则这些视图必须采用相同的排序规则。
查询视图
以下示例将查询该视图。为清晰起见,$unset
阶段会从输出中删除 _id
字段。
db.graduateStudents.aggregate( [ { $sort: { name: 1 } }, { $unset: [ "_id" ] } ] )
对输出进行排序时,$sort
阶段使用排序规则对小写字母前的大写字母进行排序。
[ { sID: 18020, name: 'Harley', year: 5, score: 2.8 }, { sID: 17301, name: 'harley', year: 6, score: 3.1 } ]
行为
以下各部分介绍了视图创建和查询的行为。
聚合优化
当您查询视图时:
查询
filter
、projection
、sort
、skip
、limit
和db.collection.find()
的其他操作会转换为等效的聚合管道阶段。MongoDB 将客户端查询附加到底层管道,并将组合管道的结果返回给客户端。MongoDB 可能会将聚合管道优化应用于组合管道。
聚合管道优化器会重塑视图聚合管道阶段以提高性能。 优化不会更改查询结果。
资源锁定
db.createView()
在操作期间获得指定集合或视图的独占锁。对集合的所有后续操作都必须等到 db.createView()
释放该锁为止。db.createView()
通常会短暂占用该锁。
创建视图需获得数据库中 system.views
集合的额外独占锁。此锁会阻止创建或修改数据库中的视图,直到命令完成。