Skip to content

Instantly share code, notes, and snippets.

@oleoprado
Last active March 21, 2023 22:21
Show Gist options
  • Select an option

  • Save oleoprado/944c15978eaa993cb687d23297b60989 to your computer and use it in GitHub Desktop.

Select an option

Save oleoprado/944c15978eaa993cb687d23297b60989 to your computer and use it in GitHub Desktop.
Guia básico mongoDB
logo mongoDB logo mongoDB

Executando container via terminal

(dentro do diretório desejado)

docker run --name <nome-do-container> -d -p 27017:27017 mongo:4
docker run --name mongodb_docker -v $(pwd)/backup:/data/db -p 8080:27017 -d mongo

obs: `27017` porta (interna container) padrão do mongoDB

obs: `8080` porta externa(localhost)

obs: diretório `backup` fica os arquivos de backup do container

Executando via docker-compose

```
version: 5

services:

  mongo:
    image: mongo
    restart: always
    ports:
      - 8080:27017
    volumes:
      - ./backup:/data/db

```

Subir o docker-compose

```bash
docker-compose up -d
```

Importar arquivos locais para dentro do container utilizando mongoimport

1 - No primeiro passo, copiamos o arquivo que será importado para dentro do nosso container.

docker cp nome-do-arquivo.json <nome-do-container-ou-id>:/tmp/nome-do-arquivo.json

2 - No segundo passo, realizamos a importação do arquivo JSON para o MongoDB.

docker exec <nome-do-container-ou-id> mongoimport -d <nome-do-banco> -c <nome-da-coleção> --file /tmp/nome-do-arquivo.json

Importar uma matriz JSON (Array de dados) com mongoimport

Importar (e criar) um documento com varias linhas de uma vez no banco:

Dentro do container:

```
mongoimport --port <port> -d <db> -c <collection> --jsonArray --file <file>
```

Na raiz do projeto:

```bash
 docker exec <nome-do-container-ou-id> mongoimport --collection='from_array_file' --file='one_big_list.json' --jsonArray
 ```

Exemplo de varios documentos:

  [
     { title: "Informação 1", description: "Valor de exemplo 1"},
     { title: "Informação 2", description: "Valor de exemplo 2"}
  ]

Executando o shell do Mongo no Docker

docker exec -it <nome-do-container-ou-id> mongo

Operadores de Comparação

Operator $lt

Seleciona os documentos em que o valor do atributo filtrado é menor do que (<) o valor especificado:

db.inventory.find({ qty: { $lt: 20 } })

Essa consulta selecionará todos os documentos na coleção inventory cujo valor do atributo qty é menor do que 20.


Operator $lte

Seleciona os documentos em que o valor do atributo filtrado é menor ou igual que (<=) o valor especificado:

db.inventory.find({ qty: { $lte: 20 } })

Essa query selecionará todos os documentos na coleção inventory cujo valor do atributo qty é menor ou igual a 20.


Operator $gt

Seleciona os documentos em que o valor do atributo filtrado é maior do que (>) o valor especificado:

db.inventory.find({ qty: { $gt: 20 } })

Essa query selecionará todos os documentos na coleção inventory cujo valor do atributo qty é maior do que 20.


Operator $gte

Seleciona os documentos em que o valor do atributo filtrado é maior ou igual que (>=) o valor especificado:

db.inventory.find({ qty: { $gte: 20 } })

Essa query selecionará todos os documentos na coleção inventory cujo valor do atributo qty é maior ou igual a 20.


Operator $eq

Seleciona os documentos em que o valor do atributo filtrado é igual (=) ao valor especificado.Esse operador é equivalente ao filtro { campo: <valor> } e não tem nenhuma diferença de performance.

db.inventory.find({ qty: { $eq: 20 } })

ou

db.inventory.find({ qty: 20 })

Essa query selecionará todos os documentos na coleção inventory cujo valor do atributo qty é igual a 20.


Operator $ne

Seleciona os documentos em que o valor do atributo filtrado NÃO é igual ao valor especificado:

db.inventory.find({ qty: { $ne: 20 } })

Essa query selecionará todos os documentos na coleção inventory cujo valor do atributo qty é diferente de 20, incluindo os documentos em que o atributo qty não existe


Operator $in

Seleciona os documentos em que o valor do atributo é igual a um dos valores do array:

db.inventory.find({ qty: { $in: [ 5, 15 ] } })

