Actualizar Arrays en MongoDB

MongoDBBeginner
Practicar Ahora

Introducción

En este laboratorio, aprenderá a manipular arrays dentro de documentos de MongoDB. Practicará la adición, eliminación y actualización de elementos de array utilizando los potentes operadores de actualización de MongoDB. El laboratorio proporciona instrucciones paso a paso y ejemplos prácticos para ayudarle a dominar la gestión de arrays en sus bases de datos MongoDB.

Comenzará añadiendo elementos a un array utilizando el operador $push. A continuación, aprenderá a eliminar elementos utilizando los operadores $pull y $pullAll. También explorará cómo modificar elementos específicos dentro de un array y cómo utilizar $addToSet para garantizar que un array solo contenga elementos únicos. Finalmente, aprenderá a eliminar duplicados existentes de un array utilizando un pipeline de agregación.

Añadir Elementos a un Array con $push

En este paso, aprenderá a añadir nuevos elementos a un array en un documento de MongoDB utilizando el operador $push. Este operador añade un valor especificado a un array.

Primero, abra la shell de MongoDB para interactuar con su base de datos. Todas las operaciones de base de datos en este laboratorio se realizarán dentro de esta shell.

mongosh

Una vez dentro de la shell, cambie a la base de datos arraylab. Esta base de datos fue creada para usted durante el proceso de configuración.

use arraylab

El script de configuración también creó una colección students con un documento. Busquemos este documento para ver su estado actual.

db.students.findOne({ name: "Alice Johnson" })

Debería ver la siguiente salida, que muestra que Alice está inscrita en dos cursos:

{
  _id: ObjectId('...'),
  name: 'Alice Johnson',
  courses: [ 'Mathematics', 'Computer Science' ]
}

Ahora, añadamos un nuevo curso, "Data Structures", al array courses de Alice utilizando el operador $push.

db.students.updateOne(
    { name: "Alice Johnson" },
    { $push: { courses: "Data Structures" } }
)

El método updateOne busca un documento que coincida con el filtro { name: "Alice Johnson" } y aplica la actualización { $push: { courses: "Data Structures" } }. El operador $push añade el nuevo curso al array courses.

También puede añadir varios elementos a la vez combinando $push con el modificador $each. Añadamos "Physics" y "Chemistry" al array.

db.students.updateOne(
    { name: "Alice Johnson" },
    { $push: { courses: { $each: ["Physics", "Chemistry"] } } }
)

Para confirmar que se han añadido todos los cursos nuevos, ejecute de nuevo el comando findOne.

db.students.findOne({ name: "Alice Johnson" })

El documento actualizado ahora contiene los cinco cursos:

{
  _id: ObjectId('...'),
  name: 'Alice Johnson',
  courses: [
    'Mathematics',
    'Computer Science',
    'Data Structures',
    'Physics',
    'Chemistry'
  ]
}

Eliminar Elementos de un Array

En este paso, aprenderá a eliminar elementos de un array utilizando los operadores $pull y $pullAll. $pull elimina todas las instancias de un valor especificado, mientras que $pullAll elimina todas las instancias de múltiples valores especificados.

Debería seguir en la shell de mongosh del paso anterior. Empecemos eliminando el curso "Physics" de la lista de Alice utilizando el operador $pull.

db.students.updateOne(
    { name: "Alice Johnson" },
    { $pull: { courses: "Physics" } }
)

Este comando busca el documento de "Alice Johnson" y elimina la cadena "Physics" de su array courses.

A continuación, eliminemos varios cursos a la vez. El operador $pullAll es perfecto para esto. Eliminaremos "Mathematics" y "Chemistry".

db.students.updateOne(
    { name: "Alice Johnson" },
    { $pullAll: { courses: ["Mathematics", "Chemistry"] } }
)

Ahora, verifiquemos el estado final del documento para ver qué cursos quedan.

db.students.findOne({ name: "Alice Johnson" })

La salida muestra que "Physics", "Mathematics" y "Chemistry" han sido eliminados, dejando solo dos cursos.

{
  _id: ObjectId('...'),
  name: 'Alice Johnson',
  courses: [ 'Computer Science', 'Data Structures' ]
}

Actualizar Elementos Específicos en un Array

En este paso, aprenderá a modificar elementos específicos dentro de un array. Esto es útil cuando su array contiene objetos y necesita actualizar un campo en uno de esos objetos.

Primero, insertemos un nuevo documento de estudiante. El array courses de este documento contendrá objetos, cada uno con un name y una grade.

db.students.insertOne({
    name: "Bob Smith",
    courses: [
        { name: "Mathematics", grade: "B" },
        { name: "Computer Science", grade: "A" },
        { name: "Physics", grade: "C" }
    ]
})

Supongamos que queremos cambiar la calificación de Bob en "Computer Science" de "A" a "A+". Podemos usar el operador posicional $. Este operador actúa como un marcador de posición para el primer elemento que coincide con la condición de la consulta.

db.students.updateOne(
    { name: "Bob Smith", "courses.name": "Computer Science" },
    { $set: { "courses.$.grade": "A+" } }
)

En este comando, la consulta { "courses.name": "Computer Science" } identifica el elemento correcto del array. La actualización { $set: { "courses.$.grade": "A+" } } utiliza entonces $ para referirse a ese elemento y actualizar su campo grade.

Verifiquemos el cambio.

db.students.findOne({ name: "Bob Smith" })

La salida mostrará la calificación actualizada:

