MongoDB: Updates complexos - array

MongoDB: Updates complexos - array

No artigo anterior, expliquei o que era o MongoDB e os comandos básicos para inserção, remoção e atualização de dados.

Hoje nós iremos aprender como inserimos e alteramos itens em um array utilizando os Update Operators (operadores de atualização) no MongoDB.

De acordo com a documentação do MongoDB, existem quatro desses modificadores, os mesmos serão abordados no artigo.


Mas por que isso é importante?


Tendo em vista que os arrays são estruturas muito importantes de dados no contexto de modelagem do MongoDB e que o MongoDB é um banco de dados não relacional, também temos que lembrar que é impossível não haver nenhum tipo de relação entre os seus dados. Deste modo os arrays são estruturas que são responsáveis por esse relacionamento necessário entre os dados.

Com eles somos capazes de criar estruturas que simulam algo como o relacionamento de 1:N <- um para vários como no banco de dados relacional, e o MongoDB oferece uma estrutura que facilita muito o uso dessas estruturas.

Lembrando que esses operadores, além de serem restritos aos dados do tipo array, também serão utilizados apenas em operações de atualização.

Quais são?

Como dito anteriormente, segundo a documentação oficial, são 4 os modificadores existentes, eles são: $each, $position, $Slice e $sort.

Sintaxes:

Apesar de serem muito parecidos, cada um dos Update Operators possui uma peculiaridade que serão explicadas uma por uma abaixo.

$each

  • Função: Nos permite inserir múltiplos valores em um campo do tipo array. Ele funcionará apenas com os operadores $push e $addToSet.
  • Sintaxe: Será declarado após o campo que sofrerá a modificação e também recebe um array com os valores a serem inseridos.

Daqui em diante usarei nos exemplos, uma lista de compras logo após as sintaxes para melhor compreensão.

$position

  • Função: Permite que seja inserido um ou mais arquivos em uma posição específica do array. Funcionará apenas com o operador $push.
  • Sintaxe: Será sempre necessário o uso do $each previamente, em seguida iremos declarar o $position e informamos a partir de qual posição os novos valores serão inseridos.


$slice

  • Função: Limita a inserção de novos valores. Funcionará apenas com o operador $push.
  • Sintaxe: Será sempre necessário o uso do $each previamente, em seguida iremos declarar o $slice e definiremos o número máximo de valores que serão inseridos.

$sort

  • Função: Organiza de forma ordenada todos os valores contidos no array, também organiza os que serão adicionados. Funcionará apenas com o operador $push.
  • Sintaxe: Será sempre necessário o uso do $each previamente, em seguida iremos declarar o $sort e definiremos por qual campo a ordenação será feita e se será uma ordenação crescente ou decrescente.


Operadores:

Agora iremos nos aprofundar um pouco nos operadores que foram utilizados mas ainda não foram falando, começando pelo:

$push

O que é?

O $push é um operador que lida diretamente com dados do tipo array, permitindo que sejam adicionados novos valores sem a necessidade de recriamos um campo do zero.

Sintaxe:

Existem duas formas de se utilizar o operador $push, podemos adicionar tanto um item como vários itens de uma vez em um único array, além de termos controles de comportamentos como por exemplo a ordenação automática.

Para o primeiro exemplo, invocamos o $push, declaramos qual dos campos irá receber a adição e por fim definimos qual item será adicionado.

Já no outro caso é obrigatório o uso do operador $each, que além de nos permitir a inserção de múltiplos valores, abre também a possibilidade de alterarmos outros comportamentos.


$pop

O que é?

É um operador para deleção de elementos de um array, podendo ser o primeiro ou o último elemento.

Sintaxe:

Para podermos deletar o primeiro ou o último item de um array, invocamos o método $pop, em seguida iremos definir o campo que possui o array em que ocorrerá a deleção e por último informamos qual o elemento que será excluído, se será o primeiro ou o último.

$pull

O que é?

Assim como o $pop, o $pull é um operador de deleção de itens, porém o $pull é mais “refinado” pois o mesmo nos permite deletar itens de um campo específico através de condições, desse modo todos os itens que correspondem às condições impostas no $pull, serão deletados.

Sintaxe:

Primeiramente invocamos o $pull, em seguida definimos qual dos campos sofrerá as deleções e por fim dizemos quais condições precisam ser atendidas para que o elemento indicado seja deletado.

$addToSet

O que é?

É um operador que funciona de forma parecida com o $push, mas o $addToSet, além de adicionar novos valores a um campo do tipo array, também realiza uma verificação para evitar valores duplicados, sendo assim, o valor a ser inserido, só será caso seja único.

