DEV Community

Cover image for Operações de CRUD com MongoDB
Marcelo Michels
Marcelo Michels

Posted on • Updated on

Operações de CRUD com MongoDB

Gostaria de compartilhar com vocês e também para consulta própria no futuro, algumas das operações disponíveis no MongoDB para inserir, atualizar, buscar e deletar dados em coleções de documentos no MongoDB.

Vamos começar criando uma coleção de documentos chamada posts, onde vamos inserir alguns documentos que representam um post feito em um blog, depois vamos manipular suas informações.

// Input
db.createCollection("posts");
// Output
{
    "ok" : 1
}
Enter fullscreen mode Exit fullscreen mode

Pronto, já temos nossa coleção chamada posts.

Inserindo documentos

Como estamos trabalhando com um banco de dados orientado a documentos, isso significa que cada registro em nosso banco é um documento. Esse documento basicamente é um JSON qual podemos adicionar nossas informações, incluindo sub documentos e sub listas de documentos. Lembrando que cada documento de uma coleção não pode passar de 16MB de dados. Também não pode ultrapassar 100 níveis de sub documentos.

Inserindo um documento

Vamos inserir um documento que representa nosso post do blog, utilizando a função insertOne.

// Input
db.posts.insertOne({
  title: "Introdução a banco de dados NoSQL",
  content: "...",
  categories: [ "database", "nosql", "mongodb"],
  author: { name: "Marcelo Michels", about: "..."},
  likes: 0
});
// Output
{
    "insertedId" : ObjectId("601ea27a4fb18f6b8e31fd3c")
}
Enter fullscreen mode Exit fullscreen mode

A função insertOne retornou um insertedId que vai ser o identificador do nosso documento. Esse identificador que o MongoDB gerou automaticamente vai ficar salvo dentro de um campo do nosso documento chamado _id. Caso seja informado um campo chamado _id dentro do nosso JSON que estamos salvando, o MongoDB não vai gerar um novo valor para ele, e vai considerar a informação que estamos passando.

Inserindo vários documentos ao mesmo tempo

Também podemos inserir mais do que um documento ao mesmo tempo utilizando a função insertMany.

// Input
db.posts.insertMany([
  {
    title: "Introdução a Rust",
    content: "...",
    categories: ["languages", "rust"],
    author: { name: "Marcelo Michels", about: "..." },
    likes: 0,
  },
  {
    title: "Fazendo backup automatizado do MongoDB",
    content: "...",
    categories: ["database", "nosql", "mongodb", "infra"],
    author: { name: "Marcelo Michels", about: "..." },
    likes: 0,
  },
  {
    title: "Performance para páginas WEB",
    content: "...",
    categories: ["performance", "front-end"],
    author: { name: "Marcelo Michels", about: "..." },
    likes: 0,
  },
  {
    title: "Introdução a PWA",
    content: "...",
    categories: ["front-end", "pwa"],
    author: { name: "Joaquim Augusto Michels", about: "..." },
    likes: 0,
  },
]);
// Output
{
    "insertedIds" : [
        ObjectId("601ed2614fb18f6b8e31fd43"),
        ObjectId("601ed2614fb18f6b8e31fd44"),
        ObjectId("601ed2614fb18f6b8e31fd45"),
        ObjectId("601ed2614fb18f6b8e31fd46")
    ]
}
Enter fullscreen mode Exit fullscreen mode

Buscando por documentos

Com alguns registros já inseridos na nossa coleção de posts, já podemos buscar as informações que tem nela. Abaixo veremos algumas das operações de buscas que temos.

Buscando todos os documentos da coleção

Para buscar todos os registros de uma coleção usaremos o a função find.

// Input
db.posts.find({});
// Output
[
  {
    "_id" : ObjectId("601ed2504fb18f6b8e31fd42"),
    "title" : "Introdução a banco de dados NoSQL",
    "content" : "...",
    "categories" : [ "database", "nosql", "mongodb" ],
    "author" : { "name" : "Marcelo Michels", "about" : "..." },
    "likes" : 0
  }
,
  ...
]
// colei aqui apenas a primeira linha do que foi retornado
// mas no total foram 5 documentos quais inserimos anteriormente
Enter fullscreen mode Exit fullscreen mode

Podemos observar que dentro de cada documento temos o campo _id ObjectId que foi gerado automaticamente pelo MongoDB para cada registro

Buscando por algum campo especifico

Para buscar um documento a partir de alguma referencia que necessitamos basta passarmos um JSON para função find. Nesse JSON vamos passar apenas os campos quais queremos fazer a busca, no exemplo abaixo estamos passando um JSON contendo apenas o campo chamado title, isso significa que todos os documentos que tiverem o title igual ao que estamos passando no JSON serão retornando na nossa consulta.

