Docs Menu
Docs Home
/ /
/ / /

Crear y consultar una vista

Para crear una vista, utilice uno de los siguientes métodos:

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(
"<viewName>",
{
"viewOn" : "<source>",
"pipeline" : [<pipeline>],
"collation" : { <collation> }
}
)
db.createView(
"<viewName>",
"<source>",
[<pipeline>],
{
"collation" : { <collation> }
}
)
  • Debe crear vistas en la misma base de datos que la colección de origen.

  • Una definición de vista pipeline no puede incluir la etapa $out o la $merge. Esta restricción también se aplica a pipelines integradas, como las pipelines usadas en las etapas de $lookup o $facet.

  • No puede renombrar una vista una vez que se creó.

Algunas operaciones no están disponibles con las vistas:

Para obtener más información, consulte Operaciones admitidas para vistas.

El primer ejemplo llena una colección con datos de estudiantes y crea una vista para realizar un query de los datos.

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

Nota

Restricciones de proyecciones

find() Las operaciones en vistas no son compatibles con los siguientes operadores de proyección del comando find:

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 $lookup o $graphLookup, las vistas deben tener la misma intercalación.

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 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:

  • James con un rol de Billing que pueda acceder a un campo creditCard.

  • Michelle con un rol de Provider que pueda acceder a un campo diagnosisCode.

Realice los siguientes pasos para crear los roles, los usuarios, la colección y la vista:

1

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: [ ] } )
2

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

Ejecuta:

db.medical.insertMany( [
{
_id: 0,
patientName: "Jack Jones",
diagnosisCode: "CAS 17",
creditCard: "1234-5678-9012-3456"
},
{
_id: 1,
patientName: "Mary Smith",
diagnosisCode: "ACH 01",
creditCard: "6541-7534-9637-3456"
}
] )
4

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 diagnosisCode para un usuario con el rol Provider.

  • incluye el campo creditCard para un usuario con el rol Billing.

  • utiliza las etapas de pipeline $set y $$REMOVE para 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:

1

Ejecuta:

db.auth( "James", "js008" )
2

Ejecuta:

db.medicalView.find()
3

James tiene el rol Billing y ve los siguientes documentos, que incluyen el campo creditCard pero no el campo diagnosisCode:

[
{
_id: 0, patientName: 'Jack Jones',
creditCard: '1234-5678-9012-3456'
},
{
_id: 1, patientName: 'Mary Smith',
creditCard: '6541-7534-9637-3456'
}
]

Realice los siguientes pasos para recuperar la información accesible a Michelle:

1

Ejecuta:

db.auth( "Michelle", "me009" )
2

Ejecuta:

db.medicalView.find()
3

Michelle tiene el rol Provider y ve los siguientes documentos, que incluyen el campo diagnosisCode pero no el campo creditCard:

[
{ _id: 0, patientName: 'Jack Jones',
diagnosisCode: 'CAS 17' },
{ _id: 1, patientName: 'Mary Smith',
diagnosisCode: 'ACH 01' }
]

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:

1

Ejecuta:

db.createRole( { role: "Marketing", roles: [], privileges: [] } )
db.createRole( { role: "Sales", roles: [], privileges: [] } )
db.createRole( { role: "Development", roles: [], privileges: [] } )
db.createRole( { role: "Operations", roles: [], privileges: [] } )
2

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

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:

1

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.

2

Ejecuta:

db.auth( "John", "jn008" )
3

Ejecuta:

db.budgetView.find()
4

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:

1

Ejecuta:

db.auth( "Jane", "je009" )
2

Ejecuta:

db.budgetView.find()
3

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.

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:

1

Ejecuta:

db.auth( "Jane", "je009" )
2

Ejecuta:

db.budget.findOne( {}, { myRoles: "$$USER_ROLES" } )
3

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' }
]
}

Las siguientes secciones describen los comportamientos de la creación de vistas y los queries.

Cuando consulta una vista:

  • Los query filter, projection, sort, skip, limit y otras operaciones para db.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.

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.

Volver

Vistas