Também é bom lembrar que esse processo de validar documentos duplicados é mais “sensível” ao erro, isso acontece porque o $addToSet só irá considerar valores que são exatamente iguais.

Sintaxe:

Assim como seu comportamento é parecido com o do operador $push, a sua sintaxe também é extremamente similar, o que quer dizer que também podemos adicionar um ou mais itens de uma única vez utilizando o $each, porém com o $addToSet não é possível utilizarmos outras opções como o $sort.

Se quisermos fazer a adição de um item, precisamos invocar o operador $addToSet, seguido do campo que receberá a adição e então definimos o valor a ser adicionado.

Caso a intenção seja adicionar vários itens, precisaremos invocar o $addTo Set, seguido do campo que receberá a adição, em seguida declaramos o operador $each e por último definimos os valores que serão adicionados.

💡
Obs: Se existirem valores duplicados dentro do array em que estamos realizando a adição dos itens, o MongoDB irá executar normalmente a ação sem levantar erro algum, mas o valor duplicado não será adicionado, se manterá apenas o valor pré-existente no array.


Filtros em arrays

O que é?

Os filtros são diferentes formas pelas quais podemos selecionar um valor no array de forma dinâmica, se fôssemos fazer um paralelo com o JS, seria o mesmo que a high order function (HOF) find().

Sintaxe:

Os filtros possuem uma sintaxe simples, mas com sua particularidade, isso porque funciona de forma similar a interpolação do Node com o mysql2.

Utilizaremos os filtros de array dentro de operações de atualização, utilizando o operador $[<identifier>] iremos definir um nome genérico que será utilizado como a referência para a interpolação. Nesse ponto definiremos o valor que será buscado, utilizaremos a opção filtroArrays passando as referências que criamos antes e atribuindo um valor para elas.


Usaremos em conjunto com o filtro a opção de atualizar todos os elementos que correspondem a condição do filtroArrays ou também apenas para consulta, caso essas sejam as condições do filtroArrays.

Ficando assim:

💡
Observação: Lembre-se sempre que o <identifier> deve sempre começar com uma letra minúscula e conter apenas caracteres alfanuméricos.

Citarei alguns exemplos para melhor esclarecimento. Aqui, criaremos uma coleção compras:


Para atualizarmos todos os elementos maiores ou iguais a 100.00 na price, usaremos o operador posicional filtrado $[<identifier>] com o arrayFiltros.


O operador posicional $[<identifier>] irá atuar como um espaço reservado para todos os elementos do campo selecionado que correspondem às condições que foram especificadas no arrayFiltros.

Após a operação, a coleção compras terá o seguinte retorno como resultado da operação:


$pullAll

O que é?

O $pullAll irá remover todas as instâncias de valores especificados no array existente. Ao contrário do $pull, que remove elementos especificando uma consulta, o $pullAll remove todos os elementos correspondentes aos valores listados.

Sintaxe:


Sempre que precisar especificar um <field> em algum documento, use a notação de ponto.

Comportamento:

Se a <value> for um documento ou um array, o $pullAll removerá apenas os elementos no array que correspondem ao <value> exatamente igual ao especificado, incluindo a ordem.

A partir da versão do MongoDB 5.0, o mongod não gera mais erros quando você usa um operador de atualização como o $pullAll com uma expressão de operação vazia ( { } ). Uma atualização “vazia” significa que nenhuma alteração e nenhuma entrada foi criada, o que irá significar que a operação é não operacional.

Veja no exemplo abaixo:

Criaremos a coleção números que terá um array aleatórios com números aleatórios.


Na nossa próxima operação, iremos remover todas as instâncias que tiverem o valor “0” e “2” do arrayNumeros.


Após a atualização, arrayNumeros não irá mais possuir as ocorrências dos números “0” ou “2”, ficando da seguinte forma:


E por último, mas não menos importante, temos o operador $[] que indica que o operador de atualização deve modificar todos os elementos no campo do array especificado.

O operador $[] ficará da seguinte forma:


Use-o em operações de atualização como por exemplo o updateOne() e o findAndModity(), para modicar todos os elementos do array para o documento ou documentos que correspondam a condição da consulta. Por exemplo:

Criaremos uma coleção students:


Para podermos incrementar todos os elementos da “grades” para 10, também fazendo isso para todos os documentos da seleção, faremos da seguinte forma:


O $[] irá incrementar todos os “grades” do array, fazendo com que todos os elementos sejam incrementados com +10, ficando da seguinte forma:


Em breve, trarei formas mais aprofundadas para utilizarmos o MongoDB da forma mais eficiente possível.

Até logo!

💡
As opiniões e comentários expressos neste artigo são de propriedade exclusiva de seu autor e não representam necessariamente o ponto de vista da Revelo.

A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.