DEV Community

Pedro Victor
Pedro Victor

Posted on • Edited on

Filtrando campos retornados em buscas com MongoDB

Filtrando campos em SQL

Se você já usou bancos relacionais, com certeza já se deparou com as famosas querys de busca, coisas como:

select nome, idade from usuario
Enter fullscreen mode Exit fullscreen mode

Muito comuns e úteis, já que nem sempre queremos todas as colunas de uma tabela.

Mas e no MongoDB ?

Bom, geralmente aprendemos em vários eventos e cursos as funções básicas para fazer o famoso CRUD (Create, read, update, delete), com mongoose, que são ótimos para dar uma base prática a quem acaba de conhecer a tecnologia e dar ideias de desafios para quem já domina a tecnologia, nesses cursos aprendemos a fazer buscar com condições como essa:

const user = await User.find({name: "Nome do alvo"})
Enter fullscreen mode Exit fullscreen mode

E como sabemos, isso retorna todo o Schema (modelo especificado por nós do documento) do usuário, cujo nome seja "Nome do alvo". Vamos supor que esse seja o Schema do User:

const UserSchema = new mongoose.Schema({
    name: {
        required: true,
        type: String,
        unique: false
    },
    githubUser: {
        required: true,
        type: String, 
        unique: true
    },
    bio: {
        required: false,
        type: String,
        unique: false
    },
    avatar_url: {
        required: true,
        type: String,
        unique: true
    },
    techs: [String]
    githubFollowers: [UserSchema],
    githubFollowing: [UserSchema]
});
Enter fullscreen mode Exit fullscreen mode

Suponha que em dado momento da nossa aplicação, somente nos importe buscar os dados { name, githubUser, avatar_url }, não faz sentido buscarmos todos os dados se apenas queremos estes!

O segundo parâmetro do método find

Para resolvermos esse problema da requisição desnecessária de campos, podemos usar o segundo parâmetro do métodos find, chamado Projection, um JSON em que podemos filtrar quais campos queremos que sejam retornados, ou não, exemplo:

/*
  O 1 indica a inclusão do campo no retorno da query
  os demais campos não serão inclusos
*/
{
 name: 1,
 githubUser: 1,
 avatar_url: 1
}
/*
  O 0 indica a exclusão do campo no retorno da query
  os demais campos serão inclusos
*/
{
 bio: 0,
 techs: 0,
 githubFollowers: 0,
 githubFollowing: 0
}
Enter fullscreen mode Exit fullscreen mode

IMPORTANTE: NÃO SE PODE MISTURAR 1s E 0s NA MESMA PROJEÇÃO!

Assim, temos o mesmo resultado nos dois casos! Filtramos então os campos para recebermos { name, githubUser, avatar_url }!

Mas como ficaria isso no código? Como se parece a resposta dessa query?

//Query
const result = await Dev.find({name: "Algum nome"},{name:1, githubUser: 1, avatar_url: 1})

//Resposta
 {
    "_id": "Array do ID",
    "name": "Pedro Victor",
    "githubUser": "stormsamurai1",
    "avatar_url": "https://avatars2.githubusercontent.com/u/37453874?v=4"
  }
Enter fullscreen mode Exit fullscreen mode

PROBLEMA DE VIRTUALS!!!

Se você usa algum campo virtual no seu modelo, provavelmente vai se deparar com um problema: Os campos virtuais não são afetados.
Bem, isso ocorre por eles não persistirem no banco de dados, e, por isso, não temos tanto controle, mas isso não será um problema, podemos adicionar uma função a mais para remover esses campos e resolver o empecilho. Trata-se da função lean()

//Antes do lean
{
    "_id": "Array do ID",
    "name": "Pedro Victor",
    "githubUser": "stormsamurai1",
    "avatar_url": "https://avatars2.githubusercontent.com/u/37453874?v=4",
    "virtual_field": "virtual result",
    "id": "5e7aa3fc0cf9ea14d47fa461"
}
Enter fullscreen mode Exit fullscreen mode
//Query atualizada
const result = await Dev.find({},{name:1, githubUser:1, avatar_url:1}).lean()
Enter fullscreen mode Exit fullscreen mode
//Resultado atualizado
{
    "_id": "Array do ID",
    "name": "Pedro Victor",
    "githubUser": "stormsamurai1",
    "avatar_url": "https://avatars2.githubusercontent.com/u/37453874?v=4",
}   
Enter fullscreen mode Exit fullscreen mode

Conclusão

Apesar de ser um tema básico, é algo que senti vontade de escrever, via poucas pessoas utilizando essas funções e vi uma boa oportunidade de explorar o tema, pesquisar e começar com um projeto de escrita sobre coisas que aprendi. Qualquer dúvida que tenha, entre em contato! Críticas construtivas? Por favor, diga! É isto, obrigado a quem leu!

Top comments (2)

Collapse
 
dev_jessi profile image
Jéssica Félix

O texto ficou muito bom e bem explicado. Parabéns!!

Collapse
 
porto_sql profile image
Douglas Porto

Parabéns Pedro, muito bom!