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:
Cree una vista de una colección de datos de empleados para
excludecualquier información privada o personal (PII). Las aplicaciones pueden query la vista para obtener datos de los empleados que no contienen información personal identificable (PII).Cree una vista sobre una colección de datos de sensores recopilados para
addcampos y métricas calculados. Las aplicaciones pueden utilizar operaciones de búsqueda simples para query los datos.Cree una vista que
joinsdos colecciones que contienen respectivamente inventario e historial de pedidos. Las aplicaciones pueden query los datos combinados sin gestionar o comprender el complejo pipeline.
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.
Crear Vista
Para crear o definir una vista:
Utilice el método
db.createCollection()createo 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.
Advertencia
No intente crear una colección o vista de series temporales con el nombre system.profile porque el servidor MongoDB fallará.
Comportamiento
Las vistas muestran el siguiente comportamiento:
Solo lectura
Las vistas son de solo lectura; las operaciones de guardar en vistas darán error.
Las siguientes operaciones de lectura pueden soportar vistas:
Operaciones de uso y ordenación de índices
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
$naturalal ejecutar un comandofinden una vista. Las versiones anteriores de MongoDB no admiten el ordenamiento$naturalen 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
findconallowDiskUse: trueen 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
aggregateaceptaba la opciónallowDiskUse.Tip
Para más información sobre los límites de memoria para la operación de ordenamiento bloqueante, consulta Operaciones de ordenamiento.
Restricciones de proyecciones
find() Las operaciones en vistas no admiten los siguientes operadores de proyección:
Nombre inmutable
No puede cambiar el nombre de vistas.
Ver creación
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:
Los query
filter,projection,sort,skip,limity otras operaciones paradb.collection.find()se convierten en etapas de pipeline de agregación equivalentes.Las etapas del pipeline de agregación convertidas se agregan al final del pipeline de agregación para la vista. Esto no modifica el pipeline subyacente de la vista, que se define cuando se crea la vista.
El optimizador del pipeline de agregación reorganiza las etapas del pipeline de agregación de la vista para mejorar el rendimiento. Esto no cambia los resultados de la consulta.
Vista fragmentada
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.
Vistas e intercalación
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
$lookupo$graphLookup, las vistas deben tener la misma intercalación.
Aislamiento de snapshot
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.
Definición de vista pública
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.
Descartar una vista
Para eliminar una vista, utilice el método en la db.collection.drop() vista.
Modificar una vista
Puede modificar una vista eliminándola y volviéndola a crear o utilizando el collMod comando.
Operaciones compatibles
Las siguientes operaciones proporcionan soporte para las vistas, excepto las restricciones mencionadas en esta página:
Comandos | Métodos |
|---|---|
Ejemplos
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
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:
firstYearses el nombre de la nueva vista.studentses la colección en la que se basa la vista.$matches una expresión de agregación que coincide con los estudiantes de primer año en la colecciónstudents.
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 } ]
Utilice db.createCollection() para crear una vista
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 } ]
Utiliza una vista para unir dos colecciones
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 lasalesvista.La vista
salesse basa en la colecciónorders.La etapa
$lookuputiliza el campoprodIden la colecciónorderspara "unir" documentos en la coleccióninventoryque tienen camposprodIdque coinciden.Los documentos que coinciden se agregan como un arreglo en el campo
inventoryDocs.La
$projectetapa selecciona un subconjunto de los campos disponibles.La etapa
$unwindconvierte el campopricede 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 } ]