天天看点

mongodb——视图

作者:老葛说码

MongoDB视图是一个可查询的对象,其内容由其他集合或视图上的聚合管道定义。MongoDB不会将视图内容持久化到磁盘。当客户端查询视图时,MongoDB可以要求客户端拥有查询视图的权限。MongoDB不支持针对视图的写操作。

例如,您可以:

  • 创建一个关于员工数据集合的视图,以排除exclude任何私人或个人信息(PII)。应用程序可以在视图中查询不包含任何PII的员工数据。
  • 在收集的传感器数据集合上创建一个视图,以添加add计算字段和度量。应用程序可以使用简单的查找操作来查询数据。
  • 创建一个连接两个集合的视图,这两个集合分别包含库存和订单历史记录。应用程序可以在不管理或不了解底层复杂管道的情况下查询连接的数据。

当客户端查询视图时,MongoDB将客户端查询附加到底层管道,并将组合管道的结果返回给客户端。MongoDB可能会对合并后的管道进行聚合管道优化。

接下来讨论视图。有关按需物化视图的讨论,请参阅按需物化视图。

创建视图

要创建或定义视图,请执行以下操作:

  • 使用db.createCollection()方法或create命令:
db.createCollection(
  "<viewName>",
  {
    "viewOn" : "<source>",
    "pipeline" : [<pipeline>],
    "collation" : { <collation> }
  }
)           
  • 使用db.createView()方法:
db.createView(
  "<viewName>",
  "<source>",
  [<pipeline>],
  {
    "collation" : { <collation> }
  }
)           

-您必须在与源集合相同的数据库中创建视图。

视图定义管道不能包括$out或$merge阶段。如果视图定义包括嵌套管道(例如,视图定义包括$lookup或$facet-stage),则此限制也适用于嵌套管道。

行为

视图表现出以下行为:

只读

视图是只读的;对视图的写入操作将出错。

以下读取操作可以支持视图:

  • db.collection.find()
  • db.collection.findOne()
  • db.collection.aggregate()
  • db.collection.countDocuments()
  • db.collection.estimatedDocumentCount()
  • db.collection.count()
  • db.collection.distinct()

索引使用和排序操作

  • 视图使用基础集合的索引。
  • 由于索引位于基础集合上,因此无法直接在视图上创建、删除或重新生成索引,也无法获取视图上的索引列表。
  • 从MongoDB 4.4开始,您可以在视图上运行find命令时指定$natural排序。MongoDB的早期版本不支持对视图进行$natural排序。
  • 视图的底层聚合管道受阻塞排序和阻塞组操作的100兆字节内存限制。从MongoDB 4.4开始,您可以在视图上发出一个带有allowDiskUse:true的find命令,允许MongoDB使用临时文件来阻塞排序和分组操作。
  • 在MongoDB 4.4之前,只有aggregate命令接受allowDiskUse选项。

另请参阅:

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

投影限制

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

  • $
  • $elemMatch
  • $slice
  • $meta

不可变名称

不能重命名视图。

视图创建

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

  • db.collection.mapReduce()
  • $text 运算符,因为聚合中的$text运算仅对第一阶段有效
  • $geo 管道阶段

如果用于创建视图的聚合管道取消显示_id字段,则视图中的文档没有_id字段。

查询视图时,将显示:

  • db.collection.find()的查询筛选、投影、排序、跳过、限制和其他操作被转换为等效的聚合管道阶段。
  • 转换后的聚合管道阶段将添加到视图的聚合管道的末尾。这不会修改视图的基础管道,该管道是在创建视图时设置的。
  • 聚合管道优化器重新调整视图聚合管道阶段以提高性能。这不会更改查询结果。

分片视图

如果视图的基础集合是分片的,则视图被视为分片的。因此,不能在$lookup和$graphLookup操作中为from字段指定分片视图。

视图和排序

  • 您可以在创建时为视图指定默认排序规则。如果未指定排序规则,则视图的默认排序规则是“简单”二进制比较排序规则。也就是说,视图不会继承集合的默认排序规则。
  • 视图上的字符串比较使用视图的默认排序规则。试图更改或覆盖视图的默认排序规则的操作将失败,并出现错误。
  • 如果从另一个视图创建视图,则不能指定与源视图的排序规则不同的排序规则。
  • 如果执行涉及多个视图的聚合,例如使用$lookup或$graphLookup,则视图必须具有相同的排序规则。

公共视图定义

列出集合的操作,如db.getCollectionInfos()和db.getCollectionNames(),在其输出中包含视图。

视图定义是公开的;即db.getCollectionInfos(),并解释对视图的操作将包括定义视图的管道。因此,请避免直接引用视图定义中的敏感字段和值。

删除视图

要删除视图,请对视图使用db.collection.drop()方法。

修改视图

您可以通过删除并重新创建视图或使用collMod命令来修改视图。

支持的操作

以下操作为视图提供支持,但本页中提到的限制除外:

Commands Methods
create

db.createCollection()

db.createView()

collMod

db.getCollection()

db.getCollectionInfos()

db.getCollectionNames()

find

distinct

count

db.collection.aggregate()

db.collection.find()

db.collection.findOne()

db.collection.countDocuments()

db.collection.estimatedDocumentCount()

db.collection.count()

db.collection.distinct()