Essa query selecionará todos os documentos na coleção inventory cujo valor do atributo qty é 5 ou 15


Operator $nin

Seleciona os documentos em que o valor do atributo NÃO é igual ao especificado no array, ou o campo não existe:

db.inventory.find({ qty: { $nin: [ 5, 15 ] } })

Essa query selecionará todos os documentos na coleção inventory cujo valor do atributo qty é diferente de 5 e 15.Esse resultado também inlcui os documentos em que o atributo qty não existe.


Operador $exists

Sintaxe:

{ campo: { $exists: <boolean> } }

Quando o <boolean> é verdadeiro (true), o operador $exists encontra os documentos que contêm o atributo, incluindo os documentos em que o valor do atributo é igual a null. Se o <boolean> é falso (false), a consulta retorna somente os documentos que não contêm o atributo.

db.inventory.find({ qty: { $exists: true } })

Essa consulta selecionará todos os documentos na coleção inventory em que o atributo qty existe.

Você também pode combinar operadores, como no exempo abaixo:

db.inventory.find({ qty: { $exists: true, $nin: [ 5, 15 ] } })

Essa consulta selecionará todos os documentos na coleção inventory em que o atributo qty existe E seu valor é diferente de 5 e 15

Operadores Lógicos

Operator $not

O operador $not executa uma operação de NEGAÇÃO no <operador ou expressão> especificado e seleciona os documentos que não correspondam ao <operador ou expressão>. Também inclui os documentos que não contêm o atributo:
db.inventory.find({ price: { $not: { $gt: 1.99 } } })

Essa consulta selecionará todos os documentos na coleção inventory cujo valor do atributo price é menor ou igual a 1.99(não é maior que 1.99) ou em que o atributo price não existe.

IMPORTANTE:

a expressão { $not: { $gt: 1.99 } } retorna um resultado diferente do operador $lte. Ao utilizar { $lte: 1.99 }, os documentos retornados serão somente aqueles em que o campo price existe e cujo valor é menor ou igual a 1.99.


Operator $or

O operador $or executa a operação lógica de OU em um array de uma ou mais expressões e seleciona os documentos que satisfaçam ao menos uma das expressões:

Sintaxe:

{ $or: [{ <expression1> }, { <expression2> }, ... , { <expressionN> }] }

db.inventory.find({ $or: [{ qty: { $lt: 20 } }, { price: 10 }] })

Essa consulta selecionará todos os documentos na coleção inventory cujo valor do atributo qty é menor do que 20 ou o valor do atributo price é igual a 10 .


Operator $nor

O operador $or também executa uma operação lógica NEGAÇÃO porém, em um array de uma ou mais expressões, e seleciona os documentos em que todas essas expressões falhem, ou seja, seleciona os documentos em que todas as expressões desse array sejam falsas:

Sintaxe:

{ $nor: [ { <expressão1> }, { <expressão2> }, ...  { <expressãoN> } ] }

db.inventory.find({ $nor: [{ price: 1.99 }, { sale: true }] })

Essa query retorna todos os documentos da coleção inventory que:

  • Contêm o atributo price com o valor diferente de 1.99 e o atributo sale com o valor diferente de true;
  • Ou contêm o atributo price com valor diferente de 1.99 e não contêm o atributo sale;
  • Ou não contêm o atributo price e contêm o atributo sale com valor diferente de true;
  • Ou não contêm o atributo price e nem o atributo sale.

Operator $and

O operador $and executa a operação lógica E num array de uma ou mais expressões e seleciona os documentos que satisfaçam todas as expressões no array. O operador $and usa o que chamamos de avaliação em curto-circuito (short-circuit evaluation). Se alguma expressão for avaliada como falsa, o MongoDB não avaliará as expressões restantes, pois o resultado final sempre será falso independentemente do resultado delas.

Sintaxe:

{ $and: [{ <expressão1> }, { <expressão2> } , ... , { <expressãoN> }] }

Múltiplas expressões especificando o mesmo atributo

db.inventory.find({
    $and: [
        { price: { $ne: 1.99 } },
        { price: { $exists: true } }
    ]
})

Essa consulta selecionará todos os documentos na coleção inventory em que o valor do atributo price é diferente de 1.99 e o atributo price existe.

Múltiplas expressões especificando o mesmo operador