// Input
db.posts.find({title: "Introdução a PWA"});
// Output
{
    "_id" : ObjectId("601ed2614fb18f6b8e31fd46"),
    "title" : "Introdução a PWA",
    "content" : "...",
    "categories" : [  "front-end", "pwa" ],
    "author" : { "name" : "Marcelo Michels", "about" : "..." },
    "likes" : 0
}
Enter fullscreen mode Exit fullscreen mode

Definindo quais campos do documento queremos que sejam retornados

Na função find podemos passar no primeiro parâmetro um JSON para a consulta que desejamos, assim como também podemos passar no segundo parâmetro quais campos dos documentos queremos que sejam retornados para utilizarmos.
No exemplo abaixo vamos passar no primeiro parâmetro {}, isso vai retornar todos os posts, no segundo parâmetro vamos passar o JSON { title: 1} o que sinaliza que queremos que seja retornado apenas o campo title de cada documento, porem o campo _id sempre vai ser retornado, a não ser que indiquemos que não o queremos da seguinte forma { _id: 0, title: 1}, ou seja, nesse segundo JSON passamos 0 para os campos que não queremos e 1 para os campos que queremos.

// Input
db.posts.find({}, { _id: 0, title: 1 });
// Output
[
  { title: "Introdução a banco de dados NoSQL" },
  { title: "Introdução a Rust" },
  { title: "Fazendo backup automatizado do MongoDB" },
  { title: "Performance para páginas WEB" },
  { title: "Introdução a PWA" },
];
Enter fullscreen mode Exit fullscreen mode

Busca com paginação

Em casos onde temos muitos documentos, buscar esses documentos em quantidades menores pode ser uma boa opção, para isso podemos acrescentar ao find as funções skip e limit onde define quantos registros ignorar e quantos registros retornar, respectivamente.

// Input
db.posts.find({}, { _id: 0, title: 1 }).skip(1).limit(3);
// Output
[
  { title: "Introdução a Rust" },
  { title: "Fazendo backup automatizado do MongoDB" },
  { title: "Performance para páginas WEB" },
];
Enter fullscreen mode Exit fullscreen mode

Buscando documentos com expressões regulares

No JSON que passamos para a função find também podemos passar expressões regulares, ampliando nossas possibilidades de buscas, permitindo por exemplo, buscar todos os usuários que tenham um e-mail valido, entre outros tipos de validações, no exemplo atual vamos buscar por todos os posts que contenham no titulo do post a palavra Introdução e vamos querer apenas o title de cada post.

// Input
db.posts.find({ title: /Introdução/ }, { _id: 0, title: 1 });
// Output
[
  { title: "Introdução a banco de dados NoSQL" },
  { title: "Introdução a Rust" },
  { title: "Introdução a PWA" },
];
Enter fullscreen mode Exit fullscreen mode

Buscando documentos a partir de informações de sub documentos

Nosso documento de posts contem dentro dele um sub documento que contem os dados do autor, caso queiramos buscar todos os documentos de posts filtrando pelos dados do sub documento author também é possível e muito fácil.

// Input
db.posts.find(
  { "author.name": "Joaquim Augusto Michels" },
  { _id: 0, title: 1 }
);
// Output
[{ title: "Introdução a PWA" }];
Enter fullscreen mode Exit fullscreen mode

Buscando documentos a partir de informações de sub listas

Vamos buscar um documento a partir de uma informação que está dentro de uma sub lista no nosso documento, que no caso é a lista de categorias que ficam dentro do campo categories.

// Input
db.posts.find({ categories: "database" }, { _id: 0, title: 1 });
// Output
[
  { title: "Introdução a banco de dados NoSQL" },
  { title: "Fazendo backup automatizado do MongoDB" },
];
Enter fullscreen mode Exit fullscreen mode

Buscando documentos utilizando operador $in

Mongo nos ofere alguns operadores para agregamos mais poderes em nossas buscas, um deles é o $in, podemos encontrar mais alguns na documentação em https://docs.mongodb.com/manual/reference/operator/.

// Input
db.posts.find(
  { categories: { $in: ["infra", "performance"] } },
  { _id: 0, title: 1 }
);
// Output
[
  { title: "Fazendo backup automatizado do MongoDB" },
  { title: "Performance para páginas WEB" },
];
Enter fullscreen mode Exit fullscreen mode

Atualizando documentos

Já aprendemos inserir e buscar dados em uma coleção do MongoDB, agora vamos atualizar alguns desses documentos para depois realizarmos umas consultas mais avançadas.

Substituindo um documento inteiro

Utilizaremos a função updateOne qual no primeiro parâmetro espera um JSON para localizar o
Quando queremos substituir todas as informações do documento por um novo documento passamos no segundo parâmetro um operador $replaceWith que é onde vai ser passado o novo documento a

// Input
db.posts.updateOne(
  { title: "Performance para páginas WEB" },
  [
    {
      "$replaceWith": {
        title: "Performance em páginas WEB",
        content: "...",
        categories: ["performance", "front-end"],
        author: { name: "Marcelo Michels", about: "..." },
        likes: 0,
      },
    },
  ]
);
// Output
{
    "matchedCount" : 1,
    "modifiedCount" : 1
}
Enter fullscreen mode Exit fullscreen mode

Atualizando parte de um documento

Para atualizar parte de um documento utilizaremos o operador $set no lugar de $replaceWith, dessa forma o JSON que passarmos dentro desse operador será adicionado ao documento sem modificar as demais informações do documento (como se fosse um merge entre o documento que já está salvo e o JSON que estamos enviando no $set).
Dessa forma vamos atualizar a quantidade de likes de um post para 1.

// Input
db.posts.updateOne(
  { title: "Introdução a banco de dados NoSQL" },
  [
    {
      "$set": {
        likes: 1,
      },
    },
  ]
);
// Output
{
    "matchedCount" : 1,
    "modifiedCount" : 1
}
Enter fullscreen mode Exit fullscreen mode

Atualizando muitos documentos

Caso queira atualizar muitos documentos utilizaremos a função updateMany, onde pode atualizar mais que um documento na mesma operação, assim todos os documentos que se aplicarem na query no primeiro parâmetro serão atualizados. Da mesma forma que buscamos todos os documentos passando um JSON vazio, para atualizar todos os documentos passamos um JSON vazio também na query do nosso updateMany.

// Input
db.posts.updateMany(
  { },
  [
    {
      "$set": {
        published: true,
      },
    },
  ]
);
// Output
{
    "matchedCount" : 5,
    "modifiedCount" : 5
}
Enter fullscreen mode Exit fullscreen mode

Com a operação acima todos os nossos posts receberam o campo published com valor true.

Atualizando campo de um documento de forma incremental

Seguindo o comando anterior $set, cada vez que um post receber um like teríamos que buscar o post para saber quantos likes ele tinha para adicionar mais 1 nesse valor e salvar a informação novamente, mas com o operador $inc podemos apenas incrementar o valor que já temos salvo com o valor que queremos incrementar.

// Input
db.posts.updateOne(
  { title: "Introdução a banco de dados NoSQL" },
  {
    "$inc": {
      likes: 1,
    },
  }
);
// Output
{
    "matchedCount" : 1,
    "modifiedCount" : 1
}
Enter fullscreen mode Exit fullscreen mode

Atualizando sub lista de documento com novos registros

Vamos imaginar os comentários de um post, caso queiramos gravar eles dentro de uma sub lista do nosso documento vamos precisar utilizar o operador $push

// Input
db.posts.updateOne(
  { title: "Introdução a banco de dados NoSQL" },
  {
    "$push": {
      "comments": {
        "$each": [{
          "name" : "Marcelo"
          "message": "Muito legal, parabéns"
        }]
      }
    }
  }
);
// Output
{
    "matchedCount" : 1,
    "modifiedCount" : 1
}
Enter fullscreen mode Exit fullscreen mode

Deletando documentos

Com base no conhecimento nas operações que já temos deletar um documento não se torna muito diferente do que já aprendemos, então segue abaixo um exemplo com a utilização da função remove, usando também um operador novo $lte (qual também pode ser usado no find) que retorna todos os documentos que tenham um determinado campo com valor menor do que estamos passando na query.
Com o remove abaixo estamos removendo todos posts que o campo likes seja menor ou igual a 1.

// Input
db.posts.remove({ "likes": { "$lte": 1 } });
// Output
Removed 4 record(s)
Enter fullscreen mode Exit fullscreen mode

Consulte também outros operador de maior e menor https://docs.mongodb.com/manual/reference/operator/query-comparison/

Conclusão

Se você executou todos os comandos que aprendemos aqui, na nossa coleção de posts deve ter sobrado apenas um único documento igualmente o que consta abaixo.

{
    "_id" : ObjectId("601ed2504fb18f6b8e31fd42"),
    "title" : "Introdução a banco de dados NoSQL",
    "content" : "...",
    "categories" : [
        "database",
        "nosql",
        "mongodb"
    ],
    "author" : {
        "name" : "Marcelo Michels",
        "about" : "..."
    },
    "likes" : 2,
    "published" : true,
    "comments" : [
        {
            "name" : "Marcelo",
            "message" : "Muito legal, parabéns"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Espero utilizar desses exemplos no futuro e espero que possa ser útil para alguém também.

Latest comments (2)

Collapse
 
leandroats profile image
Leandro Torres • Edited

Excelente post. Obrigado por compartilhar seu conhecimento.

Collapse
 
bgcorazza profile image
Bruno Corazza

Muito bom.
Didático e direto!
Obrigado pelas informações.