db.createView()
db.createView()
注意
以下页面将讨论视图。 有关按需物化视图的讨论,请参阅
$merge
。将指定的聚合管道应用于源集合或视图后,创建一个视图。视图仅充当只读集合,且会在读取操作期间按需进行计算。必须在与源集合相同的数据库中创建视图。MongoDB 会对作为底层聚合管道其中一部分的视图执行读取操作。
视图定义
pipeline
不能包含$out
或$merge
阶段。 如果视图定义包含嵌套管道(例如视图定义包含$lookup
或$facet
阶段),则此限制也适用于嵌套管道。
兼容性
此方法可用于以下环境中托管的部署:
MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务
注意
所有 MongoDB Atlas 集群都支持此命令。有关 Atlas 对所有命令的支持的信息,请参阅不支持的命令。
MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本
MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本
语法
db.createView
通过以下语法实现:
db.createView(<view>, <source>, <pipeline>, <options>)
该方法接受以下参数:
Parameter | 类型 | 说明 |
---|---|---|
| 字符串 | 待创建的视图的名称。 |
| 字符串 | 要从中创建视图的源集合或视图的名称。该名称不是集合或视图的完整命名空间;即不包括数据库名称,并意味着与要创建的视图是同一个数据库。您必须在与源集合相同的数据库中创建视图。 |
| 阵列 | 由聚合管道阶段组成的大量。 视图定义 视图定义是公开的;即视图上的 |
| 文档 | 可选。 该方法的其他选项。 |
选项文档包含以下选项字段:
字段 | 类型 | 说明 | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| 文档 | 可选。 指定视图的默认排序规则。 排序规则允许用户为字符串比较指定特定于语言的规则,例如字母大小写和重音符号规则。 如果底层 如果未指定排序规则,视图的默认排序规则则为“简易”二进制比较排序规则。 如果底层 排序规则选项的语法如下:
指定排序规则时, 版本 3.4 中的新增功能。 |
db.createView()
方法封装以下create
命令操作:
db.runCommand( { create: <view>, viewOn: <source>, pipeline: <pipeline>, collation: <collation> } )
列出集合的操作(例如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()
获得了对父数据库的独占锁,在操作完成之前阻塞对该数据库及其所有集合执行任何操作。
访问控制
要创建视图,您必须对创建视图的数据库具有
createCollection
权限。此外,如果您对要创建的视图的命名空间拥有find
权限,则还必须对以下资源拥有find
权限:从中创建新视图的源集合或视图。
要查询视图,您必须拥有视图命名空间的
find
权限。您不需要对视图管道中引用的源集合或任何命名空间具有find
权限。
readWrite
对数据库具有内置 角色的用户拥有运行所列操作所需的特权。要授予所需权限,请执行以下任一操作:
示例
从单个集合创建视图
给定一个包含以下文档的集合survey
:
{ _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 }
从多个集合创建视图
给定以下两个集合:
orders
集合:{ "_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
集合:{ "_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
集合:
{ _id: 1, category: "café" } { _id: 2, category: "cafe" } { _id: 3, category: "cafE" }
以下操作创建一个视图,并在视图级别指定排序规则:
db.createView( "placesView", "places", [ { $project: { category: 1 } } ], { collation: { locale: "fr", strength: 1 } } )
视图上的string比较使用视图的默认排序规则。 示例,以下操作使用视图的排序规则:
db.placesView.count( { category: "cafe" } )
该操作会返回 3
。
尝试更改或覆盖视图的默认排序规则的操作将失败并显示错误。