db.inventory.find({
    $and: [
        { price: { $gt: 0.99, $lt: 1.99 } },
        {
            $or: [
                { sale : true },
                { qty : { $lt : 20 } }
            ]
        }
    ]
})

Essa consulta seleciona todos os documentos da coleção inventory em que o valor do campo price é maior que 0.99 e menor que 1.99, E o valor do atributo sale é igual a true, OU o valor do atributo qty é menor do que 20. Ou seja, essa expressão é equivalente a (price > 0.99 E price < 1.99) (onde o E está implícito na vírgula aqui { $gt: 0.99, $lt: 1.99 }) E (sale = true OU qty < 20).


Método sort()

Sintaxe:

db.colecao.find().sort({ "campo": "1 ou -1"})

Quando existe a necessidade de ordenar os documentos por algum atributo, o método sort() se mostra muito útil. Usando um valor positivo (1) como valor do atributo, os documentos da consultas são ordenados de forma crescente ou alfabética (também ordena por campos com strings). Em complemento, usando um valor negativo (-1), os documentos de saída estarão em ordem decrescente ou contra alfabética.

Esse método pode ser combinado com o método find():

db.example.find({}, { "value": 1, "name": 1 }).sort({ "value": -1, "name": 1 })

O sort() só pode ser usado se tiver algum resultado de busca antes:

db.colecao.find().sort({ nomeDoAtributo: 1 }) // certo
db.colecao.sort({ nomeDoAtributo: 1 }) // errado

Removendo documentos

deleteOne() e o deleteMany(). Os dois métodos aceitam um documento como parâmetro, que pode conter um filtro simples ou até mesmo um conjunto de expressões para atender aos critérios de seleção.

deleteOne()

Remove apenas um documento, que deve satisfazer o critério de seleção, mesmo que muitos outros documentos também se enquadrem no criterio. Se nenhum valor for passado como parâmetro, a operação removerá o primeiro documento da coleção. O exemplo abaixo remove o primeiro documento da coleção inventory em que o atributo status é igual a D:

db.inventory.deleteOne({ status: "D" })

deleteMany()

Esse método remove todos os documentos que satisfaçam o critério de seleção. O exemplo abaixo remove todos os documentos da coleção inventory em que o atributo status é igual a A:

db.inventory.deleteMany({ status : "A" })

Para remover todos os documentos da coleção, basta não passar nenhum parâmetro para o método deleteMany():

db.inventory.deleteMany({})

Operadores de Consulta (array)

Operador $all

O operador $all seleciona todos os documentos em que o valor do campo é um array que contenha todos os elementos especificados.Esse operador é equivalente ao operador $and.

db.inventory.find({ tags: { $all: ["red", "blank"] } });

Operador $elemMatch

O operador $elemMatch seleciona os documentos que contêm um campo do tipo array com pelo menos um elemento que satisfaça todos os critérios de seleção especificados. Ou seja, com esse operador você pode especificar várias queries para um mesmo array. Exemplo scores:

{ _id: 1, results: [82, 85, 88] },
{ _id: 2, results: [75, 88, 89] }

A query abaixo seleciona somente os documentos em que o array results contém ao menos um elemento que seja maior ou igual a 80 e menor que 85:

db.scores.find(
  { results: { $elemMatch: { $gte: 80, $lt: 85 } } }
);

Como resultado, apenas o documento com o _id igual a 1 será retornado, já que o 82 satisfaz as duas verificações.


Você pode utilizar o operador $elemMatch em arrays que contenham subdocumentos e especificar vários campos desses subdocumentos como filtro. Veja os seguintes documentos na coleção survey:

{
  _id: 1,
  results: [
    { product: "abc", score: 10 },
    { product: "xyz", score: 5 }
  ]
},
{
  _id: 2,
  results: [
    { product: "abc", score: 8 },
    { product: "xyz", score: 7 }
  ]
},
{
  _id: 3,
  results: [
    { product: "abc", score: 7 },
    { product: "xyz", score: 8 }
  ]
}

A query abaixo selecionará apenas os documentos em que o array results contenha ao menos um elemento subdocumento com o campo product igual a xyz e o campo score maior ou igual a 8:

db.survey.find(
  { results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } }
);

Será retornado apenas o documento com o _id igual a 3.


Operador $expr

O operador $expr permite que você utilize expressões de agregação e construa queries que comparem campos no mesmo documento.

Considere os documentos abaixo na coleção monthlyBudget:

