Docs 菜单

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: truefind命令,以允许 MongoDB 使用临时文件进行阻塞排序和分组操作。

    在 MongoDB 4.4 之前,只有aggregate命令接受allowDiskUse选项。

    提示

    另请参阅:

    有关阻塞排序操作内存限制的更多信息,请参阅排序操作。

视图上的find()操作不支持以下投影操作符:

您无法重命名视图

  • 视图是在读取操作期间按需计算的,MongoDB 将对视图执行读取操作作为底层聚合管道的一部分。 因此,视图不支持以下操作:

  • 如果用于创建视图的聚合管道抑制_id字段,则视图中的文档没有_id字段。

查询视图时,:

  • 查询 filterprojectionsortskiplimitdb.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 权限,则则该用户须具有以下额外权限:

  • find 源集合或视图上。

  • find位于pipeline中引用的任何其他集合或视图(如有)。

在数据库中具有 readWrite 内置角色的用户具有特权,可以运行列出的操作。创建具有所需角色的用户将该角色授予现有用户

给定一个包含以下文档的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" }

以下操作将创建一个包含 _idfeedback.managementdepartment 字段的 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视图执行聚合,使用$sortByCountdepartment字段进行分组,并按每个非重复部门的数量降序排序:

db.managementFeedback.aggregate([ { $sortByCount: "$department" } ] )

该操作将返回以下文档:

{ "_id" : "A", "count" : 2 }
{ "_id" : "B", "count" : 1 }

给定以下两个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视图执行聚合,使用$sortByCountitem字段进行分组,并按每个不同项目的计数降序排序:

db.orderDetails.aggregate( [ { $sortByCount: "$item" } ] )

该操作将返回以下文档:

{ "_id" : "xyz", "count" : 2 }
{ "_id" : "abc", "count" : 2 }
{ "_id" : "jkl", "count" : 1 }

给定包含以下文档的placescollection:

{ _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

尝试更改或覆盖视图的默认排序规则的操作将失败并显示错误。

提示

另请参阅:

← db.createCollection()