Docs Menu

Docs HomeDevelop ApplicationsMongoDB Manual

Views

On this page

  • Create View
  • Behavior
  • Drop a View
  • Modify a View
  • Supported Operations
  • Examples

A MongoDB view is a queryable object whose contents are defined by an aggregation pipeline on other collections or views. MongoDB does not persist the view contents to disk. A view's content is computed on-demand when a client queries the view. MongoDB can require clients to have permission to query the view. MongoDB does not support write operations against views.

For example, you can:

When clients query a view, MongoDB appends the client query to the underlying pipeline and returns the results of that combined pipeline to the client. MongoDB may apply aggregation pipeline optimizations to the combined pipeline.

Note

The following page discusses views. For discussion of on-demand materialized views, see On-Demand Materialized Views instead.

To create or define a view:

  • Use the db.createCollection() method or the create command:

    db.createCollection(
    "<viewName>",
    {
    "viewOn" : "<source>",
    "pipeline" : [<pipeline>],
    "collation" : { <collation> }
    }
    )
  • Use the db.createView() method:

    db.createView(
    "<viewName>",
    "<source>",
    [<pipeline>],
    {
    "collation" : { <collation> }
    }
    )

Note

- You must create views in the same database as the source collection.

  • The view definition pipeline cannot include the $out or the $merge stage. If the view definition includes nested pipeline (e.g. the view definition includes $lookup or $facet stage), this restriction applies to the nested pipelines as well.

Views exhibit the following behavior:

Views are read-only; write operations on views will error.

The following read operations can support views:

  • Views use the indexes of the underlying collection.

  • As the indexes are on the underlying collection, you cannot create, drop or re-build indexes on the view directly nor get a list of indexes on the view.

  • Starting in MongoDB 4.4, you can specify a $natural sort when running a find command on a view. Prior versions of MongoDB do not support $natural sort on views.

  • The view's underlying aggregation pipeline is subject to the 100 megabyte memory limit for blocking sort and blocking group operations. Starting in MongoDB 4.4, you can issue a find command with allowDiskUse: true on the view to allow MongoDB to use temporary files for blocking sort and group operations.

    Prior to MongoDB 4.4, only the aggregate command accepted the allowDiskUse option.

    Tip

    See also:

    For more information on blocking sort operation memory limits, see Sort Operations.

find() operations on views do not support the following projection operators:

You cannot rename views.

  • Views are computed on demand during read operations, and MongoDB executes read operations on views as part of the underlying aggregation pipeline. As such, views do not support operations such as:

  • If the aggregation pipeline used to create the view suppresses the _id field, documents in the view do not have the _id field.

When you query a view, the:

Views are considered sharded if their underlying collection is sharded. As such, you cannot specify a sharded view for the from field in $lookup and $graphLookup operations.

  • You can specify a default collation for a view at creation time. If no collation is specified, the view's default collation is the "simple" binary comparison collator. That is, the view does not inherit the collection's default collation.

  • String comparisons on the view use the view's default collation. An operation that attempts to change or override a view's default collation will fail with an error.

  • If creating a view from another view, you cannot specify a collation that differs from the source view's collation.

  • If performing an aggregation that involves multiple views, such as with $lookup or $graphLookup, the views must have the same collation.

Operations that lists collections, such as db.getCollectionInfos() and db.getCollectionNames(), include views in their outputs.

Important

The view definition is public; i.e. db.getCollectionInfos() and explain operations on the view will include the pipeline that defines the view. As such, avoid referring directly to sensitive fields and values in view definitions.

To remove a view, use the db.collection.drop() method on the view.

You can modify a view either by dropping and recreating the view or using the collMod command.

The following operations provide support for views, except for the restrictions mentioned in this page:

Commands
Methods
create

Create the students collection to use in the following examples:

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 },
] )

Use db.createView() to create a view that is limited to first year students:

db.createView(
"firstYears",
"students",
[ { $match: { year: 1 } } ]
)

In the example:

  • firstYears is the name of the new view.

  • students is the collection the view is based on.

  • $match is an aggregation expression that matches first year students in the students collection.

This example queries the view:

db.firstYears.find({}, { _id: 0 } )

The following output only contains the documents with data on first year students. The { _id: 0 } projection suppresses the _id field in the output.

[
{ 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 }
]

The db.createCollection() method allows you to create a collection or a view with specific options.

The following example creates a graduateStudents view. The view only contains documents selected by the $match stage. The optional collation setting determines the sort order.

db.createCollection(
"graduateStudents",
{
viewOn: "students",
pipeline: [ { $match: { $expr: { $gt: [ "$year", 4 ] } } } ],
collation: { locale: "en", caseFirst: "upper" }
}
)

The following example queries the view. The $unset stage removes the _id field from the output for clarity.

db.graduateStudents.aggregate(
[
{ $sort: { name: 1 } },
{ $unset: [ "_id" ] }
]
)

When the output is sorted, the $sort stage uses the collation ordering to sort uppercase letters before lowercase letters.

[
{ sID: 18020, name: 'Harley', year: 5, score: 2.8 },
{ sID: 17301, name: 'harley', year: 6, score: 3.1 }
]

It is often convenient to use $lookup to create a view over two collections and then run queries against the view. Applications can query the view without having to construct or maintain complex pipelines.

Create two sample collections, inventory and orders:

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 }
] )

Create a view that combines elements from each collection:

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" }
] )

In the example:

  • db.createView() creates the sales view.

  • The sales view is based on the orders collection.

  • The $lookup stage uses the prodId field in the orders collection to "join" documents in the inventory collection that have matching prodId fields.

  • The matching documents are added as an array in the inventoryDocs field.

  • The $project stage selects a subset of the available fields.

  • The $unwind stage converts the price field from an array to a scalar value.

The documents in the sales view are:

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

To find the total amount sold of each product, query the view:

db.sales.aggregate( [
{
$group:
{
_id: "$prodId",
amountSold: { $sum: { $multiply: [ "$price", "$numPurchased" ] } }
}
}
] )

The output is:

[
{ _id: 100, amountSold: 600 },
{ _id: 103, amountSold: 1105 },
{ _id: 101, amountSold: 150 },
{ _id: 102, amountSold: 90 }
]
←  Databases and CollectionsOn-Demand Materialized Views →