{ _id: 1, category: "food", budget: 400, spent: 450 },
{ _id: 2, category: "drinks", budget: 100, spent: 150 },
{ _id: 3, category: "clothes", budget: 100, spent: 50 },
{ _id: 4, category: "misc", budget: 500, spent: 300 },
{ _id: 5, category: "travel", budget: 200, spent: 650 }

A query abaixo utiliza o operador $expr para buscar os documentos em que o valor de spent exceda o valor de budget:

db.monthlyBudget.find(
  {
    $expr: { $gt: [ "$spent", "$budget" ] }
  }
);

Apenas os seguintes documentos serão retornados:

{ "_id" : 1, "category" : "food", "budget" : 400, "spent" : 450 }
{ "_id" : 2, "category" : "drinks", "budget" : 100, "spent" : 150 }
{ "_id" : 5, "category" : "travel", "budget" : 200, "spent" : 650 }

Nenhum valor foi especificado explicitamente. O que acontece é que o operador $expr entende que deve comparar os valores dos dois campos. Por isso o $ é utilizado, indicando que a string entre aspas referencia um campo.

Operador $regex

O operador $regex fornece os “poderes” das expressões regulares (regular expressions) para seleção de strings.

db.products.find({ sku: { $regex: /789$/ } });

Operador $mod

O operador $mod, que seleciona todos os documentos em que o valor do campo dividido por um divisor seja igual ao valor especificado (ou seja, executa a operação matemática módulo). Considere os seguintes documentos na coleção inventory:

{ _id: 1, item: "abc123", qty: 0 },
{ _id: 2, item: "xyz123", qty: 5 },
{ _id: 3, item: "ijk123", qty: 12 }

A query a seguir seleciona todos os documentos da coleção em que o valor do campo qty módulo 4 seja 0:

db.inventory.find({ qty: { $mod: [4, 0] } });

Então, apenas os seguintes documentos serão retornados:

{ "_id" : 1, "item" : "abc123", "qty" : 0 }
{ "_id" : 3, "item" : "ijk123", "qty" : 12 }

Operador $size

O operador $size seleciona documentos em que um array contenha um número de elementos especificado. Considere a coleção products a seguir, contendo documentos em que o campo tags pode ser um array:

{ _id: 1, tags: ["red", "green"] },
{ _id: 2, tags: ["apple", "lime"] },
{ _id: 3, tags: "fruit" },
{ _id: 4, tags: ["orange", "lemon", "grapefruit"] }

Ao executar a query abaixo, apenas os documentos com o _id igual 1 e 2 serão retornados, pois seus campos tags são arrays e contêm exatamente 2 elementos:

db.products.find(
  { tags: { $size: 2 } }
);

IMPORTANTE: o operador $size aceita apenas valores numéricos, ou seja, ele verifica se um array possui exatamente um certo número de elementos. Por isso, não é possível utilizá-lo, por exemplo, para trazer arrays com comprimento maior do que 2 ($gt: 2). Se você precisar selecionar documentos com base em valores diferentes, a solução é criar um campo que se incremente quando elementos forem adicionados ao array.

Update simples

Método Update

  • db.colecao.updateOne(<filtro>, <update>, <opcoes>) altera apenas o primeiro documento que satisfazer o critério;
  • db.colecao.updateMany(<filtro>, <update>, <opcoes>) altera todos os documentos que satisfazerem o critério;

O método de update pode receber como parâmetro vários operadores diferentes em uma mesma operação:

{
  <operador>: { <campo1>: <valor1>, ... },
  <operador>: { <campo2>: <valor2>, ... },
  ...
}

updateOne()

o método db.colecao.updateOne() é utilizado para alterar o primeiro documento na coleção inventory em que o campo item seja igual a "paper":

db.inventory.updateOne(
  { item: "paper" },
  { $set: { "size.uom": "cm", status: "P" } }
);
  • O primeiro parâmetro é o filtro. Nesse exemplo, um filtro simples de igualdade(mas outros operadores podem ser usados);
  • O segundo é o update em si.Foi utilizado o operador de atualização $set para alterar o valor do campo size.uom para cm e o valor do campo status para P.

⚠️ Chamando o método db.colecao.updateOne() com o parâmetro de filtro vazio { }, o resultado é a atualização do primeiro documento presente em colecao. ⚠️


updateMany()

