Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs Menu
Docs Home
/ /
Bases de datos y colecciones

Vistas

Una vista de MongoDB es un objeto consultable cuyos contenidos están definidos por un pipeline de agregación en otras colecciones o vistas. MongoDB no guarda el contenido de la vista en el disco. El contenido de una vista se calcula a demanda cuando un cliente consulta la vista. MongoDB puede requerir que los clientes tengan permiso para query la vista. MongoDB no admite operaciones de escritura en vistas.

Por ejemplo, puedes:

Puedes crear vistas materializadas en la interfaz de usuario para despliegues alojados en MongoDB Atlas.

Cuando los clientes query una vista, MongoDB añade la query del cliente a la pipeline subyacente y devuelve los resultados de esa pipeline combinada al cliente. MongoDB puede aplicar pipeline de agregación a la pipeline combinada.

Nota

La siguiente página discute las vistas. Para la discusión de vistas materializadas on-demand, consulta On-Demand Materialized Views en su lugar.

Para crear o definir una vista:

  • Utilice el método db.createCollection() o el comando create:

    db.createCollection(
    "<viewName>",
    {
    "viewOn" : "<source>",
    "pipeline" : [<pipeline>],
    "collation" : { <collation> }
    }
    )
  • Utiliza el método db.createView():

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

Nota

- Debe crear vistas en la misma base de datos que la colección de origen.

  • La definición de la vista pipeline no puede incluir la etapa $out o $merge. Si la definición del vista incluye una pipeline anidada (por ejemplo, la definición del vista incluye la etapa $lookup o $facet), esta restricción también se aplica a las pipelines anidadas.

Advertencia

No intente crear una colección de series de tiempo o una vista con el nombre system.profile porque el servidor de MongoDB se bloqueará.

Las vistas presentan el siguiente comportamiento:

Las vistas son de solo lectura; las operaciones de guardar en vistas darán error.

Las siguientes operaciones de lectura pueden soportar vistas:

  • Las vistas usan los índices de la colección subyacente.

  • Dado que los índices están en la colección subyacente, no se pueden crear, descartar o reconstruir índices en la vista directamente ni obtener una lista de índices en la vista.

  • A partir de MongoDB 4.4, puedes especificar un ordenamiento $natural al ejecutar un comando find en una vista. Las versiones anteriores de MongoDB no admiten el ordenamiento $natural en vistas.

  • La pipeline de agregación subyacente de la vista está sujeta al límite de memoria de 100 megabytes para las operaciones de ordenamiento bloqueante y grupo por bloqueo. A partir de MongoDB 4.4, puede emitir un comando find con allowDiskUse: true sobre la vista para permitir que MongoDB utilice archivos temporales para las operaciones de ordenamiento y agrupación bloqueantes.

    Antes de MongoDB 4.4, sólo el comando aggregate aceptaba la opción allowDiskUse.

    Tip

    Para más información sobre los límites de memoria para la operación de ordenamiento bloqueante, consulta Operaciones de ordenamiento.

find() Las operaciones en vistas no admiten los siguientes operadores de proyección:

No puede cambiar el nombre de vistas.

  • Las vistas se calculan a demanda durante las operaciones de lectura y MongoDB ejecuta operaciones de lectura en ellas como parte del pipeline de agregación subyacente. Como tal, las vistas no soportan operaciones tales como:

  • Si el pipeline de agregación utilizado para crear la vista suprime el campo _id, los documentos en la vista no tienen el campo _id.

Cuando consultas una vista, el:

Las vistas se consideran particionadas si su colección subyacente está particionada. Por lo tanto, no puedes especificar una vista fragmentada para el campo from en las operaciones $lookup y $graphLookup.

  • Puede especificar una intercalación por defecto para una vista en el momento que la crea. Si no se especifica ninguna intercalación, la intercalación por defecto de la vista es la intercalación de comparación binaria "simple". Es decir, la vista no hereda la intercalación por defecto de la colección.

  • Las comparaciones de string en la vista utilizan la intercalación por defecto de la vista. Una operación que intente cambiar o sobrescribir la intercalación por defecto de una vista fallará con un error.

  • Si crea una vista a partir de otra vista, no puede especificar una intercalación que difiera de la intercalación de la vista de origen.

  • Si realiza una agregación que implique varias vistas, como con $lookup o $graphLookup, las vistas deben tener la misma intercalación.

Las vistas no mantienen marcas de tiempo de los cambios en la colección ni admiten el aislamiento de lectura en un punto específico o aislamiento de lectura de instantáneas.

Las operaciones que enumeran colecciones, como db.getCollectionInfos() y db.getCollectionNames(), incluyen vistas en sus salidas.

Importante

La definición de la vista es pública; es decir, las operaciones db.getCollectionInfos() y explain en la vista incluirán el pipeline que define la vista. Por lo tanto, evite referirse directamente a campos y valores sensibles en las definiciones de vistas.

Para remover una vista, utilice el método db.collection.drop() en la vista.

Puedes modificar una vista ya sea eliminándola y volviéndola a crear, o usando el comando collMod.

Las siguientes operaciones proporcionan soporte para vistas, excepto las restricciones mencionadas en esta página:

Comandos
Métodos

Cree la colección students para usarla en los siguientes ejemplos:

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

Utilice db.createView() para crear una vista que esté limitada a estudiantes de primer año:

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

En el ejemplo:

  • firstYears es el nombre de la nueva vista.

  • students es la colección en la que se basa la vista.

  • $match es una expresión de agregación que coincide con los estudiantes de primer año en la colección students.

Este ejemplo consulta la vista:

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

El siguiente resultado solo contiene los documentos con datos sobre estudiantes de primer año. La proyección { _id: 0 } suprime el campo _id en la salida.

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

El método db.createCollection() le permite crear una colección o una vista con opciones específicas.

El siguiente ejemplo crea una vista graduateStudents. La vista solo contiene documentos seleccionados por la etapa $match. La configuración opcional de intercalación determina el orden en la clasificación.

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

El siguiente ejemplo consulta la vista. La etapa $unset elimina el campo _id de la salida para mayor claridad.

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

Cuando se ordena la salida, la etapa $sort utiliza el orden de intercalación para clasificar las letras mayúsculas antes que las minúsculas.

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

A menudo es conveniente usar $lookup para crear una vista sobre dos colecciones y luego ejecutar consultas contra la vista. Las aplicaciones pueden query la vista sin tener que construir ni mantener pipelines complejas.

Crea dos colecciones de muestra, inventory y 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 }
] )

Cree una vista que combine elementos de cada colección:

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

En el ejemplo:

  • db.createView() crea la vista sales.

  • La vista sales se basa en la colección orders.

  • La etapa $lookup utiliza el campo prodId en la colección orders para "unir" documentos en la colección inventory que tienen campos prodId que coinciden.

  • Los documentos que coinciden se agregan como un arreglo en el campo inventoryDocs.

  • La $project etapa selecciona un subconjunto de los campos disponibles.

  • La etapa $unwind convierte el campo price de un arreglo a un valor escalar.

Los documentos en la vista sales son:

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

Para encontrar la cantidad total vendida de cada producto, consulta la vista:

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

La salida es:

[
{ _id: 100, amountSold: 600 },
{ _id: 103, amountSold: 1105 },
{ _id: 101, amountSold: 150 },
{ _id: 102, amountSold: 90 }
]

Volver

Bases de datos y colecciones

En esta página