本章内容:
- 建立視圖
- 視圖特性
- 删除視圖
- 修改視圖
- 支援的操作
MongoDB視圖是可查詢的對象,視圖内容由其他集合或視圖的聚合管道定義。
MongoDB視圖内容不會持久化到磁盤。
客戶查詢視圖時,将按需計算視圖的内容。
MongoDB可授權用戶端查詢視圖的權限。
MongoDB不支援針對視圖的寫入操作。
例如,可以:
- 在員工資料集合上建立視圖,該視圖排除任何私人或隐私資訊(PII)。應用程式可以在視圖中查詢不包含任何PII的員工資料。
- 在傳感器收集資料的集合上建立一個視圖,在視圖中添加計算的字段和統計資訊。應用程式可以使用簡單的查找操作來查詢資料。
- 建立一個視圖,将分别包含庫存和訂單曆史記錄的兩個集合連接配接起來。應用程式可以查詢連接配接後的資料,而無需管理或了解底層的複雜管道。
當用戶端查詢視圖時,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階段),則此限制也适用于嵌套管道。
二、視圖特性
視圖具有以下特點:
1.隻讀(Read Only)
視圖是隻讀的;對視圖的寫操作将出錯。
下面的讀操作都支援視圖:
- db.collection.find()
- db.collection.findOne()
- db.collection.aggregate()
- db.collection.countDocuments()
- db.collection.estimatedDocumentCount()
- db.collection.count()
- db.collection.distinct()
2.索引和排序(Index Use and Sort Operations)
- 視圖使用底層集合的索引。
- 由于索引在底層的集合上。是以,在視圖上不能直接建立、删除或重建索引,也不能擷取索引清單。
- 從MongoDB 4.4開始,在視圖上可以在運作find指令時指定$natural排序。MongoDB的早期版本不支援對視圖進行自然排序。
- 視圖的底層聚合管道必須遵守100 MB的記憶體限制,才能執行阻塞排序群組操作。從MongoDB 4.4開始,可以在視圖上發出帶有allowDiskUse:true的find指令,以允許MongoDB使用臨時檔案來阻塞排序群組操作。
在MongoDB 4.4之前,僅聚合(aggregate)指令接受allowDiskUse選項。
有關阻塞排序操作記憶體限制的更多資訊,請參見排序操作。
3.投影限制(Projection Restrictions)
視圖上的find()操作不支援如下的投影(projection)運算符:
- $
- $elemMatch
- $slice
- $meta
4.視圖名不可變(Immutable Name)
已經建立的視圖,不能重命名。
5.視圖的運作(View Creation)
1. 視圖是在讀取操作期間按需計算的,并且MongoDB對視圖執行讀取操作,這是基礎聚合管道的一部分。是以,視圖不支援以下操作:
- db.collection.mapReduce(),
- $ text運算,因為聚合中的$ text運算僅對第一階段有效,
- $ geoNear管線階段。
2. 如果用于建立視圖的聚合管道禁用了_id字段,則視圖中的文檔不會顯示_id字段。
6.視圖的分片(Sharded View)
如果視圖的底層集合是分片的,則視圖也是分片的。是以,無法在$ lookup和$ graphLookup操作中為from字段指定分片視圖。
7.視圖和排序(Views and Collation)
- 在建立視圖時,可以指定預設排序規則。如果未指定排序規則,則視圖的預設排序規則為“simple”二進制比較排序規則。也就是說,視圖不會繼承集合的預設排序規則。
- 字元串的比較使用視圖的預設排序規則。要更改或覆寫視圖的預設排序規則的操作将失敗并顯示錯誤。
- 如果從另一個視圖建立視圖,則不能指定與源視圖的排序規則不同的排序規則。
- 如果涉及多個視圖的聚合,例如使用$ lookup或$ graphLookup,則這些視圖必須具有相同的排序規則。
8.公開視圖定義(Public View Definition)
查詢集合清單的操作(例如db.getCollectionInfos()和db.getCollectionNames()),在其輸出中包括視圖。
重要
視圖定義是公開的; 即db.getCollectionInfos(),并說明對視圖的操作将包括定義視圖的管道。 是以,請避免在視圖定義中直接引用敏感字段和值。
三、删除視圖
在視圖上使用db.collection.drop()方法就可以删除視圖。
四、修改視圖
可通下面方式過來修改視圖:
- 删除并重新建立視圖,或者
- collMod指令。
db.runCommand( { collMod: <collection or view>, <option1>: <value1>, <option2>: <value2> ... } )
五、支援的操作
下面的操作均支援視圖,但本文中提到的限制除外:
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() |