Una vista MongoDB es un objeto consultable cuyo contenido está definido por un Canal de agregación en otras colecciones o vistas. MongoDB no conserva el contenido de la vista en el disco. El contenido de una vista se calcula bajo demanda cuando un cliente la consulta. MongoDB puede requerir que los clientes tengan permiso para consultar 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 consultar la vista para buscar datos de empleados que no contengan PII.Cree una vista de una colección de datos de sensores recopilados para calcular campos y métricas. Las aplicaciones pueden usar operaciones de búsqueda sencillas para consultar los
adddatos.Cree una vista que incluya dos colecciones que contengan inventario e historial de pedidos, respectivamente. Las aplicaciones pueden consultar los datos combinados sin tener que administrar ni comprender el complejo proceso
joinssubyacente.
Puedes crear vistas materializadas en la interfaz de usuario para despliegues alojados en MongoDB Atlas.
Cuando los clientes consultan una vista, MongoDB agrega la consulta del cliente a la canalización subyacente y devuelve los resultados de esa canalización combinada al cliente. MongoDB puede aplicar optimizaciones de la canalización de agregación a la canalización combinada.
Nota
En la siguiente página se describen las vistas. Para obtener información sobre las vistas materializadas bajo demanda, consulte Vistas materializadas bajo demanda.
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> } } ) Utilice el
db.createView()método: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 sólo lectura; las operaciones de escritura en las vistas generarán errores.
Las siguientes operaciones de lectura pueden admitir vistas:
Operaciones de uso y ordenación de índices
Las vistas utilizan 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 100 límite de memoria de megabytes para bloquear las operaciones de ordenación y agrupación. A partir de MongoDB,4.4 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 solo el comando aceptaba
aggregatelaallowDiskUseopción.Tip
Para obtener más información sobre cómo bloquear los límites de memoria de las operaciones de clasificación, consulte Operaciones de clasificación.
Restricciones de proyecciones
find() Las operaciones en las 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 bajo demanda durante las operaciones de lectura, y MongoDB ejecuta operaciones de lectura en las vistas como parte del flujo de trabajo de agregación subyacente. Por lo tanto, las vistas no admiten operaciones 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 se consulta una vista,:
Los query
filter,projection,sort,skip,limity otras operaciones paradb.collection.find()se convierten en etapas de pipeline de agregación equivalentes.Las etapas convertidas del pipeline de agregación se añaden al final del pipeline de agregación de la vista. Esto no modifica el pipeline subyacente de la vista, que se configura al crearla.
El optimizador de canalización de agregación reestructura las etapas de la canalización de agregación de vistas para mejorar el rendimiento. Esto no altera los resultados de la consulta.
Vista fragmentada
Las vistas se consideran fragmentadas si su colección subyacente también lo está. Por lo tanto, no se puede especificar una vista fragmentada para el from campo en $lookup las operaciones $graphLookup y.
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() db.getCollectionNames()y, 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.
Dejar 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 utilizarla 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 } ] )
Crea 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 } ]