Como removo documentos usando o Node.js Mongoose?

291
FBFriendModel.find({
    id: 333
}, function (err, docs) {
    docs.remove(); //Remove all the documents that match!
});

O exposto acima não parece funcionar. Os registros ainda estão lá.

Alguém pode consertar?

TIMEX
fonte

Respostas:

489

Se você não quiser repetir, tente FBFriendModel.find({ id:333 }).remove( callback );ouFBFriendModel.find({ id:333 }).remove().exec();

mongoose.model.finddevolve uma consulta , que tem uma removefunção .

A atualização para o Mongoose v5.5.3 - remove()agora está obsoleta. Use deleteOne(), deleteMany()oufindOneAndDelete() instead.

Yusuf X
fonte
3
Isso executa o middleware pré / pós-remoção? (alguns métodos de modelo de bypass middleware documento e eu não tenho certeza se este é um deles, os documentos não são claras)
hunterloftis
12
Suponho que o @hunterloftis já tenha descoberto isso, mas para quem está lendo a resposta é não, isso não funcionará antes / depois do middleware em documentos individuais.
usar o seguinte código
Parece que muitas das outras respostas mencionam, .exec()no entanto, isso não acontece. É .exec()necessário, existem efeitos colaterais em usá-lo ou não?
DanH
Os documentos são claros (talvez tenham sido atualizados) que isso ignora o middleware - consulte a parte inferior do mongoosejs.com/docs/middleware.html -, portanto, tenha cuidado, o uso desse método pode causar problemas sérios e difíceis de rastrear.
Jed Watson
1
Ótima resposta! Quais são os argumentos do retorno de chamada?
precisa saber é o seguinte
299

ATUALIZAÇÃO: versão Mongoose (5.5.3)

remove () foi descontinuado e você pode usar deleteOne (), deleteMany () ou bulkWrite ().

A partir de "mongoose": ">=2.7.1"que você pode remover o documento diretamente com o .remove()método em vez de encontrar o documento e, em seguida, removê-lo o que me parece mais eficiente e fácil de manter.

Consultar exemplo:

Model.remove({ _id: req.body.id }, function(err) {
    if (!err) {
            message.type = 'notification!';
    }
    else {
            message.type = 'error';
    }
});

ATUALIZAR:

No mangusto 3.8.1, existem vários métodos que permitem remover diretamente um documento, como:

  • remove
  • findByIdAndRemove
  • findOneAndRemove

Consulte os documentos da API mangusto para obter mais informações.

diosney
fonte
13
Conforme observado em outros comentários para outras respostas, isso ignora o middleware definido no esquema e pode ser realmente perigoso. Portanto, use-o apenas se entender o impacto que isso terá. Para mais informações, consulte mongoosejs.com/docs/middleware.html
Jed Watson
2
Apenas para o registro, até agora eu sempre tê-los usado sem quaisquer efeitos secundários, com certeza, eu tinha para não usar qualquer middleware em meus projetos :)
diosney
8
remove(query)potencialmente pode esvaziar toda a sua coleção se você passar acidentalmente query = {}. Por esse motivo, prefiro findOneAndRemove(query)se estiver removendo apenas um documento.
Joeytwiddle 14/09/16
1
Observe também que isso não está retornando uma consulta, portanto, nem uma promessa. Você não pode fazerModel.remove({ _id: 'whatever' }).exec().then(...)
David
48

docsé uma variedade de documentos. então não tem um mongooseModel.remove()método.

Você pode iterar e remover cada documento da matriz separadamente.

Ou - já que parece que você está encontrando os documentos por um (provavelmente) ID único - use em findOnevez de find.

mtkopone
fonte
5
Visto que esta resposta assume uma versão bastante antiga do mangusto, eu realmente não me oponho a alguém que mude a resposta aceita.
Mtkopone 12/05
Essa é realmente uma das melhores maneiras de fazer isso, porque invoca corretamente o middleware definido no esquema - consulte mongoosejs.com/docs/middleware.html . Você só deve usar os outros métodos se NÃO estiver usando middleware em seu aplicativo e, em seguida, com cuidado.
Jed Watson
41

