Para crear una vista, utilice uno de los siguientes métodos:
Usar
db.createView()
Para crear una vista en la interfaz de usuario de MongoDB Atlas, debe utilizar una vista materializada. Para obtener más información, consulte Crear una vista materializada en la interfaz de usuario de MongoDB Atlas.
Importante
Los nombres de las vistas están incluidos en la salida de la lista de colecciones
Las operaciones que enumeran colecciones, como db.getCollectionInfos() y db.getCollectionNames(), incluyen vistas en sus resultados.
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.
db.createCollection() Sintaxis
db.createCollection( "<viewName>", { "viewOn" : "<source>", "pipeline" : [<pipeline>], "collation" : { <collation> } } )
db.createView() Sintaxis
db.createView( "<viewName>", "<source>", [<pipeline>], { "collation" : { <collation> } } )
Restricciones
Debe crear vistas en la misma base de datos que la colección de origen.
Una definición de vista
pipelineno puede incluir la etapa$outo la$merge. Esta restricción también se aplica a pipelines integradas, como las pipelines usadas en las etapas de$lookupo$facet.No puede renombrar una vista una vez que se creó.
Operaciones no admitidas
Algunas operaciones no están disponibles con las vistas:
El operador
$text, ya que$texten la agregación solo es válido para la primera etapa.Cambio de nombre de una vista.
Para obtener más información, consulte Operaciones admitidas para vistas.
Ejemplos
El primer ejemplo llena una colección con datos de estudiantes y crea una vista para realizar un query de los datos.
Rellene la colección
Cree una colección students para utilizar en este ejemplo:
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.
Consulte la vista
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 } ]
Nota
Restricciones de proyecciones
find() Las operaciones en vistas no son compatibles con los siguientes operadores de proyección del comando find:
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: { year: { $gt: 4 } } } ], collation: { locale: "en", caseFirst: "upper" } } )
Nota
Comportamiento de la 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.
Consulte la vista
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 } ]
Recupere la información médica de los roles concedidos al usuario actual
A partir de MongoDB 7.0, puedes usar la nueva variable de sistema USER_ROLES para devolver los roles de usuario.
Nota
No se admite el uso de la USER_ROLES variable de sistema en agregaciones
Clústeres M0 y Flex.
El ejemplo en esta sección muestra a los usuarios con acceso limitado a los campos en una colección que contiene información médica. El ejemplo utiliza una vista que lee los roles actuales del usuario desde la variable de sistema USER_ROLES y oculta campos basándose en los roles.
El ejemplo crea a estos usuarios:
Jamescon un rol deBillingque pueda acceder a un campocreditCard.Michellecon un rol deProviderque pueda acceder a un campodiagnosisCode.
Realice los siguientes pasos para crear los roles, los usuarios, la colección y la vista:
Crea los roles
Ejecuta:
db.createRole( { role: "Billing", privileges: [ { resource: { db: "test", collection: "medicalView" }, actions: [ "find" ] } ], roles: [ ] } ) db.createRole( { role: "Provider", privileges: [ { resource: { db: "test", collection: "medicalView" }, actions: [ "find" ] } ], roles: [ ] } )
Crea los usuarios
Crea usuarios llamados James y Michelle con los roles requeridos. Reemplaza la base de datos test con el nombre de su base de datos.
db.createUser( { user: "James", pwd: "js008", roles: [ { role: "Billing", db: "test" } ] } ) db.createUser( { user: "Michelle", pwd: "me009", roles: [ { role: "Provider", db: "test" } ] } )
Cree la vista
Para usar una variable del sistema, agrega $$ al inicio del nombre de la variable. Especifica la variable del sistema USER_ROLES como $$USER_ROLES.
La vista lee los roles actuales del usuario desde la variable de sistema USER_ROLES y oculta campos según los roles.
Ejecuta:
db.createView( "medicalView", "medical", [ { $set: { "diagnosisCode": { $cond: { if: { $in: [ "Provider", "$$USER_ROLES.role" ] }, then: "$diagnosisCode", else: "$$REMOVE" } } }, }, { $set: { "creditCard": { $cond: { if: { $in: [ "Billing", "$$USER_ROLES.role" ] }, then: "$creditCard", else: "$$REMOVE" } } } } ] )
Ejemplo de vista:
incluye el campo
diagnosisCodepara un usuario con el rolProvider.incluye el campo
creditCardpara un usuario con el rolBilling.utiliza las etapas de pipeline
$sety$$REMOVEpara ocultar campos según si el usuario que consulta la vista tiene el rol que coincidente que se devuelve en$$USER_ROLES.role.
Realice los siguientes pasos para recuperar la información accesible a James:
Realice los siguientes pasos para recuperar la información accesible a Michelle:
Recupere los documentos de presupuesto de los roles concedidos al usuario actual
A partir de MongoDB 7.0, puedes usar la nueva variable de sistema USER_ROLES para devolver los roles de usuario.
En esta sección aparecen usuarios con varios roles que tienen acceso limitado a documentos en una colección que contiene información presupuestaria.
El escenario muestra un posible uso de USER_ROLES. La colección budget contiene documentos con un campo llamado allowedRoles. Como verás en el siguiente caso, puedes guardar queries que comparen los roles de usuario encontrados en el campo allowedRoles con los roles devueltos por la variable de sistema USER_ROLES.
Nota
Para otro escenario de ejemplo USER_ROLES, consulta Recuperar información médica para los roles concedidos al usuario actual. Ese ejemplo no almacena los roles de usuario en los campos del documento, como se hace en el ejemplo siguiente.
Para el escenario presupuestario de esta sección, realiza los siguientes pasos para crear los roles, usuarios y la colección de budget:
Crea los usuarios
Crea usuarios llamados John y Jane con los roles requeridos. Reemplaza la base de datos test con el nombre de su base de datos.
db.createUser( { user: "John", pwd: "jn008", roles: [ { role: "Marketing", db: "test" }, { role: "Development", db: "test" }, { role: "Operations", db: "test" }, { role: "read", db: "test" } ] } ) db.createUser( { user: "Jane", pwd: "je009", roles: [ { role: "Sales", db: "test" }, { role: "Operations", db: "test" }, { role: "read", db: "test" } ] } )
Crear la colección
Ejecuta:
db.budget.insertMany( [ { _id: 0, allowedRoles: [ "Marketing" ], comment: "For marketing team", yearlyBudget: 15000 }, { _id: 1, allowedRoles: [ "Sales" ], comment: "For sales team", yearlyBudget: 17000, salesEventsBudget: 1000 }, { _id: 2, allowedRoles: [ "Operations" ], comment: "For operations team", yearlyBudget: 19000, cloudBudget: 12000 }, { _id: 3, allowedRoles: [ "Development" ], comment: "For development team", yearlyBudget: 27000 } ] )
Realice los siguientes pasos para crear una vista y recuperar los documentos accesibles a John:
Cree la vista
Para usar una variable del sistema, agrega $$ al inicio del nombre de la variable. Especifica la variable del sistema USER_ROLES como $$USER_ROLES.
Ejecuta:
db.createView( "budgetView", "budget", [ { $match: { $expr: { $not: { $eq: [ { $setIntersection: [ "$allowedRoles", "$$USER_ROLES.role" ] }, [] ] } } } } ] )
Si no puede crear la vista, asegúrese de iniciar sesión como un usuario con el privilegio de crear una vista.
El ejemplo anterior devuelve los documentos de la colección budget que coinciden con al menos uno de los roles que tiene el usuario que ejecuta el ejemplo. Para hacer eso, el ejemplo utiliza $setIntersection para devolver documentos donde la intersección entre el campo allowedRoles del documento budget y el conjunto de roles de usuario de $$USER_ROLES no está vacía.
Examina los documentos
John tiene los roles Marketing, Operations y Development, y ve estos documentos:
[ { _id: 0, allowedRoles: [ 'Marketing' ], comment: 'For marketing team', yearlyBudget: 15000 }, { _id: 2, allowedRoles: [ 'Operations' ], comment: 'For operations team', yearlyBudget: 19000, cloudBudget: 12000 }, { _id: 3, allowedRoles: [ 'Development' ], comment: 'For development team', yearlyBudget: 27000 } ]
Realice los siguientes pasos para recuperar los documentos accesibles para Jane:
Examina los documentos
Jane tiene los roles Sales y Operations y ve estos documentos:
[ { _id: 1, allowedRoles: [ 'Sales' ], comment: 'For sales team', yearlyBudget: 17000, salesEventsBudget: 1000 }, { _id: 2, allowedRoles: [ 'Operations' ], comment: 'For operations team', yearlyBudget: 19000, cloudBudget: 12000 } ]
Nota
En un clúster, una query se puede ejecutar en un fragmento por otro nodo de servidor en nombre del usuario. En esas queries, USER_ROLES todavía se completan con los roles del usuario.
Roles con el mismo nombre en múltiples bases de datos
Varias bases de datos pueden tener roles con el mismo nombre. Si crea una vista y referencia un rol específico en la vista, debe especificar tanto el campo de nombre de la base de datos db como el campo role, o especificar el campo _id que contiene el nombre de la base de datos y el rol.
En el siguiente ejemplo se devuelven los roles asignados a Jane, que tiene roles con nombres diferentes. El ejemplo devuelve los nombres de las bases de datos _id, role y db:
Examina los documentos
Ejemplo de salida que muestra los nombres de las bases de datos _id, role y db en el arreglo myRoles:
{ _id: 0, myRoles: [ { _id: 'test.Operations', role: 'Operations', db: 'test' }, { _id: 'test.Sales', role: 'Sales', db: 'test' }, { _id: 'test.read', role: 'read', db: 'test' } ] }
Comportamiento
Las siguientes secciones describen los comportamientos de la creación de vistas y los queries.
Optimizaciones de agregación
Cuando 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.MongoDB agrega el query del cliente a la pipeline subyacente y le devuelve los resultados de esa pipeline combinada. MongoDB puede aplicar optimizaciones de pipeline de agregación a la pipeline combinada.
El optimizador de la pipeline de agregación ajusta las etapas de la pipeline de agregación de vistas para mejorar el rendimiento. La optimización no cambia los resultados del query.
Bloqueo de recursos
db.createView() obtiene un bloqueo exclusivo en la colección o vista especificada durante toda la operación. Todas las operaciones posteriores en la colección deben esperar hasta que db.createView() libere el bloqueo. db.createView() normalmente mantiene este bloqueo por poco tiempo.
Crear una vista requiere obtener un bloqueo exclusivo adicional en la colección system.views de la base de datos. Este bloqueo impide la creación o modificación de vistas en la base de datos hasta que el comando se complete.