Docs 主页 → 开发应用程序 → MongoDB Manual
db.createView()
db.createView()
注意
以下页面将讨论视图。有关按需物化视图的讨论,请参阅
$merge
。将指定的聚合管道应用于源集合或视图后,创建一个视图。视图仅充当只读集合,且会在读取操作期间按需进行计算。必须在与源集合相同的数据库中创建视图。MongoDB 会对作为底层聚合管道其中一部分的视图执行读取操作。
视图定义
pipeline
不能包含$out
或$merge
阶段。 如果视图定义包含嵌套管道(例如视图定义包含$lookup
或$facet
阶段),则此限制也适用于嵌套管道。db.createView()
采用以下语法:db.createView(<view>, <source>, <pipeline>, <options>) 该方法接受以下参数:
范围类型说明view
字符串待创建的视图的名称。source
字符串要从中创建视图的源集合或视图的名称。该名称不是集合或视图的完整命名空间;即不包括数据库名称,并意味着与要创建的视图是同一个数据库。您必须在与源集合相同的数据库中创建视图。pipeline
阵列由聚合管道阶段组成的数组。
db.createView()
通过将指定的pipeline
应用于source
集合或视图来创建视图。视图定义
pipeline
不能包含$out
或$merge
阶段。 如果视图定义包含嵌套管道(例如视图定义包含$lookup
或$facet
阶段),则此限制也适用于嵌套管道。视图定义是公开的;即视图上的
db.getCollectionInfos()
和explain
操作将包括定义视图的管道。因此,应避免在视图定义中直接引用敏感字段和值。options
文档可选。该方法的其他选项。选项文档包含以下选项字段:
字段类型说明collation
文档可选。 指定视图的默认排序规则。
排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。
如果底层
source
是一个集合,则视图不会继承该集合的排序规则设置。如果未指定排序规则,视图的默认排序规则则为“简易”二进制比较排序规则。
如果底层
source
为其他视图,该视图则须指定相同的排序规则设置。排序规则选项的语法如下:
collation: { locale: <string>, caseLevel: <boolean>, caseFirst: <string>, strength: <int>, numericOrdering: <boolean>, alternate: <string>, maxVariable: <string>, backwards: <boolean> } 指定排序规则时,
locale
字段为必填字段;所有其他排序规则字段均为可选字段。有关字段的说明,请参阅排序规则文档。版本 3.4 中的新增功能。
db.createView()
方法封装以下create
命令操作:db.runCommand( { create: <view>, viewOn: <source>, pipeline: <pipeline>, collation: <collation> } ) 列出collection的操作(例如
db.getCollectionInfos()
和db.getCollectionNames()
)在其输出中包含视图。重要
视图定义是公开的;即视图上的
db.getCollectionInfos()
和explain
操作将包括定义视图的管道。因此,应避免在视图定义中直接引用敏感字段和值。要删除视图,请对视图执行
drop()
方法。
行为
视图表现出以下行为:
只读
视图为只读;对视图进行写入操作会出错。
以下读取操作可以支持视图:
索引使用和排序操作
视图使用底层集合的索引。
由于索引位于底层collection上,因此您无法直接在视图上创建、删除或重新构建索引,也无法获取视图上的索引列表。
从 MongoDB 4.4 开始,对视图运行 命令时,可以指定
$natural
find
排序。以前版本的 MongoDB 不支持对视图进行$natural
排序。对于阻塞排序和阻塞分组操作,视图的底层聚合管道受到 100 MB 内存限制。 从 MongoDB 4.4 开始,您可以对视图发出带有
allowDiskUse: true
的find
命令,以允许 MongoDB 使用临时文件进行阻塞排序和分组操作。在 MongoDB 4.4 之前,只有
aggregate
命令接受allowDiskUse
选项。提示
另请参阅:
有关阻塞排序操作内存限制的更多信息,请参阅排序操作。
投影限制
不可变名称
您无法重命名视图。
视图创建
视图是在读取操作期间按需计算的,MongoDB 将对视图执行读取操作作为底层聚合管道的一部分。 因此,视图不支持以下操作:
如果用于创建视图的聚合管道抑制
_id
字段,则视图中的文档没有_id
字段。
查询视图时,:
查询
filter
、projection
、sort
、skip
、limit
和db.collection.find()
的其他操作会转换为等效的聚合管道阶段。转换后的聚合管道阶段将添加到视图的聚合管道的末尾。 这不会修改视图的底层管道,该管道是在创建视图时设置的。
聚合管道优化器会重塑视图聚合管道阶段以提高性能。 这不会更改查询结果。
分片视图
如果视图的底层集合已分片,则视图也被视为已分片。 因此,您无法在$lookup
和$graphLookup
操作中为from
字段指定分片视图。
视图和排序规则
您可以在创建视图时为其指定默认排序规则。如果未指定排序规则,则视图的默认排序规则是“简单”二进制比较排序规则。也就是说,视图不会继承集合的默认排序规则。
视图上的字符串比较使用的是视图的默认排序规则。尝试更改或覆盖视图默认排序规则的操作会失败并报错。
如果从另一个视图创建视图,则无法指定与源视图不同的排序规则。
如果执行的聚合涉及多个视图,例如使用
$lookup
或$graphLookup
,则这些视图必须采用相同的排序规则。
资源锁定
版本 4.2 中进行了更改。
db.createView()
在操作期间获得指定集合或视图的独占锁。对集合的所有后续操作都必须等到db.createView()
释放该锁。 db.createView()
通常会短暂占用此锁。
创建视图需获得数据库中 system.views
集合的额外独占锁。此锁会阻止创建或修改数据库中的视图,直到命令完成。
MongoDB 4之前的版本。 2 、 db.createView()
获得了对父数据库的独占锁,阻止对数据库及其所有集合的所有操作,直到操作完成。
访问控制
如果部署强制执行身份验证,则db.createView()
要求经过身份验证的用户对数据库具有createCollection
特权。
但是,如果用户在数据库上具有 createCollection
权限,并在要创建的视图上具有 find
权限,则则该用户还须具有以下额外权限:
在数据库中具有 readWrite
内置角色的用户具有特权,可以运行列出的操作。创建具有所需角色的用户或将该角色授予现有用户
举例
从单个collection创建视图
给定一个包含以下文档的collectionsurvey
:
{ _id: 1, empNumber: "abc123", feedback: { management: 3, environment: 3 }, department: "A" } { _id: 2, empNumber: "xyz987", feedback: { management: 2, environment: 3 }, department: "B" } { _id: 3, empNumber: "ijk555", feedback: { management: 3, environment: 4 }, department: "A" }
以下操作将创建一个包含 _id
、feedback.management
和 department
字段的 managementFeedback
视图:
db.createView( "managementFeedback", "survey", [ { $project: { "management": "$feedback.management", department: 1 } } ] )
查询视图
要查询视图,可以在视图上使用db.collection.find()
:
db.managementFeedback.find()
该操作将返回以下文档:
{ "_id" : 1, "department" : "A", "management" : 3 } { "_id" : 2, "department" : "B", "management" : 2 } { "_id" : 3, "department" : "A", "management" : 3 }
在视图上执行聚合管道
以下操作对managementFeedback
视图执行聚合,使用$sortByCount
按department
字段进行分组,并按每个非重复部门的数量降序排序:
db.managementFeedback.aggregate([ { $sortByCount: "$department" } ] )
该操作将返回以下文档:
{ "_id" : "A", "count" : 2 } { "_id" : "B", "count" : 1 }
从多个collection创建视图
给定以下两个collection:
orders
collection:{ "_id" : 1, "item" : "abc", "price" : NumberDecimal("12.00"), "quantity" : 2 } { "_id" : 2, "item" : "jkl", "price" : NumberDecimal("20.00"), "quantity" : 1 } { "_id" : 3, "item" : "abc", "price" : NumberDecimal("10.95"), "quantity" : 5 } { "_id" : 4, "item" : "xyz", "price" : NumberDecimal("5.95"), "quantity" : 5 } { "_id" : 5, "item" : "xyz", "price" : NumberDecimal("5.95"), "quantity" : 10 } inventory
collection:{ "_id" : 1, "sku" : "abc", description: "product 1", "instock" : 120 } { "_id" : 2, "sku" : "def", description: "product 2", "instock" : 80 } { "_id" : 3, "sku" : "ijk", description: "product 3", "instock" : 60 } { "_id" : 4, "sku" : "jkl", description: "product 4", "instock" : 70 } { "_id" : 5, "sku" : "xyz", description: "product 5", "instock" : 200 }
以下db.createView()
示例指定了一个$lookup
阶段,以通过两个集合的联接创建视图:
db.createView ( "orderDetails", "orders", [ { $lookup: { from: "inventory", localField: "item", foreignField: "sku", as: "inventory_docs" } }, { $project: { "inventory_docs._id": 0, "inventory_docs.sku": 0 } } ] )
查询视图
要查询视图,可以在视图上使用db.collection.find()
:
db.orderDetails.find()
该操作将返回以下文档:
{ "_id" : 1, "item" : "abc", "price" : NumberDecimal("12.00"), "quantity" : 2, "inventory_docs" : [ { "description" : "product 1", "instock" : 120 } ] } { "_id" : 2, "item" : "jkl", "price" : NumberDecimal("20.00"), "quantity" : 1, "inventory_docs" : [ { "description" : "product 4", "instock" : 70 } ] } { "_id" : 3, "item" : "abc", "price" : NumberDecimal("10.95"), "quantity" : 5, "inventory_docs" : [ { "description" : "product 1", "instock" : 120 } ] } { "_id" : 4, "item" : "xyz", "price" : NumberDecimal("5.95"), "quantity" : 5, "inventory_docs" : [ { "description" : "product 5", "instock" : 200 } ] } { "_id" : 5, "item" : "xyz", "price" : NumberDecimal("5.95"), "quantity" : 10, "inventory_docs" : [ { "description" : "product 5", "instock" : 200 } ] }
在视图上执行聚合管道
以下操作对orderDetails
视图执行聚合,使用$sortByCount
按item
字段进行分组,并按每个不同项目的计数降序排序:
db.orderDetails.aggregate( [ { $sortByCount: "$item" } ] )
该操作将返回以下文档:
{ "_id" : "xyz", "count" : 2 } { "_id" : "abc", "count" : 2 } { "_id" : "jkl", "count" : 1 }
创建具有默认排序规则的视图
给定包含以下文档的places
collection:
{ _id: 1, category: "café" } { _id: 2, category: "cafe" } { _id: 3, category: "cafE" }
以下操作创建一个视图,并在视图级别指定排序规则:
db.createView( "placesView", "places", [ { $project: { category: 1 } } ], { collation: { locale: "fr", strength: 1 } } )
视图上的字符串比较使用视图的默认排序规则。例如,以下操作会使用视图的排序规则:
db.placesView.count( { category: "cafe" } )
该操作会返回 3
。
尝试更改或覆盖视图的默认排序规则的操作将失败并显示错误。