Isso para mim é o melhor da versão 3.8.1:

MyModel.findOneAndRemove({field: 'newValue'}, function(err){...});

E isso requer apenas uma chamada de banco de dados. Use isso, pois você não realiza nenhumaremove ação pior para a pesquisa e remoção.

José Pinto
fonte
1
Contanto que você não precise executar pre 'remove'ações, ele funciona bem.
precisa
32

Simplesmente faça

FBFriendModel.remove().exec();
Sandro Munda
fonte
1
Simples e eficaz.
Rich Apodaca
1
Isso retorna uma promessa? Em caso afirmativo, qual objeto é definido quando a promessa é resolvida?
22816 Kenny Worden
@KennyWorden uma abordagem eficaz para encontrar a resposta -> mongoosejs.com/docs/api.html , procure o que deseja, mas acrescente '#' à pesquisa na página com seu navegador, como em '#save' e você vou ver que retorna uma promessa.
Jason Sebring
3
Esta é uma espécie de resposta perigoso sem colocar a condição da op especificado na remoção ...
blak3r
29

mongoose.model.find()retorna um objeto de consulta que também tem uma remove()função.

Você também pode usar mongoose.model.findOne()se quiser remover apenas um documento exclusivo.

Caso contrário, você pode seguir a abordagem tradicional, bem como onde primeiro recuperou o documento e depois remove.

yourModelObj.findById(id, function (err, doc) {
    if (err) {
        // handle error
    }

    doc.remove(callback); //Removes the document
})

A seguir, são apresentadas as formas do modelobjeto que você pode executar para remover os documentos:

yourModelObj.findOneAndRemove(conditions, options, callback)

yourModelObj.findByIdAndRemove(id, options, callback)

yourModelObj.remove(conditions, callback);

var query = Comment.remove({ _id: id });
query.exec();
Amol M Kulkarni
fonte
22

remove()foi descontinuado. Use deleteOne(), deleteMany()ou bulkWrite().

O código que eu uso

TeleBot.deleteMany({chatID: chatID}, function (err, _) {
                if (err) {
                    return console.log(err);
                }
            });
Samyak Jain
fonte
1
Esta resposta honestamente precisa de mais votos. É injustamente colocado no fundo do barril (porque não está recebendo meia década de votos antigos), mas é a única resposta que resolve o problema de:(node:9132) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
Steven Ventimiglia
18

Para generalizar você pode usar:

SomeModel.find( $where, function(err,docs){
  if (err) return console.log(err);
  if (!docs || !Array.isArray(docs) || docs.length === 0) 
    return console.log('no docs found');
  docs.forEach( function (doc) {
    doc.remove();
  });
});

Outra maneira de conseguir isso é:

SomeModel.collection.remove( function (err) {
  if (err) throw err;
  // collection is now empty but not deleted
});
alexandru.topliceanu
fonte
18

Cuidado com o findOne e remova-o!

  User.findOne({name: 'Alice'}).remove().exec();

O código acima remove TODOS os usuários nomeados 'Alice', em vez do primeiro .

A propósito, prefiro remover documentos como este:

  User.remove({...}).exec();

Ou forneça um retorno de chamada e omita o exec ()

  User.remove({...}, callback);
damphat
fonte
12

Se você estiver procurando apenas um objeto a ser removido, poderá usar

Person.findOne({_id: req.params.id}, function (error, person){
        console.log("This object will get deleted " + person);
        person.remove();

    });

Neste exemplo, o Mongoose será excluído com base na correspondência req.params.id.

bhavsac
fonte
Bem-vindo ao Stackoverflow. Sua resposta é uma duplicata de várias respostas neste tópico. Além disso, você deve sempre verificar se há erros nos retornos de chamada.
VtoCorleone
9

