1
resposta

[Dúvida] Remover item do array no mongoDB com mongoose

Estou com o seguinte problema:

Tenho uma aplicação com alguns items ordenados no front-end, no caso é uma página de links, esses links devem ser manipulados dentro do array que os contém. O array está armazenado no mongoDB, e estou usando o mongoose no NodeJs.

    `links = [

      '<a>Primeiro link</a>',
      '<a>Segundo link</a>',
      '<a>Terceiro link</a>'

    ]`

O primeiro passo é ter a possibilidade de excluí-los quando convém. Inicialmente eu queria excluí-los pela sua posição no array, mas não obtive sucesso. Agora, com o código abaixo, consigo excluir exatamente na posição que quero, porém só parcialmente, porque o array ainda permanece com suas posições nulas, não ficam zeradas. Veja a imagem depois do código:

   ` const docUpdate = {

       $unset: {
         [`links.${position}`]: "<p><a>Link teste</a></p>"
       }

    }`

   `const user = await User.updateOne({_id: id }, docUpdate, { 
      new: true
    })`

enter image description here)

O efeito disso no front-end são campos de links vazios, se bem que dá pra fazer uma condicional de valor verdadeiro para só assim renderizar a caixa de link, mas não acho que esse seja o caso, é bom manter as coisas organizadas. Confira o estrago:

enter image description here

Então, tendo em vista a solução desse problema em que me meti, qualquer ajuda é bem vinda. Muito obrigado. Desculpa se não fui claro. Disponho.

Vi muitos exemplos, mas como lidava com objetos dentro de arrays, com suas respectivas chaves e valores, não consegui aplicar para o meu caso, onde só tenho valores dentro do array.

1 resposta

Oi, Heleno, tudo bem? Nos desculpe a demora a responder.

Realmente, você se deparou com um caso bastante específico do MongoDB, pois ele realmente não fornece um operador de modificação de array que remove um item de um array apenas pelo valor de seu índice.

O que chega mais próximo disso é o operador $pull, que remove um item do array ao especificar o valor a ser removido (ou especificando uma condição de busca mais complexa).

Ou seja, você poderia remover um link específico pelo seu valor com um código como esse:

const user = await User.updateOne(
  { _id: id },
  {
    $pull: {
      links: "<a>Terceiro link</a>"
    },
  }
);

Mas para remover um item pelo índice, você vai precisar realizar ao menos duas operações do MongoDB. A primeira delas é a que você já está fazendo, aplicando o operador $unset em um elemento de um índice específico do seu array. Isso vai fazer o elemento ter o valor null no array.

Em seguida, você irá utilizar o operador $pull para remover o item que possui valor null. Ou seja, o código vai ficar assim:

const id = "id_do_documento";
const position = 2;

await User.updateOne(
  { _id: id },
  {
    $unset: { [`links.${position}`]: "" },
  }
);

const result = await User.updateOne(
  { _id: id },
  {
    $pull: { links: null },
  }
);

Porém, do momento que o MongoDB não fornece um método direto para remover um item de array pelo índice, talvez seja melhor pensar em um alternativa que utilize apenas o operador $pull, como no primeiro código que eu exemplifiquei aqui, onde você fornece exatamente o valor do item a ser removido do array.

Espero ter ajudado! Abraços e bons estudos :)