o método db.colecao.updateMany() é utilizado para alterar todos os documentos da coleção inventory em que o valor do campo qty seja menor do que 50:

db.inventory.updateMany(
  { "qty": { $lt: 50 } },
  { $set: { "size.uom": "in", status: "P" } }
);

Se tiver 10 documentos na coleção inventory em que o valor do campo qty seja menor do que 50 (esse valor foi passado como parâmetro do filtro e utilizou o operador $lt), todos esses documentos serão alterados em uma única operação.

⚠️ Chamando o método db.colecao.updateMany() com o parâmetro de filtro vazio { }, o resultado é a atualização de todos os documentos presentes em colecao. ⚠️


Operador $set

  • $set altera o valor de um campo específico.
  • Se o campo não existir, o operador $set adiciona um novo campo com o valor especificado

Alterando campos no primeiro nível (top-level)

Para o documento que corresponder ao critério de filtro em que o campo _id seja igual a 100, a operação a seguir altera o valor dos campos quantity, details e tags:

db.products.update(
 { _id: 100 },
 { $set: {
     quantity: 500,
     details: { model: "14Q3", make: "xyz" },
     tags: [ "coats", "outerwear", "clothing" ]
   }
 }
);

Alterando campos em documentos embedados

Para alterar campos dentro de subdocumentos, você deve utilizar o mesmo conceito de dot notation.

A operação abaixo altera o valor do campo make dentro do subdocumento details em que o campo _id seja igual a 100:

db.products.update(
  { _id: 100 },
  { $set: { "details.make": "zzz" } }
);

Alterando valores em arrays

A query abaixo tem como critério de seleção o campo _id igual a 100. Ela altera o segundo elemento (índice 1) do array tags e o campo rating no primeiro elemento (índice 0) do array ratings:

db.products.update(
  { _id: 100 },
  { $set: {
      "tags.1": "rain gear",
      "ratings.0.rating": 2
    }
  }
);

Operador $mul

Multiplica o valor de um campo por um número especificado, persistindo o resultado dessa operação sem a necessidade do operador $set. A query abaixo altera esse documento, utilizando o operador $mul para multiplicar os valores dos campos price e qty:

db.products.update(
  { _id: 1 },
  { $mul: { price: NumberDecimal("1.25"), qty: 2 } }
);

O resultado dessa operação é o documento abaixo, em que o novo valor do campo price é o valor original 10.99 multiplicado por 1.25, e o valor do campo qty, que originalmente era 25, é multiplicado por 2:

{ "_id": 1, "item": "ABC", "price": NumberDecimal("13.7375"), "qty": 50 }

Operador $inc

Você pode incrementar ou decrementar valores em um campo específico, utilizando tanto valores positivos quanto negativos.

Esse operador é bastante útil para fazer alterações em campos numéricos sem a necessidade prévia de uma consulta para retornar o valor atual do campo. Com o $inc, em uma única operação isso é possível!

Na operação de update a seguir, o operador $inc é utilizado para decrementar o valor do campo qty em 2 (incrementa em -2) e incrementar o valor do campo metrics.orders em 1:

db.increment.update(
  { sku: "abc123" },
  { $inc: { quantity: -2, "metrics.orders": 1 } }
);

Em uma única chamada ao operador $inc, você consegue aumentar e diminuir os valores de campos diferentes.


Operadores $min e $max

  • $min: Altera o valor do campo atual para o valor passado pelo método se o valor passado pelo método for menor do que o valor do campo atual.
  • $max: Altera o valor do campo atual para o valor passado pelo método se o valor passado pelo método for maior do que o valor do campo atual.

A seguir, vamos aplicar um update utilizando o operador $max. Nosso intuito é atingir todos os documentos com o atributo campo que possuem um valor de no máximo 75. Nesse caso, o operador não só define o escopo máximo, como também o conteúdo que o campo deve passar a ter:

db.collection.updateMany({}, { $max: { campo: 75 } });
db.collection.updateMany({}, { $min: { campo: 42 } });

Comparando datas

db.tags.update(
  { _id: 1 },
  {
    $min: { dateEntered: new Date("2019-09-25") },
    $max: { dateExpired: new Date("2019-10-02") }
  }
);

Operador $currentDate

O operador $currentDate atribui ao valor de um campo a data corrente, utilizando um tipo Date ou timestamp. Se você não especificar o tipo, por padrão, o MongoDB atribui o valor do tipo Date.

