Atualizar Arrays no MongoDB

MongoDBBeginner
Pratique Agora

Introdução

Neste laboratório, você aprenderá a manipular arrays dentro de documentos MongoDB. Você praticará a adição, remoção e atualização de elementos de array usando os poderosos operadores de atualização do MongoDB. O laboratório fornece instruções passo a passo e exemplos práticos para ajudá-lo a dominar o gerenciamento de arrays em seus bancos de dados MongoDB.

Você começará adicionando elementos a um array usando o operador $push. Em seguida, aprenderá a remover elementos usando os operadores $pull e $pullAll. Você também explorará como modificar elementos específicos dentro de um array e como usar $addToSet para garantir que um array contenha apenas elementos únicos. Finalmente, você aprenderá a remover duplicatas existentes de um array usando um pipeline de agregação.

Adicionar Elementos a um Array com $push

Nesta etapa, você aprenderá a adicionar novos elementos a um array em um documento MongoDB usando o operador $push. Este operador anexa um valor especificado a um array.

Primeiro, abra o shell do MongoDB para interagir com seu banco de dados. Todas as operações de banco de dados neste laboratório serão realizadas dentro deste shell.

mongosh

Uma vez dentro do shell, mude para o banco de dados arraylab. Este banco de dados foi criado para você durante o processo de configuração.

use arraylab

O script de configuração também criou uma coleção students com um documento. Vamos encontrar este documento para ver seu estado atual.

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

Você deverá ver a seguinte saída, que mostra que Alice está matriculada em dois cursos:

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

Agora, vamos adicionar um novo curso, "Data Structures", ao array courses de Alice usando o operador $push.

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

O método updateOne encontra um documento que corresponde ao filtro { name: "Alice Johnson" } e aplica a atualização { $push: { courses: "Data Structures" } }. O operador $push anexa o novo curso ao array courses.

Você também pode adicionar vários elementos de uma vez combinando $push com o modificador $each. Vamos adicionar "Physics" e "Chemistry" ao array.

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

Para confirmar que todos os novos cursos foram adicionados, execute o comando findOne novamente.

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

O documento atualizado agora contém todos os cinco cursos:

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

Remover Elementos de um Array

Nesta etapa, você aprenderá a remover elementos de um array usando os operadores $pull e $pullAll. $pull remove todas as instâncias de um valor especificado, enquanto $pullAll remove todas as instâncias de múltiplos valores especificados.

Você ainda deve estar no shell mongosh da etapa anterior. Vamos começar removendo o curso "Physics" da lista de Alice usando o operador $pull.

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

Este comando encontra o documento de "Alice Johnson" e remove a string "Physics" do array courses dela.

Em seguida, vamos remover vários cursos de uma vez. O operador $pullAll é perfeito para isso. Removeremos "Mathematics" e "Chemistry".

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

Agora, vamos verificar o estado final do documento para ver quais cursos restam.

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

A saída mostra que "Physics", "Mathematics" e "Chemistry" foram removidos, restando apenas dois cursos.

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

Atualizar Elementos Específicos em um Array

Nesta etapa, você aprenderá a modificar elementos específicos dentro de um array. Isso é útil quando seu array contém objetos e você precisa atualizar um campo em um desses objetos.

Primeiro, vamos inserir um novo documento de estudante. O array courses deste documento conterá objetos, cada um com um name e uma grade.

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

Suponha que queremos mudar a nota de Bob em "Computer Science" de "A" para "A+". Podemos usar o operador posicional $. Este operador atua como um placeholder para o primeiro elemento que corresponde à condição da consulta.

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

Neste comando, a consulta { "courses.name": "Computer Science" } identifica o elemento correto do array. A atualização { $set: { "courses.$.grade": "A+" } } então usa $ para se referir a esse elemento e atualizar seu campo grade.

Vamos verificar a mudança.

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

A saída mostrará a nota atualizada:

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

Você também pode atualizar todos os elementos em um array de uma vez usando o operador posicional $[ ]. Vamos adicionar um campo semester a todos os cursos de Bob.

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

Verifique o documento final para ver o resultado.

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

Todos os objetos de curso no array agora possuem o 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' }
  ]
}

Garantir Elementos Únicos com $addToSet

Nesta etapa, você aprenderá a usar o operador $addToSet. Este operador adiciona um elemento a um array somente se ele ainda não existir no array, evitando assim entradas duplicadas.

Primeiro, vamos adicionar um novo estudante com um array de habilidades.

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

Agora, vamos tentar adicionar "Python" novamente usando $addToSet. Como "Python" já está no array, esta operação não alterará o documento.

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

Vamos verificar o documento para confirmar.

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

Você verá que o array skills não foi alterado, pois "Python" já estava presente.

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

Assim como $push, $addToSet pode ser combinado com o modificador $each para adicionar múltiplos valores. Ele adicionará apenas os valores que ainda não estão no array.

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

Vamos verificar o documento final.

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

As novas habilidades únicas foram adicionadas, enquanto o "Python" duplicado foi ignorado.

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

Remover Duplicatas Existentes de um Array

Enquanto $addToSet impede a adição de novas duplicatas, às vezes você pode ter um documento onde um array já contém valores duplicados. Neste passo, você aprenderá como remover duplicatas existentes usando um pipeline de agregação.

Primeiro, vamos inserir um documento com um array skills que contém duplicatas.

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

Para remover essas duplicatas, podemos usar um pipeline de agregação com o estágio $merge. Este pipeline lerá o documento, criará um novo array com elementos únicos e, em seguida, atualizará o documento original.

Primeiro, precisamos criar um índice no campo name para garantir que a operação $merge funcione corretamente:

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

Agora, execute o seguinte comando de agregação:

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

Vamos detalhar este pipeline:

  1. $match: Este estágio filtra os documentos para processar apenas o de "Michael Chen".
  2. $project: Este estágio remodela o documento. Mantemos o campo name e substituímos o array skills pela saída de $setUnion: "$skills". O operador $setUnion recebe um array e retorna um novo array contendo apenas os elementos únicos.
  3. $merge: Este estágio escreve os resultados do pipeline de volta na coleção students. Ele encontra o documento a ser atualizado com base no campo name (on: "name") e substitui o documento inteiro pelo novo do pipeline (whenMatched: "replace"). O índice que criamos garante a correspondência e atualização eficientes.

Agora, vamos verificar se as duplicatas foram removidas.

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

A saída mostrará o array skills com apenas elementos únicos. A ordem dos elementos pode variar.

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

Resumo

Neste laboratório, você aprendeu várias técnicas essenciais para gerenciar arrays no MongoDB. Você praticou a adição de elementos com $push, a remoção deles com $pull e $pullAll, e a atualização de elementos específicos usando o operador posicional $. Você também explorou como manter elementos únicos em um array com $addToSet e como limpar duplicatas existentes usando um pipeline de agregação com $setUnion e $merge. Essas habilidades são fundamentais para construir aplicações dinâmicas e robustas com o MongoDB.