.remove()funciona como .find():

MyModel.remove({search: criteria}, function() {
    // removed.
});
trusktr
fonte
9

Prefiro a notação de promessa, onde você precisa, por exemplo

Model.findOneAndRemove({_id:id})
    .then( doc => .... )
Simon H
fonte
7

Para remover documento, prefiro usar Model.remove(conditions, [callback])

Consulte a documentação da API para remover: -

http://mongoosejs.com/docs/api.html#model_Model.remove

Nesse caso, o código será: -

FBFriendModel.remove({ id : 333 }, function(err, callback){
console.log(‘Do Stuff’);
})

Se você deseja remover documentos sem aguardar uma resposta do MongoDB, não transmita um retorno de chamada, será necessário chamar exec na Consulta retornada

var removeQuery = FBFriendModel.remove({id : 333 });
removeQuery.exec();
satyam kumar
fonte
6

Você pode simplesmente usar a consulta diretamente na função remover, portanto:

FBFriendModel.remove({ id: 333}, function(err){});
David Losert
fonte
6

Você sempre pode usar a função interna do Mongoose:

var id = req.params.friendId; //here you pass the id
    FBFriendModel
   .findByIdAndRemove(id)
   .exec()
   .then(function(doc) {
       return doc;
    }).catch(function(error) {
       throw error;
    });
Doron Segal
fonte
5

Atualização: .remove()está obsoleta, mas isso ainda funciona para versões mais antigas

YourSchema.remove({
    foo: req.params.foo
}, function(err, _) {
    if (err) return res.send(err)
    res.json({
        message: `deleted ${ req.params.foo }`
    })
});
Joshua Michael Wagoner
fonte
Model.remove está obsoleto
Maxwell sc
2

usando o método remove () que você pode remover.

getLogout(data){
        return this.sessionModel
        .remove({session_id: data.sid})
        .exec()
        .then(data =>{
            return "signup successfully"
        })
    }
KARTHIKEYAN.A
fonte
Model.remove está obsoleto
Maxwell sc
1
Maxwell sc, faça uma solicitação de edição e corrija. Sei que você é novo no SO, mas é muito mais útil corrigi-lo do que comentar que é depreciado. Talvez você poderia sugerir uma edição da próxima vez, ou fazer uma edição si mesmo, e tomar um pouco de propriedade da situação ...
Joshua Michael Wagoner
1

Isso funcionou para mim, apenas tente o seguinte:

const id = req.params.id;
      YourSchema
      .remove({_id: id})
      .exec()
      .then(result => {
        res.status(200).json({
          message: 'deleted',
          request: {
            type: 'POST',
            url: 'http://localhost:3000/yourroutes/'
          }
        })
      })
      .catch(err => {
        res.status(500).json({
          error: err
        })
      });
MEAbid
fonte
Model.removeestá obsoleto
Maxwell sc
1

De acordo com a resposta de Samyak Jain, eu uso o Async Await

let isDelete = await MODEL_NAME.deleteMany({_id:'YOUR_ID', name:'YOUR_NAME'});
Renish Gotecha
fonte
0

Eu realmente gosto desse padrão em aplicativos Express / Mongoose assíncronos / aguardados:

app.delete('/:idToDelete', asyncHandler(async (req, res) => {
  const deletedItem = await YourModel
    .findByIdAndDelete(req.params.idToDelete) // This method is the nice method for deleting
    .catch(err => res.status(400).send(err.message))

  res.status(200).send(deletedItem)
}))
corysimmons
fonte
-2
db.collection.remove(<query>,
 {
  justOne: <boolean>,
  writeConcern: <document>
})
Rushabh.js
fonte
@ MR: Como pode ser link apenas quando não há link na resposta? Verifique também: posts de baixa qualidade e respostas apenas para códigos
BDL
Sry clique errado. Mas ainda é de baixa qualidade.
MR