Sintaxe:

{ $currentDate: { <campo>: <typeSpecification>, ... } }

typeSpecification pode ser:

  • Um valor booleano true para atribuir o valor da data corrente ao campo utilizando o tipo Date;
  • Um documento que especifica o tipo do campo. Esse documento pode ser { $type: "timestamp" } ou { $type: "date" }. Esse operador é case-sensitive e aceita somente letras minúsculas: timestamp ou date.

Com a operação abaixo, é possível alterar o valor do campo lastModified para a data corrente e criar o campo cancellation.date com o timestamp corrente, utilizando o operador $currentDate, e ainda alterar o campo status para D e criar o campo cancellation.reason com o valor "user request", utilizando o operador $set:

db.customers.updateOne(
  { _id: 1 },
  { $currentDate: {
      lastModified: true,
      "cancellation.date": { $type: "timestamp" }
    }, $set: {
      "cancellation.reason": "user request",
      status: "D"
    }
  }
);

Operador $rename

  • Renomear um determinado atributo de um ou mais documentos.
  • Pode ser utilizado com os métodos updateOne() ou updateMany(), e também pode receber um critério de seleção de documentos.

A operação a seguir altera o nome do campo name para productName no documento em que o valor do campo name seja igual a Banana:

db.fruits.updateOne(
  { name: "Banana" },
  { $rename: {
      "name": "productName"
    }
  }
);

Operador $unset

  • Para remover um ou mais campos de um documento

A operação abaixo remove o campo quantity do documento em que o valor do campo productName seja igual a Banana:

db.fruits.updateMany(
  { productName: "Banana" },
  { $unset: { quantity: "" } }
);

Operador upsert

Usado para atualizar um documento existente ou inserir um novo documento se o documento não existir.Com o upsert não é necessário executar uma operação de verificação de existência separada antes de atualizar ou inserir um documento.

Sintaxe:

db.collection.update(
  { <filtro> },
  { <atualizações> },
  {
    upsert: <booleano>,
    multi: <booleano>
  }
)

Onde:

  • <filtro>: especifica o critério de filtro para localizar o documento a ser atualizado ou inserido.
  • <atualizações>: especifica as modificações a serem aplicadas ao documento encontrado pelo filtro.
  • upsert: um parâmetro booleano opcional que determina se o MongoDB deve inserir um novo documento se nenhum documento for encontrado pelo filtro. Se definido como true, um novo documento será criado. Se definido como false, nenhuma operação será realizada se o filtro não encontrar um documento correspondente.
  • multi: um parâmetro booleano opcional que determina se a operação de atualização deve afetar vários documentos. Se definido como true, a operação será aplicada a todos os documentos correspondentes ao filtro. Se definido como false, a operação será aplicada apenas ao primeiro documento correspondente.
db.pessoas.update(
   { cpf: "123.456.789-00" },
   { $set: { nome: "João" } },
   { upsert: true }
)

Este código tentará encontrar um documento na coleção pessoas com o CPF "123.456.789-00". Se encontrar um documento, atualizará o campo "nome" para "João". Se não encontrar nenhum documento, criará um novo documento com o CPF "123.456.789-00" e o campo "nome" definido como "João". O parâmetro upsert é definido como true, indicando que um novo documento deve ser criado se nenhum for encontrado.

Update Complexos

Operador $push

O operador $push adiciona um valor a um array. Se o campo não existir no documento, um novo array com o valor em um elemento será adicionado.

Em conjunto com o $push você pode utilizar o que chamamos de modificadores:

  • $each: Adiciona múltiplos valores a um array;
  • $slice: Limita o número de elementos do array. Requer o uso do modificador $each;
  • $sort: Ordena os elementos do array. Requer o uso do modificador $each;
  • $position: Especifica a posição do elemento que está sendo inserido no array. Também requer o modificador $each. Sem o modificador $position, o operador $push adiciona o elemento no final do array.

Quando utilizar um modificador, o processo de push ocorre na seguinte ordem, independentemente da ordem em que os modificadores aparecem:

  1. Altera o array para adicionar os elementos na posição correta;
  2. Aplica a ordenação ($sort), se especificada;
  3. Limita o array ($slice), se especificado;
  4. Armazena o array.

Adicionando um valor ao array:

