Introducción
En este laboratorio, aprenderá a utilizar la proyección de MongoDB para controlar qué campos aparecen en los resultados de sus consultas. La proyección es una característica potente que le permite seleccionar campos específicos para devolver, lo que puede reducir la cantidad de datos transferidos a través de la red y mejorar el rendimiento de las consultas. Practicará la inclusión y exclusión de campos, la proyección de campos dentro de documentos anidados y el uso del framework de agregación para remodelar la salida. Al final de este laboratorio, tendrá una comprensión sólida de cómo utilizar eficazmente la proyección en sus consultas de MongoDB.
Seleccionar Campos Específicos con Proyección
En este primer paso, aprenderá los conceptos básicos de la proyección seleccionando solo los campos específicos que desea ver en los resultados de su consulta. Esto se conoce como proyección "inclusiva".
Primero, abra la Shell de MongoDB. Esta interfaz interactiva de línea de comandos es donde ejecutará todos sus comandos de base de datos para este laboratorio.
mongosh
Ahora está dentro de la Shell de MongoDB. El indicador de su terminal cambiará para indicar que está conectado. Cambiemos a una nueva base de datos llamada projectlab_database e insertemos algunos datos de ejemplo. Si la base de datos no existe, MongoDB la creará por usted cuando almacene datos por primera vez.
use projectlab_database
A continuación, inserte tres documentos en una colección llamada users.
db.users.insertMany([
{
name: "John Doe",
age: 30,
email: "john.doe@example.com",
city: "New York",
job: "Software Engineer"
},
{
name: "Jane Smith",
age: 28,
email: "jane.smith@example.com",
city: "San Francisco",
job: "Data Scientist"
},
{
name: "Mike Johnson",
age: 35,
email: "mike.johnson@example.com",
city: "Chicago",
job: "Product Manager"
}
]);
Ahora, consultemos esta colección. Para devolver solo los campos name y age para todos los documentos, agregue un documento de proyección como segundo argumento al método find(). En el documento de proyección, especifique los campos a incluir con un 1. Por defecto, el campo _id siempre se devuelve. Puede excluirlo explícitamente estableciendo su valor en 0.
db.users.find({}, { name: 1, age: 1, _id: 0 });
Debería ver la siguiente salida, que contiene solo los campos name y age para cada usuario:
[
{ "name": "John Doe", "age": 30 },
{ "name": "Jane Smith", "age": 28 },
{ "name": "Mike Johnson", "age": 35 }
]
Esta técnica es muy útil para recuperar solo los datos necesarios, lo cual es especialmente importante cuando se trabaja con documentos grandes.
Excluir Campos Específicos de los Resultados
Además de seleccionar qué campos incluir, también puede especificar qué campos excluir. Esto se conoce como proyección "exclusiva" y es útil cuando desea ver la mayoría de los campos pero ocultar algunos, como los sensibles o los grandes.
Debería seguir en la shell mongosh con la base de datos projectlab_database seleccionada.
Para excluir campos, establezca su valor en 0 en el documento de proyección. Ejecutemos una consulta para obtener todos los datos de usuario pero excluyendo los campos email y city.
db.users.find({}, { email: 0, city: 0 });
La salida incluirá todos los campos excepto email y city. Tenga en cuenta que el campo _id todavía se incluye por defecto.
[
{
_id: ObjectId("..."),
name: 'John Doe',
age: 30,
job: 'Software Engineer'
},
{
_id: ObjectId("..."),
name: 'Jane Smith',
age: 28,
job: 'Data Scientist'
},
{
_id: ObjectId("..."),
name: 'Mike Johnson',
age: 35,
job: 'Product Manager'
}
]
Una regla clave en la proyección es que no puede mezclar inclusión (1) y exclusión (0) en el mismo documento de proyección. La única excepción a esta regla es el campo _id. Puede excluir explícitamente el campo _id (_id: 0) incluso cuando incluye otros campos, como hizo en el paso anterior. También puede excluirlo en una proyección exclusiva.
Por ejemplo, para excluir email, city y _id, ejecutaría lo siguiente:
db.users.find({}, { email: 0, city: 0, _id: 0 });
Esta consulta devuelve documentos que contienen solo los campos name, age y job.
Proyectar Campos en Documentos Anidados
Los datos del mundo real a menudo se estructuran con documentos y arreglos anidados. Las capacidades de proyección de MongoDB le permiten seleccionar campos con precisión incluso cuando están incrustados profundamente en la estructura de un documento.
Primero, eliminemos la colección users existente e insertemos nuevos documentos que tengan un objeto contact anidado y un arreglo skills.
db.users.deleteMany({});
Ahora, inserte los nuevos datos.
db.users.insertMany([
{
name: "John Doe",
contact: {
email: "john.doe@example.com",
phone: {
mobile: "123-456-7890",
work: "987-654-3210"
}
},
skills: ["JavaScript", "MongoDB", "React"]
},
{
name: "Jane Smith",
contact: {
email: "jane.smith@example.com",
phone: {
mobile: "234-567-8901",
work: "876-543-2109"
}
},
skills: ["Python", "Data Science", "Machine Learning"]
}
]);
Para proyectar un campo dentro de un documento anidado, use la "notación de punto" (dot notation). Por ejemplo, para seleccionar el name del usuario y su número de teléfono móvil, especificaría "contact.phone.mobile": 1. Intentemos proyectar el name, el email y el número de teléfono mobile.
db.users.find(
{},
{
name: 1,
"contact.email": 1,
"contact.phone.mobile": 1,
_id: 0
}
);
El resultado conservará la estructura anidada para los campos seleccionados:
[
{
"name": "John Doe",
"contact": {
"email": "john.doe@example.com",
"phone": { "mobile": "123-456-7890" }
}
},
{
"name": "Jane Smith",
"contact": {
"email": "jane.smith@example.com",
"phone": { "mobile": "234-567-8901" }
}
}
]
También puede proyectar una porción de un arreglo utilizando el operador $slice. Para obtener el name y solo las dos primeras habilidades (skills) de cada usuario, ejecute el siguiente comando:
db.users.find({}, { name: 1, skills: { $slice: 2 }, _id: 0 });
La salida mostrará a cada usuario con un arreglo skills que contiene solo dos elementos:
[
{ "name": "John Doe", "skills": ["JavaScript", "MongoDB"] },
{ "name": "Jane Smith", "skills": ["Python", "Data Science"] }
]
Remodelar Campos de Salida con Agregación
Para transformaciones más avanzadas, como renombrar campos o crear nuevos campos calculados, la proyección del método find() no es suficiente. En su lugar, puede utilizar el framework de agregación, específicamente la etapa $project.
Preparemos nuestros datos para este paso. Limpie la colección e inserte usuarios con información salarial.
db.users.deleteMany({});
db.users.insertMany([
{
name: "John Doe",
age: 30,
salary: 75000,
department: "Engineering"
},
{
name: "Jane Smith",
age: 28,
salary: 85000,
department: "Data Science"
},
{
name: "Mike Johnson",
age: 35,
salary: 95000,
department: "Management"
}
]);
La etapa $project en un pipeline de agregación puede remodelar documentos agregando nuevos campos, renombrando campos existentes o eliminando campos. Para usarla, pase una matriz de etapas al método aggregate().
Para renombrar un campo, defina un nuevo nombre de campo y asígnele el valor de un campo existente, precedido por un signo $. Renombremos name a fullName y age a yearsOld.
db.users.aggregate([
{
$project: {
fullName: "$name",
yearsOld: "$age",
_id: 0
}
}
]);
También puede crear nuevos campos basados en cálculos. Creemos un campo monthlySalary dividiendo el salary anual entre 12, y un campo salaryTier basado en lógica condicional utilizando el operador $switch.
db.users.aggregate([
{
$project: {
name: 1,
monthlySalary: { $divide: ["$salary", 12] },
salaryTier: {
$switch: {
branches: [
{ case: { $lt: ["$salary", 80000] }, then: "Junior" },
{ case: { $gte: ["$salary", 80000] }, then: "Senior" }
],
default: "Unknown"
}
},
_id: 0
}
}
]);
La salida será una estructura de documento completamente nueva que definió en la etapa $project:
[
{ "name": "John Doe", "monthlySalary": 6250, "salaryTier": "Junior" },
{
"name": "Jane Smith",
"monthlySalary": 7083.333333333333,
"salaryTier": "Senior"
},
{
"name": "Mike Johnson",
"monthlySalary": 7916.666666666667,
"salaryTier": "Senior"
}
]
La etapa $project le brinda control total sobre la forma final de los resultados de su consulta, permitiendo transformaciones de datos potentes directamente dentro de la base de datos.
Resumen
En este laboratorio, ha aprendido a controlar eficazmente la salida de sus consultas de MongoDB utilizando la proyección. Comenzó con los conceptos básicos de incluir y excluir campos con el método find(). Luego avanzó a temas más avanzados, como el uso de la notación de punto (dot notation) para proyectar campos dentro de documentos anidados y el uso del operador $slice para devolver un subconjunto de un arreglo. Finalmente, exploró el poder de la etapa $project del framework de agregación para remodelar completamente los documentos renombrando campos, creando nuevos campos calculados y aplicando lógica condicional. Estas habilidades son fundamentales para escribir consultas eficientes y precisas en MongoDB.