{
  _id: ObjectId('...'),
  name: 'Bob Smith',
  courses: [
    { name: 'Mathematics', grade: 'B' },
    { name: 'Computer Science', grade: 'A+' },
    { name: 'Physics', grade: 'C' }
  ]
}

También puede actualizar todos los elementos de un array a la vez utilizando el operador posicional $[ ]. Añadamos un campo semester a todos los cursos de Bob.

db.students.updateOne(
    { name: "Bob Smith" },
    { $set: { "courses.$[].semester": "Fall 2023" } }
)

Compruebe el documento final para ver el resultado.

db.students.findOne({ name: "Bob Smith" })

Todos los objetos de curso en el array ahora tienen el campo semester.

{
  _id: ObjectId('...'),
  name: 'Bob Smith',
  courses: [
    { name: 'Mathematics', grade: 'B', semester: 'Fall 2023' },
    { name: 'Computer Science', grade: 'A+', semester: 'Fall 2023' },
    { name: 'Physics', grade: 'C', semester: 'Fall 2023' }
  ]
}

Garantizar Elementos Únicos con $addToSet

En este paso, aprenderá a usar el operador $addToSet. Este operador agrega un elemento a un array solo si aún no existe en el array, evitando así entradas duplicadas.

Primero, agreguemos un nuevo estudiante con un array de habilidades.

db.students.insertOne({
    name: "Emma Wilson",
    skills: ["Python", "JavaScript"]
})

Ahora, intentemos agregar "Python" nuevamente usando $addToSet. Dado que "Python" ya está en el array, esta operación no cambiará el documento.

db.students.updateOne(
    { name: "Emma Wilson" },
    { $addToSet: { skills: "Python" } }
)

Verifiquemos el documento para confirmar.

db.students.findOne({ name: "Emma Wilson" })

Verá que el array skills no ha cambiado, porque "Python" ya estaba presente.

{
  _id: ObjectId('...'),
  name: 'Emma Wilson',
  skills: [ 'Python', 'JavaScript' ]
}

Al igual que $push, $addToSet se puede combinar con el modificador $each para agregar múltiples valores. Solo agregará los valores que aún no estén en el array.

db.students.updateOne(
    { name: "Emma Wilson" },
    { $addToSet: {
        skills: {
            $each: ["React", "Node.js", "Python", "TypeScript"]
        }
    } }
)

Verifiquemos el documento final.

db.students.findOne({ name: "Emma Wilson" })

Se han agregado las habilidades nuevas y únicas, mientras que el duplicado "Python" fue ignorado.

{
  _id: ObjectId('...'),
  name: 'Emma Wilson',
  skills: [ 'Python', 'JavaScript', 'React', 'Node.js', 'TypeScript' ]
}

Eliminar Duplicados Existentes de un Array

Mientras que $addToSet previene la adición de nuevos duplicados, a veces puedes tener un documento donde un array ya contiene valores duplicados. En este paso, aprenderás cómo eliminar duplicados existentes utilizando un pipeline de agregación.

Primero, insertemos un documento con un array skills que contiene duplicados.

db.students.insertOne({
    name: "Michael Chen",
    skills: ["Python", "JavaScript", "Python", "React", "JavaScript", "Node.js"]
})

Para eliminar estos duplicados, podemos usar un pipeline de agregación con la etapa $merge. Este pipeline leerá el documento, creará un nuevo array con elementos únicos y luego actualizará el documento original.

Primero, necesitamos crear un índice en el campo name para asegurar que la operación $merge funcione correctamente:

db.students.createIndex({ name: 1 }, { unique: true })

Ahora, ejecuta el siguiente comando de agregación:

db.students.aggregate([
    { $match: { name: "Michael Chen" } },
    { $project: {
        name: 1,
        skills: { $setUnion: "$skills" }
    } },
    { $merge: { into: "students", on: "name", whenMatched: "replace" } }
])

Analicemos este pipeline:

  1. $match: Esta etapa filtra los documentos para procesar solo el de "Michael Chen".
  2. $project: Esta etapa remodela el documento. Mantenemos el campo name y reemplazamos el array skills con el resultado de $setUnion: "$skills". El operador $setUnion toma un array y devuelve un nuevo array que contiene solo los elementos únicos.
  3. $merge: Esta etapa escribe los resultados del pipeline de vuelta en la colección students. Encuentra el documento a actualizar basándose en el campo name (on: "name") y reemplaza el documento completo con el nuevo del pipeline (whenMatched: "replace"). El índice que creamos asegura una coincidencia y actualización eficientes.

Ahora, verifiquemos que los duplicados han sido eliminados.

db.students.findOne({ name: "Michael Chen" })

La salida mostrará el array skills con solo elementos únicos. El orden de los elementos puede variar.

{
  _id: ObjectId('...'),
  name: 'Michael Chen',
  skills: [ 'JavaScript', 'Node.js', 'Python', 'React' ]
}

Resumen

En este laboratorio, ha aprendido varias técnicas esenciales para gestionar arrays en MongoDB. Ha practicado la adición de elementos con $push, su eliminación con $pull y $pullAll, y la actualización de elementos específicos utilizando el operador posicional $. También ha explorado cómo mantener elementos únicos en un array con $addToSet y cómo limpiar duplicados existentes utilizando un pipeline de agregación con $setUnion y $merge. Estas habilidades son fundamentales para construir aplicaciones dinámicas y robustas con MongoDB.