MongoDBビューはクエリ可能なオブジェクトであり、その内容は他のコレクションまたはビューの 集計パイプラインによって定義されます。MongoDB はビューの内容をディスクに永続化しません。 ビューのコンテンツは、クライアントがビューをクエリしたときにオンデマンドで計算されます。MongoDB、クライアントがビューをクエリする権限を持っていることを要求できます。MongoDB はビューに対する書込み操作をサポートしていません。
例としては次のことができます。
- 従業員データのコレクションのビューを作成し、 - excludeの個人情報または個人情報(PII)を表示します。 アプリケーションは、 PII を含まない従業員データのビューを照会できます。
- 計算されたフィールドとメトリクスを - addするには、収集されたセンサーデータのコレクションにビューを作成します。アプリケーションは単純な検索操作を使用してデータをクエリできます。
- 在庫と注文履歴をそれぞれ含む - joinsのビューを作成します。 アプリケーションは、基盤となる複雑なパイプラインを管理したり理解したりしなくても、結合されたデータをクエリできます。
MongoDB Atlas でホストされている配置向け に UI でマテリアライズドビューを作成 できます。
クライアントが ビュー をクエリすると、MongoDB はクライアント クエリを基礎となるパイプラインに追加し、その結合されたパイプラインの結果をクライアントに返します。 MongoDB は、結合されたパイプラインに集計パイプラインの最適化を適用する場合があります。
注意
次のページではビューについて説明します。 オンデマンドのマテリアライズドビューについて詳しくは、「オンデマンドのマテリアライズドビュー 」を参照してください。
ビューの作成
ビューを作成または定義するには、次の手順に従います。
- db.createCollection()メソッドまたは- createコマンドを使用します。- db.createCollection( - "<viewName>", - { - "viewOn" : "<source>", - "pipeline" : [<pipeline>], - "collation" : { <collation> } - } - ) 
- db.createView()メソッドを使用します。- db.createView( - "<viewName>", - "<source>", - [<pipeline>], - { - "collation" : { <collation> } - } - ) 
注意
- ソース コレクションと同じデータベースにビューを作成する必要があります。
警告
MongoDB サーバーがクラッシュするため、 system.profileという名前の時系列コレクションまたはビューを作成しないでください。
動作
ビューは、次の動作を示します。
読み取り専用
ビューは読み取り専用です。ビューに対する書込み操作はエラーになります。
次の読み取り操作ではビューをサポートできます。
インデックス使用とソート操作
- ビューでは、基になるコレクションのインデックスが使用されます。 
- インデックスは基礎となるコレクションにあるため、ビューでインデックスを直接作成、削除、再構築したり、ビューでインデックスのリストを取得したりすることはできません。 
- MongoDB 4.4 以降では、ビューで コマンドを実行するときに - $natural- findの並べ替えを指定できます。MongoDB の以前のバージョンでは、ビューでの- $naturalソートはサポートされていません。
- ビューの基盤となる集計パイプラインには、ブロッキングソート操作とブロッキンググループ操作のメモリ制限が 100 MB に制限されます。 MongoDB 4.4 以降では、 ビューで - allowDiskUse: trueを使用して- findコマンドを発行し、MongoDB がブロッキングソートとグループ操作に一時ファイルを使用できるようにします。- MongoDB 4.4 より前では、 - aggregateコマンドのみが- allowDiskUseオプションを受け入れていました。- Tip- ブロッキングソート操作のメモリ制限の詳細については、「ソート操作 」を参照してください。 
プロジェクションの制限
不変名
ビューの名前を変更することはできません。
ビューの作成
- ビューは読み取り操作中にオンデマンドで計算され、MongoDB は基礎となる集計パイプラインの一部としてビューに対して読み取り操作を実行します。 そのため、ビューでは次のような操作はサポートされていません。 
- ビューの作成に使用される集計パイプラインが - _idフィールドを抑制している場合、ビュー内のドキュメントには- _idフィールドは表示されません。
ビューをクエリすると、
- クエリ - filter、- projection、- sort、- skip、- limit- db.collection.find()、およびその他の操作は、同等の集計パイプライン ステージに変換されます。
- 変換された集計パイプライン ステージは、ビューの集計パイプラインの末尾に追加されます。 これによって、ビューの作成時に設定されるビューの基礎となるパイプラインは変更されません。 
- 集計パイプライン オプティマイザーは、ビュー集計パイプライン ステージを再形成してパフォーマンスを向上させます。 これによってクエリ結果は変更されません。 
シャードビュー
ビューは、基になるコレクションがシャーディングされている場合、シャーディングされたと見なされます。 そのため、 $lookup操作と$graphLookup操作ではfromフィールドのシャーディングされたビューを指定できません。
ビューと照合
- 作成時にビューのデフォルトの照合方法を指定できます。照合方法が指定されていない場合、ビューのデフォルトの照合には「単純な」バイナリ比較照合子が使用されます。つまり、ビューはコレクションのデフォルトの照合方法を継承しません。 
- ビューでの文字列比較では、ビューのデフォルトの照合方法が使用されます。ビューのデフォルトの照合方法を変更または上書きしようとする操作は、エラーとなり、失敗します。 
- 別のビューからビューを作成する場合、ソース ビューの照合方法と異なる照合方法を指定することはできません。 
- 複数のビューが関わる集計( - $lookupや- $graphLookupなど)が実行される場合、それらのビューには同じ照合が含まれる必要があります。
スナップショットの分離
ビューはコレクション変更のタイムスタンプを維持せず、ポイントインタイムまたはスナップショット読み取りの分離をサポートしていません。
パブリックビューの定義
コレクションを一覧表示する操作db.getCollectionInfos()やdb.getCollectionNames()など)では、出力にビューが含まれます。
重要
ビュー定義はパブリックです。つまり、ビューに対する db.getCollectionInfos() および explain操作には、ビューを定義するパイプラインが含まれます。そのため、ビュー定義で機密性の高いフィールドと値を直接参照することは避けてください。
ビューをドロップする
ビューを削除するには、ビューでdb.collection.drop()メソッドを使用します。
ビューを変更する
ビューを変更するには、ビューを削除して再作成するか、 collModコマンドを使用します。
サポートされている操作
次の操作では、このページに記載されている制限を除き、ビューのサポートを提供します。
| コマンド | メソッド | 
|---|---|
例
次の例で使用するstudentsコレクションを作成します。
db.students.insertMany( [    { sID: 22001, name: "Alex", year: 1, score: 4.0 },    { sID: 21001, name: "bernie", year: 2, score: 3.7 },    { sID: 20010, name: "Chris", year: 3, score: 2.5 },    { sID: 22021, name: "Drew", year: 1, score: 3.2 },    { sID: 17301, name: "harley", year: 6, score: 3.1 },    { sID: 21022, name: "Farmer", year: 1, score: 2.2 },    { sID: 20020, name: "george", year: 3, score: 2.8 },    { sID: 18020, name: "Harley", year: 5, score: 2.8 }, ] ) 
db.createView() を使用してビューを作成する
db.createView() を使用して、1 年生に限定したビューを作成します。
db.createView(    "firstYears",    "students",    [ { $match: { year: 1 } } ] ) 
この例では、次のことが行われます。
- firstYearsは、新しいビューの名前です。
- studentsは、ビューの基になっているコレクションです。
- $matchは、- studentsコレクション内の 1 年生に一致する集計式です。
この例では、ビューをクエリしています。
db.firstYears.find({}, { _id: 0 } ) 
以下の出力には、1年生に関するデータを含むドキュメントのみが含まれています。{ _id: 0 } プロジェクションは、出力内の _id フィールドを抑制します。
[   { sID: 22001, name: 'Alex', year: 1, score: 4 },   { sID: 22021, name: 'Drew', year: 1, score: 3.2 },   { sID: 21022, name: 'Farmer', year: 1, score: 2.2 } ] 
db.createCollection() を使用してビューを作成する
db.createCollection() メソッドを使用すると、特定のオプションを持つコレクションまたはビューを作成できます。
次の例では、graduateStudents ビューを作成しています。ビューには、$match ステージで選択されたドキュメントのみが含まれます。任意の照合設定によって並べ替え順序が決まります。
db.createCollection(    "graduateStudents",    {       viewOn: "students",       pipeline: [ { $match: { $expr: { $gt: [ "$year", 4 ] } } } ],       collation: { locale: "en", caseFirst: "upper" }    } ) 
次の例では、ビューをクエリします。$unset ステージでは、わかりやすくするために出力から _id フィールドが削除されます。
db.graduateStudents.aggregate(    [       { $sort: { name: 1 } },       { $unset: [ "_id" ] }    ] ) 
出力がソートされるとき、 $sort ステージは照合順序を使用して大文字を小文字より先にソートします。
[   { sID: 18020, name: 'Harley', year: 5, score: 2.8 },   { sID: 17301, name: 'harley', year: 6, score: 3.1 } ] 
ビューを使用して 2 つのコレクションを結合
多くの場合、 $lookupを使用して 2 つのコレクションのビューを作成し、そのビューに対してクエリを実行すると便利です。 アプリケーションは、複雑なパイプラインを構築または維持することなく、ビューに対してクエリを実行できます。
inventory とorders の 2 つのサンプル コレクションを作成します。
db.inventory.insertMany( [    { prodId: 100, price: 20, quantity: 125 },    { prodId: 101, price: 10, quantity: 234 },    { prodId: 102, price: 15, quantity: 432 },    { prodId: 103, price: 17, quantity: 320 } ] ) db.orders.insertMany( [    { orderID: 201, custid: 301, prodId: 100, numPurchased: 20 },    { orderID: 202, custid: 302, prodId: 101, numPurchased: 10 },    { orderID: 203, custid: 303, prodId: 102, numPurchased: 5 },    { orderID: 204, custid: 303, prodId: 103, numPurchased: 15 },    { orderID: 205, custid: 303, prodId: 103, numPurchased: 20 },    { orderID: 206, custid: 302, prodId: 102, numPurchased: 1 },    { orderID: 207, custid: 302, prodId: 101, numPurchased: 5 },    { orderID: 208, custid: 301, prodId: 100, numPurchased: 10 },    { orderID: 209, custid: 303, prodId: 103, numPurchased: 30 } ] ) 
各コレクションの要素を組み合わせたビューを作成します。
db.createView( "sales", "orders", [    {       $lookup:          {             from: "inventory",             localField: "prodId",             foreignField: "prodId",             as: "inventoryDocs"          }    },    {       $project:          {            _id: 0,            prodId: 1,            orderId: 1,            numPurchased: 1,            price: "$inventoryDocs.price"          }    },       { $unwind: "$price" } ] ) 
この例では、次のことが行われます。
- db.createView()は- salesビューを作成します。
- salesビューは- ordersコレクションに基づいています。
- $lookupステージでは、- ordersコレクションの- prodIdフィールドを使用して、一致する- prodIdフィールドを持つ- inventoryコレクション内のドキュメントを「結合」します。
- 一致するドキュメントは、 - inventoryDocsフィールドに配列として追加されます。
- $projectステージでは、使用可能なフィールドのサブセットが選択されます。
- $unwindステージでは、- priceフィールドを配列からスカラー値に変換します。
sales ビューのドキュメントは以下のとおりです。
{ prodId: 100, numPurchased: 20, price: 20 }, { prodId: 101, numPurchased: 10, price: 10 }, { prodId: 102, numPurchased: 5, price: 15 }, { prodId: 103, numPurchased: 15, price: 17 }, { prodId: 103, numPurchased: 20, price: 17 }, { prodId: 102, numPurchased: 1, price: 15 }, { prodId: 101, numPurchased: 5, price: 10 }, { prodId: 100, numPurchased: 10, price: 20 }, { prodId: 103, numPurchased: 30, price: 17 } 
各製品の合計販売金額を見つけるには、ビューをクエリします。
db.sales.aggregate( [    {       $group:          {             _id: "$prodId",             amountSold: { $sum: { $multiply: [ "$price", "$numPurchased" ] } }          }    } ] ) 
出力は次のとおりです。
[   { _id: 100, amountSold: 600 },   { _id: 103, amountSold: 1105 },   { _id: 101, amountSold: 150 },   { _id: 102, amountSold: 90 } ]