Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
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() create o el comando:

    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 o vista de series temporales con el nombre system.profile porque el servidor MongoDB fallará.

Las vistas muestran 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.

  • Como los índices están en la colección subyacente, no es posible crear, eliminar ni 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 canalización de agregación subyacente de la vista está sujeta al límite de memoria de 100 MB para bloquear las operaciones de ordenación y agrupación. A partir de MongoDB 4.4, se puede ejecutar un comando find con allowDiskUse: true en la vista para permitir que MongoDB use archivos temporales para bloquear las operaciones de ordenación y agrupación.

    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 la canalización de agregación utilizada para crear la vista suprime el campo _id, los documentos en la vista no tendrán 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 eliminar una vista, utilice el método en la db.collection.drop() vista.

Puede modificar una vista eliminándola y volviéndola a crear o utilizando el collMod comando.

Las siguientes operaciones proporcionan soporte para las 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 }
]

Suele ser conveniente usar para crear una vista sobre dos colecciones y luego ejecutar consultas en ella. Las aplicaciones pueden consultar la vista sin tener que construir ni mantener pipelines $lookup complejos.

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 sales vista.

  • 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