use sales;
db.supplies.updateOne(
  { _id: 1 },
  {
    $push: {
      items: {
        "name": "notepad",
        "price":  35.29,
        "quantity": 2,
      },
    },
  },
  { upsert: true },
);

Adicionando múltiplos valores a um array:

É possível adicionar múltiplos valores a um array utilizando o operador $push, mas dessa vez será necessário adicionar o modificador $each.

A operação abaixo adicionará mais dois produtos ao array items do primeiro documento na coleção supplies:

db.supplies.updateOne(
  {},
  {
    $push: {
      items: {
        $each: [
          {
            "name": "pens",
            "price": 56.12,
            "quantity": 5,
          },
          {
            "name": "envelopes",
            "price": 19.95,
            "quantity": 8,
          },
        ],
      },
    },
  },
  { upsert: true },
);

Múltiplos modificadores

O $push pode ser utilizado com múltiplos modificadores, fazendo várias operações ao mesmo tempo em um array.

db.supplies.updateOne(
  { _id: 1 },
  {
    $push: {
      items: {
        $each: [
          {
            "name" : "notepad",
            "price" : 35.29,
            "quantity" : 2,
          },
          {
            "name": "envelopes",
            "price": 19.95,
            "quantity": 8,
          },
          {
            "name": "pens",
            "price": 56.12,
            "quantity": 5,
          },
        ],
        $sort: { "quantity": -1 },
        $slice: 2,
      },
    },
  },
  { upsert: true },
);
  • O modificador $each para adicionar múltiplos documentos ao array items;
  • O modificador $sort para ordenar todos os elementos alterados no array items pelo campo quantity em ordem decrescente;
  • E o modificador $slice para manter apenas os dois primeiros elementos ordenados no array items.

Operador $pop

Uma maneira simples de remover o primeiro ou o último elemento de um array é utilizar o operador $pop. Passando o valor -1 ao operador $pop você removerá o primeiro elemento. Já ao passar o valor 1, você removerá o último elemento do array

Removendo o primeiro item de um array

db.supplies.updateOne({ _id: 1 }, { $pop: { items: -1 } });

Removendo o último item de um array

db.supplies.updateOne({ _id: 1 }, { $pop: { items: 1 } });

Operador $pull

O operador $pull remove de um array existente todos os elementos com um ou mais valores que atendam à condição especificada.

Removendo todos os itens iguais a um valor especificado:

O operador $pull remove de um array existente todos os elementos com um ou mais valores que atendam à condição especificada. Digamos que você queira remover do array items os elementos pens e envelopes:

db.supplies.updateMany(
  {},
  {
    $pull: {
      items: {
        name: { $in: ["pens", "envelopes"] },
      },
    },
  },
);

Na atualização acima, foi utilizado o operador $pull combinado com o operador $in para alterar o array items

Removendo todos os itens que atendam a uma condição diretamente no $pull

db.profiles.updateOne(
  { _id: 1 },
  {
    $pull: {
      votes: { $gte: 6 },
    },
  },
);

Operador $addToSet

O operador $addToSet é utilizado quando você precisa garantir que os valores de um array não sejam duplicados. Ou seja, ele garante que apenas valores únicos estejam presentes no array.

Você precisa ter em mente três aspectos sobre o $addToSet:

  • Se você utilizá-lo em um campo que não existe no documento alterado, ele criará um campo do tipo array com o valor especificado na operação;
  • Se você utilizá-lo em um campo já existente no documento, mas esse campo não for um array, a operação não funcionará;
  • Se o valor passado for um documento, o MongoDB o considerará como duplicado se um documento existente no array for exatamente igual ao documento a ser adicionado, ou seja, possui os mesmos campos com os mesmos valores e esses campos estão na mesma ordem.

Adicionando ao array

A operação abaixo adiciona o elemento “accessories” ao array tags desde que “accessories” não exista no array:

db.inventory.updateOne(
  { _id: 1 },
  { $addToSet: { tags: "accessories" } },
);

Com o modificador $each

Você pode utilizar o operador $addToSet combinado com o modificador $each. Esse modificador permite que você adicione múltiplos valores a um array.

A operação abaixo utiliza o operador $addToSet e o modificador $each para adicionar alguns elementos a mais no array tags:

db.inventory.updateOne(
  { _id: 2 },
  {
    $addToSet: {
      tags: {
        $each: ["camera", "electronics", "accessories"],
      },
    },
  },
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment