Roberto Umbelino
28/1/2022 Roberto Umbelino

Filtros no Mongo

blog-feature-image

Falaaa meus devs desse Brasilsão, dessa vez vamos para um conteúdo de banco de dados, filtros no queridíssimo MongoDB. ✌️

📑 Sobre

Primeiramente vou falar um pouco sobre O que é o MongoDB e as suas principais características, só para todo mundo ficar na mesma página. 😉

Antes de mais nada só para deixar claro, MongoDB é um banco de dados.😅

⭐ Open Source

É um projeto de código aberto, onde a comunidade consegue colaborar (Você, Eu, qualquer dev 💪). Atualmente há um suporte especial pela empresa MongoDB, a mesma que fornece o serviço Mongo Atlas focado em distribuir banco de dados Mongo em Cloud.


⭐ Alta performance e flexibilidade

Utilizado em projetos onde o volume de dados é gigante, pois possui uma boa performance e flexibilidade para trabalhar com os dados.


⭐ Um banco NoSQL

É o principal banco NoSQL (Não relacional). O Mongo trabalha com coleções e documentos no formato de JSON diferente dos bancos relacionais tradicionais (MySQL, PostgreSQL) que utilizam tabelas, linhas e colunas.


Mas bora falar sobre as Consultas e Filtros no MongoDB. 🤓


📖 Consultas

As consultas parecem ser bem simples e fáceis de fazer, mas as vezes há umas pegadinhas e trabalhar com filtros pode não ser tão simples assim.

Então antes de falarmos sobre os filtros, vou listar umas dicas gerais para as consultas.

⭐ Documento

Independente do tipo de consulta, do filtro aplicado, sempre será retornado um documento completo (Exceto se for criado uma agregação).

Exemplo.

[
  {
    "dev": "Galactic Dev",
    "techs":  [
      {
        "name": "NodeJS",
        "experience": 3
      },
      {
        "name": "ReactJS",
        "experience": 1
      },
      {
        "name": "MongoDB",
        "experience": 1
      },
      {
        "name": "PHP",
        "experience": 4
      },
    ]
  }
]

Dado esse documento, digamos que queremos buscar os dados onde a experiência do dev em uma determinada tecnologia é maior que 2. Então eu faço um filtro para isso, o resultado esperado seria apenas NodeJS e PHP, pois as duas tecnologias tem experiência acima de 2.

Todavia não é isso que acontece, o resultado é um documento completo, incluindo as tecnologias com experiência abaixo de 2.

Observação: Lembrando que esse cenário se aplica se eu somente realizar um filtro, porém podemos obter esse resultado com o próximo tópico.


⭐ Agregação de informação

É possível moldar a resposta gerando outra informação, como no exemplo acima, eu posso adaptar meu documento a trazer somente as tecnologias com a experiência acima de 2. Também é possível gerar outros tipos de informação através dos dados, como agrupar registros, fazer uma soma, pegar a quantidade de determinados registros, etc.


⭐ Filtros

É possível filtrar os dados que constam no documento e também navegar por todo o JSON e filtrar exatamente o que necessita.


🔎 Filtros principais

Agora chegou a hora, vamos ver alguns filtros básicos que podem ser utilizados nas consultas.

⭐ Comparação simples =

A comparação de igual é a mais simples de um banco de dados, então vamos ver como é feita no MongoDB.

Primeiramente vamos imaginar nosso banco de dados. (Lembra que comentei que cada registro no banco é um documento no formato JSON)

[
  {
    "_id": ObjectId("61ec82e2497214f02db4bf56") // Id do documento gerado pelo mongo
    "name": "João",
    "age": 20
  },
  {
    "_id": ObjectId("61ec834f4f53a88768283915") // Id do documento gerado pelo mongo
    "name": "Maria",
    "age": 21
  },
  {
    "_id": ObjectId("61ec8353e5dffd29a9f0cc10") // Id do documento gerado pelo mongo
    "name": "Pedro",
    "age": 25
  }
]

Certo, agora vamos fazer um filtro utilizando o operador Igual.

{ "name": "Maria" }

Esse filtro irá retornar apenas os documentos que a propriedade “name” for igual a “Maria”. (No caso somente Maria)

Outro exemplo.

{ "age": 25 }

Esse filtro irá retornar apenas os documentos que a propriedade “age” for igual a 25. (No caso somente Pedro)


⭐ Operador maior, menor, igual >, <, >=, <=

Agora vamos ver como realizamos um filtro onde determinado valor é (maior, menor, igual) a outro.

Novamente vamos imaginar nosso banco de dados.

[
  {
    "_id": ObjectId("61ec82e2497214f02db4bf56") // Id do documento gerado pelo mongo
    "name": "João",
    "age": 20
  },
  {
    "_id": ObjectId("61ec834f4f53a88768283915") // Id do documento gerado pelo mongo
    "name": "Maria",
    "age": 21
  },
  {
    "_id": ObjectId("61ec8353e5dffd29a9f0cc10") // Id do documento gerado pelo mongo
    "name": "Pedro",
    "age": 25
  }
]

Bora para os filtros.

  • Maior >
{ "age": { $gt: 20 } } //gt signifca Greater Than (Maior que)

Esse filtro irá retornar apenas os documentos que a propriedade “age” for maior que 20. (No caso Maria e Pedro)

  • Menor <
{ "age": { $lt: 25 } } //lt signifca Less Than (Menor que)

Esse filtro irá retornar apenas os documentos que a propriedade “age” for menor que 25. (No caso João e Maria)

  • Maior ou Igual >=
{ "age": { $gte: 20 } } //gte signifca Greater Than or Equal (Maior que ou Igual a)

Esse filtro irá retornar apenas os documentos que a propriedade “age” for maior ou igual a 20. (No caso irá trazer todos os documentos)

  • Menor ou Igual <=
{ "age": { $lte: 25 } } //lte signifca Less Than or Equal (Menor que ou Igual a)

Esse filtro irá retornar apenas os documentos que a propriedade “age” for menor ou igual a 25. (No caso irá trazer todos os documentos)


⭐ Comparação com Like LIKE '%filter%', LIKE '%filter', LIKE 'filter%'

Outro operador bem bacana para filtro é o Like, ele irá filtrar os documentos que contenham determinado valor.

Então vamos pensar nessa determinada base.

[
  {
    "_id": ObjectId("61ec82e2497214f02db4bf56")
    "name": "Maria Isabel"
  },
  {
    "_id": ObjectId("61ec87732f0d96b01886bcf5")
    "name": "Maria Eduarda"
  },
  {
    "_id": ObjectId("61ec877724604d424265e37e")
    "name": "Eduarda Fonseca"
  },
  {
    "_id": ObjectId("61ec8779a413357651e459fb")
    "name": "Ana Maria"
  }
]

Uma base simples só para demonstrar os exemplos.

  • Entre LIKE '%filter%'
{ "name": { $regex: 'Maria' } }

Irá retornar todos os registros que possuem “Maria” no nome. (Nesse exemplo, Maria Isabel, Maria Eduarda e Ana Maria)

  • Começo LIKE 'filter%'
{ "name": { $regex: '^Maria' } }

Irá retornar todos os registros que começam com “Maria” no nome. (Nesse exemplo, Maria Isabel e Maria Eduarda)

  • Final LIKE '%filter'
{ "name": { $regex: 'Eduarda$' } }

Irá retornar todos os registros que terminam com “Eduarda” no nome. (Nesse exemplo, somente a Maria Eduarda)


⭐ Múltiplas comparações AND, OR

Múltiplas operações é muito comum nas consultas de banco de dados, no MongoDB não é diferente.

Vamos ver, como é simples o uso dessas múltiplas comparações no MongoDB.

Nossa base de dados para exemplo.

[
  {
    "_id": ObjectId("61ec82e2497214f02db4bf56")
    "name": "Maria Isabel",
    "age": 23
  },
  {
    "_id": ObjectId("61ec87732f0d96b01886bcf5")
    "name": "Maria Eduarda",
    "age": 19
  },
  {
    "_id": ObjectId("61ec877724604d424265e37e")
    "name": "Eduarda Fonseca",
    "age": 26
  },
  {
    "_id": ObjectId("61ec8779a413357651e459fb")
    "name": "Ana Maria",
    "age": 22
  }
]

Vamos aos exemplos.

  • E AND

O operador AND é possível fazer de duas formas, da implícita ou explícita.

{ "name": { $regex: 'Maria' }, "age": { $gt: 20 } } // AND implícito


{
  $and: [
    { "name": { $regex: 'Maria' } },
    { "age": { $gt: 20 } }
  ]
} // AND explícito

Irá retornar todos os registros que possuem “Maria” no nome E que a idade seja maior que 20. (Nesse exemplo, Maria Isabel e Ana Maria)

  • OU OR
{
  $or: [
    { "name": { $regex: 'Maria' } },
    { "age": { $gt: 20 } }
  ]
}

Irá retornar todos os registros que possuem “Maria” no nome OU que a idade seja maior que 20. (Nesse exemplo serão todos os registros)


⭐ Comparações em lista

Em algum momento você vai precisar filtrar um valor que está contido em uma lista, e aqui tem uma pegadinha que vale ressaltar.

Vamos imaginar nossa base para esse exemplo.

[
  {
    "_id": ObjectId("61ec82e2497214f02db4bf56")
    "name": "Maria Isabel",
    "age": 23,
    "residences": [
      {
        "city": "Blumenau",
        "type": "House"
      },
      {
        "city": "Balneário Camboriú",
        "type": "Apartment"
      },
      {
        "city": "Balneário Camboriú",
        "type": "House"
      }
    ]
  },
  {
    "_id": ObjectId("61ec87732f0d96b01886bcf5")
    "name": "João Fernandes",
    "age": 17,
    "residences": [
      {
        "city": "Timbó",
        "type": "House"
      },
      {
        "city": "Penha",
        "type": "Apartment"
      }
    ]
  }
]

Certo, visualizando essa base, digamos que eu queira fazer uma consulta que me retorne todos os registros que a residência seja de Blumenau e que seja o tipo Apartment.

Então eu faria o seguinte filtro.

{ "residences.city": "Blumenau", "residences.type": "Apartment" }

Se dermos uma olhada na base, iremos notar que nenhum registro se encaixa nesse filtro, logo deveria retornar nenhum registro. Mas não é isso que acontece, será retornado o registro que contém a Maria Isabel.

[
  {
    "_id": ObjectId("61ec82e2497214f02db4bf56")
    "name": "Maria Isabel",
    "age": 23,
    "residences": [
      {
        "city": "Blumenau",
        "type": "House"
      },
      {
        "city": "Balneário Camboriú",
        "type": "Apartment"
      },
      {
        "city": "Balneário Camboriú",
        "type": "House"
      }
    ]
  }
]
  • Mas o porquê disso? 🤔

Quando os filtros são realizados em cima de uma lista, o MongoDB interpreta de outra maneira, os filtros são tratados de forma individual, ou seja, nesse filtro aplicado ele procurou uma residência que seja de Blumenau (E isso realmente existe, mas com o type House), logo em seguida ele realizou outra condição, que na lista deve haver um tipo Apartment (E também existe, mas na cidade Balneário Camboriú). As duas condições deram verdadeiras, poir isso foi retornado esse documento.

  • E como faço para filtrar em conjunto? 🤔

Agora sim vem um operador muito legal no MongoDB, o $elemMatch, com ele é possível realizar um filtro em conjunto sobre uma lista.

Vamos ver como seria esse filtro.

{
  "residences": {
    $elemMatch: {
      "city": "Blumenau",
      "type": "Apartment"
    }
  }
}

Não irá retornar nenhum registro, pois não há nenhum documento que contenha uma residência em Blumenau que seja do tipo Apartment.


🧾 Conclusão

Quando se entende bem como o MongoDB interpreta os filtros fica bem mais fácil trabalhar e também muito prático.

Há uma grande variedade de operadores para realizar filtros no MongoDB, mas que vão ficar para próxima 😁, porque esse post vai chegando ao seu fim.

Espero que esse conteúdo tenha ajudado a entender um pouquinho melhor alguns dos operadores do MongoDB. 💪🏻


🔗 Referências

Você pode estudar um pouco mais do assunto nos links:


Se você curtiu esse conteúdo deixe o seu like e compartilhe com a galera. 😋

Roberto Umbelino.

comments powered by Disqus

NOS ACOMPANHE NAS REDES SOCIAIS